XWPF POI 页脚与最后一页不同

发布于 2025-01-11 12:15:16 字数 279 浏览 0 评论 0原文

如何仅在最后一页设置不同的页脚。我的意思是,最后一页没有页脚或不同。第一页和其他都一样。

在此处输入链接说明

这是我的文档

How to set footer diferrent only in last page. I mean, in last page no footer or different. in first page and other are same.

enter link description here

this is my docx

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

哭了丶谁疼 2025-01-18 12:15:16

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 运行。

There is not a header/footer only for the last page in Microsoft Word.

There are different header/footer settings possible for first page, even pages and default pages. There the default header/footer gets used for each pages if not else is defined. So if there is a header/footer for even pages and a setting that odd and even pages shall be different, then default header/footer gets used as header/footer for odd pages only. If there is no such setting, then the default header/footer gets used for each page. This is except first page, if there is a special header/footer for first page set.

But a Word document can be separated into different sections. And each section may have own header/footer settings. So if, and only if, the last page is in its own section, then there can be a different header/footer for the last page (last section) only.

Unfortunately apache poi do not provide methods to set sections in XWPF. And it only provides methods to set the three different header/footer types in document. So to get a XWPFDocument separated into sections and to set different header/footer settings for those sections, a little bit cheating is necessary.

One could create one of the three possible header/footer types only to set it to be the default header/footer for an own section later. The following example shows this. It creates a footer for even pages in document, which never gets used but later gets referenced as the default footer for the last section. Note the further comments in the code.

Of course that only can work if one at least knows where the last page starts. That must be known because the section break needs to be set before the content of the lase page.

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();
 }
}

This is tested and works using current apache poi 5.2.0.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文