首页 > 解决方案 > 如何使用 poi 将外部页眉页脚文件(.xml 格式)添加到现有 .docx 文档

问题描述

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



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

    <?xml version="1.0" encoding="utf-8" standalone="yes"?><w:hdr xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:o="urn:schemas-microsoft-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.microsoft.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.microsoft.com/office/word/2010/wordprocessingShape" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
    <w:p>
        <w:pPr>
            <w:jc w:val="left" />
        </w:pPr>
        <w:r>
            <w:rPr>
                <w:b />
                <w:color w:val="FF00FF" />
                <w:sz w:val="30" />
            </w:rPr>
            <w:t xml:space="preserve">page 1</w:t>
        </w:r>
    </w:p>
</w:hdr>

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

.docx原文件: 在此输入图片说明

插入后的docx文档: 在此 输入图片描述



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

HdrDocument hdrDocument = HdrDocument.Factory.parse(new File("headerExternal.xm"));

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



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

但我也发现在文档中添加一大堆完整的 < w:hdr > 标签确实不是一个好主意,因为它会导致文档第一次浏览缺少的提示样式。

标签: javaapache-poiopenxmldocxword

解决方案


这是一个XY 问题。可以使用. headerExternal.xml_ 但是ZIP 存档中的那个永远不会用作. 它只是该 ZIP 存档中的一个无用的附加文件。并且在下次保存文件时将其删除。没有办法使用.*.docxOPCPackageheaderExternal.xml*.docxWordWordXWPFHeader

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

...
File headerContent = new File("./headerExternal.xml");

org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHdrFtr ctHdrFtr =
 org.openxmlformats.schemas.wordprocessingml.x2006.main.HdrDocument.Factory.parse(headerContent).getHdr();
...

完整示例:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;

import org.apache.poi.xwpf.usermodel.*;

public class DocxWordHeaderFromFile {

 public static void main(String[] args) throws Exception {

  XWPFDocument document = new XWPFDocument(new FileInputStream("./WordDocument.docx"));

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

  for (XWPFHeader header : document.getHeaderList()) {
   header.setHeaderFooter(ctHdrFtr);
  }
 
  FileOutputStream out = new FileOutputStream("./WordDocumentNew.docx");
  document.write(out);
  out.close();
  document.close();

 }
}

推荐阅读