Java 在 Apache POI 上进行搜索和替换时如何避免覆盖模板文件
Java how to avoid overwriting template file when doing search and replace on Apache POI
我正在使用 Apache POI 3.13 并尝试搜索和替换给定模板文件中的文本,然后保存新生成的 .docx。这是我的代码:
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);' 会将其刷新到磁盘。
我尝试写入同一个 'filePath' 但正如预期的那样它抛出异常,因为我正在尝试写入当前打开的文件。
唯一有用的是我先复制了模板文件,然后使用了那个副本。但是现在,我有 3 个文件,第一个是原始模板 'Sample.docx',其余 2 个具有相同的内容(SampleProcessed.docx 和 SampleProcessedOut.docx)。
它有效,但非常浪费。有什么办法吗?我是不是哪里做错了,也许是我打开word文档错了?
因为您正在使用
XWPFDocument doc = new XWPFDocument(OPCPackage.open(filePath));
创建XWPFDocument
,在READ_WRITE
模式下从filePath
打开一个OPCPackage
。如果这将被关闭,它也将被保存。参见 https://poi.apache.org/apidocs/org/apache/poi/openxml4j/opc/OPCPackage.html#close%28%29。
OPCPackage
将关闭,XWPFDocument
将关闭
但你为什么要这样做?为什么不
XWPFDocument doc = new XWPFDocument(new FileInputStream(filePath));
?
有了这个 XWPFDocument
将只在内存中创建一个与文件无关的新 OPCPackage
。
我正在使用 Apache POI 3.13 并尝试搜索和替换给定模板文件中的文本,然后保存新生成的 .docx。这是我的代码:
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);' 会将其刷新到磁盘。
我尝试写入同一个 'filePath' 但正如预期的那样它抛出异常,因为我正在尝试写入当前打开的文件。
唯一有用的是我先复制了模板文件,然后使用了那个副本。但是现在,我有 3 个文件,第一个是原始模板 'Sample.docx',其余 2 个具有相同的内容(SampleProcessed.docx 和 SampleProcessedOut.docx)。
它有效,但非常浪费。有什么办法吗?我是不是哪里做错了,也许是我打开word文档错了?
因为您正在使用
XWPFDocument doc = new XWPFDocument(OPCPackage.open(filePath));
创建XWPFDocument
,在READ_WRITE
模式下从filePath
打开一个OPCPackage
。如果这将被关闭,它也将被保存。参见 https://poi.apache.org/apidocs/org/apache/poi/openxml4j/opc/OPCPackage.html#close%28%29。
OPCPackage
将关闭,XWPFDocument
将关闭
但你为什么要这样做?为什么不
XWPFDocument doc = new XWPFDocument(new FileInputStream(filePath));
?
有了这个 XWPFDocument
将只在内存中创建一个与文件无关的新 OPCPackage
。