如何使用 poi 将外部页眉页脚文件(.xml 格式)添加到现有的 .docx 文档 - 前端之家

代码问题

其实我是想给文档加一个上头文件,但是因为文档头的格式要求比较高,比较标准,所以想尝试直接把头文件插入到文档中。我认为直接用标准头文件引用它比从 poi 创建一个头更好。

我有一个带头的xml类型文件,文件名为'headerExternal.xml',其内容如下:

  1. <?xml version="1.0" encoding="utf-8" standalone="yes"?><w:hdr xmlns:v="urn:schemas-[micr](https://www.codej.cn/tag/micr/)osoft-com:vml" xmlns:w10="urn:schemas-[micr](https://www.codej.cn/tag/micr/)osoft-com:office:word" xmlns:o="urn:schemas-[micr](https://www.codej.cn/tag/micr/)osoft-com:office:office" xmlns:ve="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:wne="http://schemas.[micr](https://www.codej.cn/tag/micr/)osoft.com/office/word/2006/wordml" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:wps="http://schemas.[micr](https://www.codej.cn/tag/micr/)osoft.com/office/word/2010/wordprocessingShape" xmlns:wpg="http://schemas.[micr](https://www.codej.cn/tag/micr/)osoft.com/office/word/2010/wordprocessingGroup" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
  2. <w:p>
  3. <w:pPr>
  4. <w:jc w:val="left" />
  5. </w:pPr>
  6. <w:r>
  7. <w:rPr>
  8. <w:b />
  9. <w:color w:val="FF00FF" />
  10. <w:sz w:val="30" />
  11. </w:rPr>
  12. <w:t xml:space="preserve">page 1</w:t>
  13. </w:r>
  14. </w:p>
  15. </w:hdr>

我想将 headerExternal.xml 插入 .docx 文件并遵循 ooxml 规范

原始.docx文件: enter image description here

插入后的docx文档: enter image description here

我尝试使用poi提供的hdrDocument直接解析headerExternal.xml文件,如下:

  1. HdrDocument hdrDocument = HdrDocument.F[act](https://www.codej.cn/tag/act/)ory.parse(new File("headerExternal.xm"));

但是我不知道如何将这个对象绑定到 XWPFDocument 对象,所以我目前没有任何进展。

我尝试了 Axel Richter 提供的方法,发现它们确实解决了我的问题。

但我也发现给文档添加一大堆完整的标签真的不是一个好主意,因为它会导致文档第一次浏览缺少提示样式。

问题答案

这是一个 XY problem。可以使用 headerExternal.xml 将该 *.docx 放入 OPCPackage ZIP 存档中。但是 headerExternal.xml ZIP 存档中的 *.docx 永远不会用作 Word 中的标头。它只是该 ZIP 存档中无用的附加文件。当 Word 下次保存文件时,它将被删除。无法使用 XWPFHeader

但如果您真的想使用 *.xml 文件作为 XWPFHeader 的模板,那么可以使用 XWPFHeaderFooter.setHeaderFooter(org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHdrFtr headerFooter) 来完成。这需要一个 org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHdrFtr,它可以从 *.xml 文件中创建,如下所示:

  1. ...
  2. File headerContent = new File("./headerExternal.xml");
  3. org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHdrFtr ctHdrFtr =
  4. org.openxmlformats.schemas.wordprocessingml.x2006.main.HdrDocument.Factory.parse(headerContent).getHdr();
  5. ...

完整示例:

  1. import java.io.File;
  2. import java.io.FileInputStream;
  3. import java.io.FileOutputStream;
  4. import org.apache.poi.xwpf.usermodel.*;
  5. public class DocxWordHeaderFromFile {
  6. public static void main(String[] args) throws Exception {
  7. XWPFDocument document = new XWPFDocument(new FileInputStream("./WordDocument.docx"));
  8. File headerContent = new File("./headerExternal.xml");
  9. org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHdrFtr ctHdrFtr =
  10. org.openxmlformats.schemas.wordprocessingml.x2006.main.HdrDocument.Factory.parse(headerContent).getHdr();
  11. for (XWPFHeader header : document.getHeaderList()) {
  12. header.setHeaderFooter(ctHdrFtr);
  13. }
  14. FileOutputStream out = new FileOutputStream("./WordDocumentNew.docx");
  15. document.write(out);
  16. out.close();
  17. document.close();
  18. }
  19. }

,

根据 Axel Richter 对 another question 的回答,我找到了我想要的答案

回忆我以前的需求:

我想从footer.xml文档压缩包中取出header.xml.docx文件,直接放到输出文档中,这样可以避免各种样式等复杂信息.

如果你想达到这个效果,你应该这样做:

1.从headerfooterxml文件中粘贴你想要的部分(_因为我的开发环境是中文的,有些属性是中文字段,但是影响不大_):

  1. <w:p>
  2. <w:pPr>
  3. <w:ind w:right="360" w:firstLine="720"/>
  4. <w:jc w:val="center"/>
  5. <w:outlineLvl w:val="0"/>
  6. <w:rPr>
  7. <w:rFonts w:hint="eastAsia" w:ascii="黑体" w:eastAsia="隶书"/>
  8. </w:rPr>
  9. </w:pPr>
  10. <w:r>
  11. <w:rPr>
  12. <w:rFonts w:hint="eastAsia" w:eastAsia="隶书"/>
  13. <w:bCs/>
  14. <w:sz w:val="36"/>
  15. </w:rPr>
  16. <w:t>This a </w:t>
  17. </w:r>
  18. <w:r>
  19. <w:rPr>
  20. <w:rFonts w:hint="eastAsia" w:eastAsia="隶书"/>
  21. <w:b/>
  22. <w:sz w:val="44"/>
  23. </w:rPr>
  24. <w:t xml:space="preserve"> </w:t>
  25. </w:r>
  26. <w:r>
  27. <w:rPr>
  28. <w:rFonts w:hint="eastAsia" w:ascii="黑体" w:eastAsia="黑体"/>
  29. <w:bCs/>
  30. </w:rPr>
  31. <w:t>footer</w:t>
  32. </w:r>
  33. </w:p>

note:不需要整个文件,注意不要包含最顶层的约束信息

2.调用poi的api创建footer对象

  1. XWPFFooter xwpfFooterHome = xwpfDocument.createFooter(HeaderFooterType.FIRST);

3.上面复制的字符串作为参数生成CTHdrFtr实例对象

  1. ctHdrFtrFooterHome = CTHdrFtr.Factory.parse(footerhomeString);

4. xwpfFooterHome 中有一个方法可以设置 CTHdrFtr 中创建的 Step 3 对象

  1. xwpfFooterHome.setHeaderFooter(ctHdrFtrFooterHome);

所以完整的代码如下(注意在xmlns:http://schemas.openxmlformats.org/wordprocessingml/2006/main标签后面加上<w:p>):

  1. String footerhomeString = "<w:p xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"><w:pPr><w:ind w:right=\"360\" w:firstLine=\"720\"/><w:jc w:val=\"center\"/><w:outlineLvl w:val=\"0\"/><w:rPr><w:rFonts w:hint=\"eastAsia\" w:ascii=\"黑体\" w:eastAsia=\"隶书\"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:hint=\"eastAsia\" w:eastAsia=\"隶书\"/><w:bCs/><w:sz w:val=\"36\"/></w:rPr><w:t>中国南车集团株洲电力机车有限公司</w:t></w:r><w:r><w:rPr><w:rFonts w:hint=\"eastAsia\" w:eastAsia=\"隶书\"/><w:b/><w:sz w:val=\"44\"/></w:rPr><w:t xml:space=\"preserve\"> </w:t></w:r><w:r><w:rPr><w:rFonts w:hint=\"eastAsia\" w:ascii=\"黑体\" w:eastAsia=\"黑体\"/><w:bCs/></w:rPr><w:t>发 布</w:t></w:r></w:p>";
  2. XWPFFooter xwpfFooterHome = xwpfDocument.createFooter(HeaderFooterType.FIRST);
  3. CTHdrFtr ctHdrFtrFooterHome = null;
  4. try {
  5. ctHdrFtrFooterHome = CTHdrFtr.Factory.parse(footerhomeString);
  6. } catch (XmlException e) {
  7. e.printStackTrace();
  8. }
  9. xwpfFooterHome.setHeaderFooter(ctHdrFtrFooterHome);

如果觉得前端之家所整理的内容很不错的话,欢迎点击下方分享按钮,转发给身边开发程序员好友。

https://www.f2er.com/112017.html


原网址: 访问
创建于: 2023-05-05 10:58:40
目录: default
标签: 无

请先后发表评论
  • 最新评论
  • 总共0条评论