I want to generate different headers in first page and other pages in poi word, So I used XWPFHeaderFooterPolicy.FIRST and XWPFHeaderFooterPolicy.DEFAULT. when I using XWPFHeaderFooterPolicy.DEFAULT I can insert my header successfully, but when I change to XWPFHeaderFooterPolicy.FIRST, I cannot see there is a header in my first page, this is my code in below, what's wrong with it? thanks!
XWPFHeader header = headerFooterPolicy.createHeader(XWPFHeaderFooterPolicy.FIRST);
paragraph = header.createParagraph();
paragraph.setAlignment(ParagraphAlignment.LEFT);
run = paragraph.createRun();
run.setText("header");
That there is a different header set for first page only, means not that this header will also be shown. In Word
GUI there is a checkbox [x] Different First Page
in Header & Footer Tools
to achieve that.
And according Office Open XML Part 4 - Markup Language Reference there must a boolean XML element titlePg
be set to determine that there is a title page present.
In actual final apache poi
version 3.15 this XML element titlePg
can only be set using underlying low level objects using doc.getDocument().getBody().getSectPr().addNewTitlePg();
.
But apache poi
version 3.16 Beta 2 has doc.createHeader(HeaderFooterType.FIRST);
which sets titlePg
flag in XML.
Complete example:
import java.io.*;
import org.apache.poi.wp.usermodel.*;
import org.apache.poi.xwpf.usermodel.*;
public class CreateWordHeaderFooterDifferent {
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.... page 1");
paragraph = doc.createParagraph();
run=paragraph.createRun();
run.addBreak(BreakType.PAGE);
run.setText("Lorem ipsum.... page 2");
paragraph = doc.createParagraph();
run=paragraph.createRun();
run.addBreak(BreakType.PAGE);
run.setText("Lorem ipsum.... page 3");
// create first page header
XWPFHeader header = doc.createHeader(HeaderFooterType.FIRST);
paragraph = header.createParagraph();
paragraph.setAlignment(ParagraphAlignment.LEFT);
run = paragraph.createRun();
run.setText("The first page header:");
// create default page header
header = doc.createHeader(HeaderFooterType.DEFAULT);
paragraph = header.createParagraph();
paragraph.setAlignment(ParagraphAlignment.LEFT);
run = paragraph.createRun();
run.setText("The default page header:");
// create footer
XWPFFooter footer = doc.createFooter(HeaderFooterType.DEFAULT);
paragraph = footer.createParagraph();
paragraph.setAlignment(ParagraphAlignment.CENTER);
run = paragraph.createRun();
run.setText("Page ");
paragraph.getCTP().addNewFldSimple().setInstr("PAGE \\* MERGEFORMAT");
run = paragraph.createRun();
run.setText(" of ");
paragraph.getCTP().addNewFldSimple().setInstr("NUMPAGES \\* MERGEFORMAT");
doc.write(new FileOutputStream("CreateWordHeaderFooterDifferent.docx"));
}
}
But in my opinion the setting titlePg
flag in XML automatically while HeaderFooterType.FIRST
is created is not correct. Since Word
can toggle between [x] Different First Page
and [] Different First Page
, apache poi
should also be able to do so. So the setting the titlePg
flag should be a method in XWPFDocument
.
There is nothing in that class to tell Word to display different first page headers. You will need the most recent version of POI, and then create the header from XWPFDocument using:
XWPFDocument.createHeader(HeaderFooterType.FIRST);
Otherwise you need to break into the CT classes and in the section properties set the titlePg
property. I don't recommend this approach though as it is likely to change.