我正在使用Apache POI 3.13并试图从给定的模板文件中搜索和替换文本,然后保存新生成的.docx。这里是我的代码:Java如何避免在搜索和替换Apache POI时覆盖模板文件
public static void main(String[] args) throws InvalidFormatException, IOException {
String filePath = "Sample.docx";
File outputfile = new File("SampleProcessed.docx");
XWPFDocument doc = new XWPFDocument(OPCPackage.open(filePath));
for (XWPFParagraph p : doc.getParagraphs()) {
List<XWPFRun> runs = p.getRuns();
if (runs != null) {
for (XWPFRun r : runs) {
String text = r.getText(0);
if (text != null && text.contains("$VAR")) {
text = text.replace("$VAR", "JohnDoe");
r.setText(text, 0);
}
}
}
}
doc.write(new FileOutputStream(outputfile));
doc.close();
System.out.println("Done");
Desktop.getDesktop().open(outputfile);
}
这看起来很简单,但是当我运行此代码,“Sample.docx”的文件也被替换。最后,我有两个具有相同内容的文档。
这是POI的正常行为吗?我认为打开文档只会将其加载到内存中,然后执行'doc.write(OutputStream);'会将其刷新到磁盘。
我试图写入相同的'文件路径',但正如所料,它会引发异常,因为我试图写入当前打开的文件。
唯一有效的工作是当我先复制模板文件并改为使用该副本。但是现在,我有3个文件,第一个是原始模板“Sample.docx”,其余2个文件的内容相同(SampleProcessed.docx和SampleProcessedOut.docx)。
它的工作,但它是很浪费。有什么办法吗?我做错了什么,也许我打开错误的文字?
这工作!谢谢!我错过了。对不起,我应该事先阅读文档。我认为OPCPackage是打开.docx文件的唯一方法。再次感谢! – yev
还有一个open()的版本,它有一个参数PackageAccess,您可以在其中指定READ作为开放模式,从而避免写回数据,请参阅https://poi.apache.org/apidocs/org/ apache/poi/openxml4j/opc/OPCPackage.html#open(java.io.File,%20org.apache.poi.openxml4j.opc.PackageAccess) – centic
@centic:你试过这个吗?如果OPCPackage被打开,你将如何改变'Run'中的文本? –