Microsoft Word中没有仅针对最后一页的页眉/页脚。
对于第一页、偶数页和默认页,可以有不同的页眉/页脚设置。如果没有定义其他内容,则默认页眉/页脚用于每页。因此,如果偶数页有页眉/页脚,并且奇数页和偶数页应不同,则默认页眉/页脚仅用于奇数页的页眉/页脚。如果没有这样的设置,则默认页眉/页脚用于每页。如果第一页设置了特殊的页眉/页脚,则第一页除外。
但是Word文档可以分成不同的部分。每个部分可能有自己的页眉/页脚设置。因此,当且仅当最后一页在自己的部分中时,那么只能为最后一页(最后一部分)设置不同的页眉/页脚。
不幸的是,apache poi
不提供在XWPF
中设置部分的方法。它只提供了在文档中设置三种不同页眉/页脚类型的方法。因此,要将XWPFDocument
分成部分并为这些部分设置不同的页眉/页脚设置,有点作弊是必要的。
可以创建三种可能的页眉/页脚类型中的一种,只是为了以后将其设置为自己部分的默认页眉/页脚。以下示例显示了这一点。它为文档中的偶数页创建了一个页脚,该页脚从未被使用过,但后来被引用为最后一部分的默认页脚。请注意代码中的进一步注释。
当然,只有当一个人至少知道最后一页从哪里开始时,这才有效。这必须是知道的,因为在激光页面的内容之前需要设置节符。
import java.io.*;
import org.apache.poi.xwpf.usermodel.*;
import org.apache.poi.wp.usermodel.HeaderFooterType;
public class CreateWordDifferentFooters {
public static void main(String[] args) throws Exception {
XWPFDocument document = new XWPFDocument();
XWPFParagraph paragraph;
XWPFRun run;
XWPFFooter footer;
//create footers
//footer for first page
footer = document.createFooter(HeaderFooterType.FIRST);
paragraph = footer.createParagraph();
run = paragraph.createRun();
run.setText("Footer FIRST");
//default footer = footer for each what is not else defined
footer = document.createFooter(HeaderFooterType.DEFAULT);
paragraph = footer.createParagraph();
run = paragraph.createRun();
run.setText("Footer DEFAULT");
//footer for even pages - gets default footer for page in last section later
footer = document.createFooter(HeaderFooterType.EVEN);
paragraph = footer.createParagraph();
run = paragraph.createRun();
run.setText("Footer EVEN = DEFAULT in last section");
//the body content
//section 1
paragraph = document.createParagraph();
run = paragraph.createRun();
run.setText("First page in first section ...");
paragraph = document.createParagraph();
run = paragraph.createRun();
run.addBreak(BreakType.PAGE);
paragraph = document.createParagraph();
run = paragraph.createRun();
run.setText("Second page in first section ...");
paragraph = document.createParagraph();
run = paragraph.createRun();
run.addBreak(BreakType.PAGE);
paragraph = document.createParagraph();
run = paragraph.createRun();
run.setText("Third page in first section ...");
paragraph = document.createParagraph();
//paragraph with section setting for section above and section break
paragraph = document.createParagraph();
org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSectPr ctSectPrSect1 = paragraph.getCTP().addNewPPr().addNewSectPr(); //we need ctSectPrSect1 later
//section 2
paragraph = document.createParagraph();
run = paragraph.createRun();
run.setText("Fourth and last page. Only page in last section ...");
//section setting for section above = last section in document
org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDocument1 ctDocument = document.getDocument();
org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBody ctBody = ctDocument.getBody();
org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSectPr ctSectPrLastSect = ctBody.getSectPr(); //there must be a SectPr already because of the footer settings above
//move first and default footer to section 1
org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHdrFtrRef ctHdrFtrRef0 = ctSectPrLastSect.getFooterReferenceArray(0); // first footer
org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHdrFtrRef ctHdrFtrRef1 = ctSectPrLastSect.getFooterReferenceArray(1); // default footer
org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHdrFtrRef[] ctHdrFtrRefs = new org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHdrFtrRef[]{ctHdrFtrRef0, ctHdrFtrRef1};
ctSectPrSect1.setFooterReferenceArray(ctHdrFtrRefs);
//set "there is a title page" for section 1 to make first footer work
org.openxmlformats.schemas.wordprocessingml.x2006.main.CTOnOff ctOnOff = org.openxmlformats.schemas.wordprocessingml.x2006.main.CTOnOff.Factory.newInstance();
ctOnOff.setVal(true);
ctSectPrSect1.setTitlePg(ctOnOff);
//set footer reference of even footer to be default footer reference for last section
org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHdrFtrRef ctHdrFtrRef = ctSectPrLastSect.getFooterReferenceArray(2);
ctHdrFtrRef.setType(org.openxmlformats.schemas.wordprocessingml.x2006.main.STHdrFtr.DEFAULT); //change this from STHdrFtr.EVEN to STHdrFtr.DEFAULT
//unset "there is a title page" for the last section
ctSectPrLastSect.unsetTitlePg();
//remove first and old default footer references from last section
ctSectPrLastSect.removeFooterReference(1);
ctSectPrLastSect.removeFooterReference(0);
FileOutputStream out = new FileOutputStream("./CreateWordDifferentFooters.docx");
document.write(out);
out.close();
document.close();
}
}
这是使用当前的apache poi 5.2.0
进行测试和工作的。