使用POI XWPF将图像添加到单词.docx文档标题中

MMo*_*ora 3 apache-poi

我一直在尝试使用Apache POI将.png图像添加到.docx文件头.我找不到能帮助我的方法.有人知道怎么做吗?这段代码我只能添加文字.

XWPFDocument docc = new XWPFDocument(); 
CTP ctpHeader = CTP.Factory.newInstance(); 
CTR ctrHeader = ctpHeader.addNewR(); 
CTText ctHeader = ctrHeader.addNewT(); 
String headerText = "mi encabezado"; 
ctHeader.setStringValue(headerText); 

XWPFParagraph headerParagraph = new XWPFParagraph(ctpHeader, docc); XWPFParagraph[] parsHeader = new XWPFParagraph[1]; 
parsHeader[0] = headerParagraph; header.createHeader(XWPFHeaderFooterPolicy.DEFAULT, parsHeader);
Run Code Online (Sandbox Code Playgroud)

Axe*_*ter 12

创建Word包含页眉和页脚的文档以及标题中的图像的示例:

import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.io.IOException;

import org.apache.poi.util.Units;

import org.apache.poi.xwpf.usermodel.*;

import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy;

import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSectPr;

import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTabStop;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTabJc;

import java.math.BigInteger;

public class CreateWordHeaderFooter {

 public static void main(String[] args) throws Exception {

  XWPFDocument doc= new XWPFDocument();

  // the body content
  XWPFParagraph paragraph = doc.createParagraph();
  XWPFRun run=paragraph.createRun();  
  run.setText("The Body:");

  paragraph = doc.createParagraph();
  run=paragraph.createRun();  
  run.setText("Lorem ipsum....");

  // create header start
  CTSectPr sectPr = doc.getDocument().getBody().addNewSectPr();
  XWPFHeaderFooterPolicy headerFooterPolicy = new XWPFHeaderFooterPolicy(doc, sectPr);

  XWPFHeader header = headerFooterPolicy.createHeader(XWPFHeaderFooterPolicy.DEFAULT);

  paragraph = header.getParagraphArray(0);
  paragraph.setAlignment(ParagraphAlignment.LEFT);

  CTTabStop tabStop = paragraph.getCTP().getPPr().addNewTabs().addNewTab();
  tabStop.setVal(STTabJc.RIGHT);
  int twipsPerInch =  1440;
  tabStop.setPos(BigInteger.valueOf(6 * twipsPerInch));

  run = paragraph.createRun();  
  run.setText("The Header:");
  run.addTab();

  run = paragraph.createRun();  
  String imgFile="Koala.png";
  run.addPicture(new FileInputStream(imgFile), XWPFDocument.PICTURE_TYPE_PNG, imgFile, Units.toEMU(50), Units.toEMU(50));


  // create footer start
  XWPFFooter footer = headerFooterPolicy.createFooter(XWPFHeaderFooterPolicy.DEFAULT);

  paragraph = footer.getParagraphArray(0);
  paragraph.setAlignment(ParagraphAlignment.CENTER);

  run = paragraph.createRun();  
  run.setText("The Footer:");


  doc.write(new FileOutputStream("test.docx"));

 }
}
Run Code Online (Sandbox Code Playgroud)

2016年3月29日编辑:

这一直有效直到apache poi 3.13.现在使用3.14它不会更多.原因:POI不再保存标题段落中图像的blip参考.

/word/header1.xml:

编译并运行3.13代码:

...
<pic:blipFill><a:blip r:embed="rId1"/>
...
Run Code Online (Sandbox Code Playgroud)

使用3.14编译和运行相同的代码:

...
<pic:blipFill><a:blip r:embed=""/>
...
Run Code Online (Sandbox Code Playgroud)

2016年3月31日编辑:

发现了问题.有人认为public final PackageRelationship getPackageRelationship()需要弃用.所以在XWPFRun.java代码中public XWPFPicture addPicture(...)被改变了

从版本3.13:

...
            CTBlipFillProperties blipFill = pic.addNewBlipFill();
            CTBlip blip = blipFill.addNewBlip();
            blip.setEmbed(picData.getPackageRelationship().getId());
...
Run Code Online (Sandbox Code Playgroud)

到版本3.14:

...
            CTBlipFillProperties blipFill = pic.addNewBlipFill();
            CTBlip blip = blipFill.addNewBlip();
            blip.setEmbed(parent.getDocument().getRelationId(picData));
...
Run Code Online (Sandbox Code Playgroud)

parent.getDocument()就是XWPFDocument永远,而picData可能是关系到XWPFHeaderFooter.

public XWPFPicture addPicture(...)程序员开始时已经知道这一点.

...
        if (parent.getPart() instanceof XWPFHeaderFooter) {
            XWPFHeaderFooter headerFooter = (XWPFHeaderFooter)parent.getPart();
            relationId = headerFooter.addPictureData(pictureData, pictureType);
            picData = (XWPFPictureData) headerFooter.getRelationById(relationId);
        } else {
            XWPFDocument doc = parent.getDocument();
            relationId = doc.addPictureData(pictureData, pictureType);
            picData = (XWPFPictureData) doc.getRelationById(relationId);
        }
...
Run Code Online (Sandbox Code Playgroud)

因此,如果确实应该实施折旧,if..else则在设置blipID时也必须使用此折旧.但为什么贬值呢?

apache poi 3.14版lol

import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.io.IOException;

import org.apache.poi.util.Units;

import org.apache.poi.xwpf.usermodel.*;

import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy;

import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSectPr;

import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTabStop;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTabJc;

import java.math.BigInteger;

public class CreateWordHeaderFooter {

 public static void main(String[] args) throws Exception {

  XWPFDocument doc= new XWPFDocument();

  // the body content
  XWPFParagraph paragraph = doc.createParagraph();
  XWPFRun run=paragraph.createRun();  
  run.setText("The Body:");

  paragraph = doc.createParagraph();
  run=paragraph.createRun();  
  run.setText("Lorem ipsum....");

  // create header start
  CTSectPr sectPr = doc.getDocument().getBody().addNewSectPr();
  XWPFHeaderFooterPolicy headerFooterPolicy = new XWPFHeaderFooterPolicy(doc, sectPr);

  XWPFHeader header = headerFooterPolicy.createHeader(XWPFHeaderFooterPolicy.DEFAULT);

  paragraph = header.getParagraphArray(0);
  paragraph.setAlignment(ParagraphAlignment.LEFT);

  CTTabStop tabStop = paragraph.getCTP().getPPr().addNewTabs().addNewTab();
  tabStop.setVal(STTabJc.RIGHT);
  int twipsPerInch =  1440;
  tabStop.setPos(BigInteger.valueOf(6 * twipsPerInch));

  run = paragraph.createRun();  
  run.setText("The Header:");
  run.addTab();

  run = paragraph.createRun();  
  String imgFile="Koala.png";
  XWPFPicture picture = run.addPicture(new FileInputStream(imgFile), XWPFDocument.PICTURE_TYPE_PNG, imgFile, Units.toEMU(50), Units.toEMU(50));
  System.out.println(picture); //XWPFPicture is added
  System.out.println(picture.getPictureData()); //but without access to XWPFPictureData (no blipID)

  String blipID = "";
  for(XWPFPictureData picturedata : header.getAllPackagePictures()) {
   blipID = header.getRelationId(picturedata);
   System.out.println(blipID); //the XWPFPictureData are already there
  }
  picture.getCTPicture().getBlipFill().getBlip().setEmbed(blipID); //now they have a blipID also
  System.out.println(picture.getPictureData());

  // create footer start
  XWPFFooter footer = headerFooterPolicy.createFooter(XWPFHeaderFooterPolicy.DEFAULT);

  paragraph = footer.getParagraphArray(0);
  paragraph.setAlignment(ParagraphAlignment.CENTER);

  run = paragraph.createRun();  
  run.setText("The Footer:");


  doc.write(new FileOutputStream("test.docx"));

 }
}
Run Code Online (Sandbox Code Playgroud)

2017年3月28日编辑:

apache poi版本3.16 Beta 2中,这似乎是修复的,因为以下代码使用apache poi版本3.16 Beta 2:

import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.io.IOException;

import org.apache.poi.util.Units;

import org.apache.poi.xwpf.usermodel.*;

import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy;

import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSectPr;

import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTabStop;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTabJc;

import java.math.BigInteger;

public class CreateWordHeaderFooter2 {

 public static void main(String[] args) throws Exception {

  XWPFDocument doc= new XWPFDocument();

  // the body content
  XWPFParagraph paragraph = doc.createParagraph();
  XWPFRun run=paragraph.createRun();  
  run.setText("The Body:");

  paragraph = doc.createParagraph();
  run=paragraph.createRun();  
  run.setText("Lorem ipsum....");

  // create header start
  CTSectPr sectPr = doc.getDocument().getBody().addNewSectPr();
  XWPFHeaderFooterPolicy headerFooterPolicy = new XWPFHeaderFooterPolicy(doc, sectPr);

  XWPFHeader header = headerFooterPolicy.createHeader(XWPFHeaderFooterPolicy.DEFAULT);

  paragraph = header.createParagraph();
  paragraph.setAlignment(ParagraphAlignment.LEFT);

  CTTabStop tabStop = paragraph.getCTP().getPPr().addNewTabs().addNewTab();
  tabStop.setVal(STTabJc.RIGHT);
  int twipsPerInch =  1440;
  tabStop.setPos(BigInteger.valueOf(6 * twipsPerInch));

  run = paragraph.createRun();  
  run.setText("The Header:");
  run.addTab();

  run = paragraph.createRun();  
  String imgFile="Koala.png";
  run.addPicture(new FileInputStream(imgFile), XWPFDocument.PICTURE_TYPE_PNG, imgFile, Units.toEMU(50), Units.toEMU(50));


  // create footer start
  XWPFFooter footer = headerFooterPolicy.createFooter(XWPFHeaderFooterPolicy.DEFAULT);

  paragraph = footer.createParagraph();
  paragraph.setAlignment(ParagraphAlignment.CENTER);

  run = paragraph.createRun();  
  run.setText("The Footer:");


  doc.write(new FileOutputStream("test.docx"));

 }
}
Run Code Online (Sandbox Code Playgroud)