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")); }}编辑2016年3月29日:
这一直有效,直到Apache poi 3.13。现在,在3.14版本中,它的工作方式不再更多。原因:POI将不再在标题段落中保存图像的blip参考。
/word/header1.xml:
使用3.13编译并运行的代码:
...<pic:blipFill><a:blip r:embed="rId1"/>...
使用3.14编译并运行的相同代码:
...<pic:blipFill><a:blip r:embed=""/>...
编辑2016年3月31日:
找到了问题。有人认为
public final PackageRelationshipgetPackageRelationship()需要弃用。因此在
XWPFRun.java代码中
public XWPFPictureaddPicture(...)已更改
从3.13版开始:
... CTBlipFillProperties blipFill = pic.addNewBlipFill(); CTBlip blip = blipFill.addNewBlip(); blip.setEmbed(picData.getPackageRelationship().getId());...
到版本3.14:
... CTBlipFillProperties blipFill = pic.addNewBlipFill(); CTBlip blip = blipFill.addNewBlip(); blip.setEmbed(parent.getdocument().getRelationId(picData));...
但
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); }...因此,如果确实应执行折旧,
if..else则在设置blipID时也必须使用此折旧。但是为什么要贬值呢?
Apache POI 3.14版本 大声笑
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")); }}编辑2017年3月28日:
在
apache poi3.16 Beta 2版中,此问题似乎已解决,因为以下代码在
apache poi3.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")); }}


