实际上,我想在文档中添加一个上页眉,但由于文档页眉的格式要求更高、更标准,我想尝试将页眉文件直接插入文档中。我认为直接用标准头文件引用它比从poi创建头要好。
我有一个带头的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>标记到文档实际上不是一个好主意,因为它会导致文档第一次浏览缺少的提示样式。
这是一个XY问题。可以使用OPCPackage
将该headerExternal.xml
放入*.docx
ZIP档案中。但是*.docx
ZIP档案中的headerExternal.xml
永远不会用作Word
中的标头。在ZIP档案中,它只是一个无用的附加文件。当Word
下次保存文件时,它将被删除。使用XWPFHeader
是没有办法的。
但是,如果您真的想使用*.xml
文件作为XWPFHeader
的模板,那么这可以使用XWPFHeaderFooter.setHeaderFooter(org.openxmlformats.schemas.wordprocessingml.x2006.main.CHDrFtr 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();
}
}
根据Axel Richter对另一个问题的回答,我找到了我想要的
回想我以前的需求:
我想从
.docx
文档zip包中取出footer.xml
或header.xml
文件,并将它们直接放入输出文档中,这样我们就可以避免各种样式等复杂信息。
如果你想达到这个效果,你应该这样做:
1.从header
或footer
xml文件中粘贴您想要的零件(因为我的开发环境是中文的,有些属性是中文字段,但它们几乎没有影响(:
<w:p>
<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>This a </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>footer</w:t>
</w:r>
</w:p>
note
:您不需要整个文件,注意不要包含最上面的约束信息
2.调用poi的api创建页脚对象
XWPFFooter xwpfFooterHome = xwpfDocument.createFooter(HeaderFooterType.FIRST);
3.上面复制的字符串用作参数,以生成CTHdrFtr
实例对象
ctHdrFtrFooterHome = CTHdrFtr.Factory.parse(footerhomeString);
4.xwpfFooterHome
中有一种方法,用于设置在Step 3
中创建的CTHdrFtr
对象
xwpfFooterHome.setHeaderFooter(ctHdrFtrFooterHome);
因此,完整的代码如下(注意将xmlns:http://schemas.openxmlformats.org/wordprocessingml/2006/main
添加到<w:p>
标签中(:
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>";
XWPFFooter xwpfFooterHome = xwpfDocument.createFooter(HeaderFooterType.FIRST);
CTHdrFtr ctHdrFtrFooterHome = null;
try {
ctHdrFtrFooterHome = CTHdrFtr.Factory.parse(footerhomeString);
} catch (XmlException e) {
e.printStackTrace();
}
xwpfFooterHome.setHeaderFooter(ctHdrFtrFooterHome);