Java如何避免在ApachePOI上执行搜索和替换时覆盖模板文件

Java如何避免在ApachePOI上执行搜索和替换时覆盖模板文件,java,apache-poi,xwpf,Java,Apache Poi,Xwpf,我正在使用ApachePOI3.13,试图搜索和替换给定模板文件中的文本,然后保存新生成的.docx。这是我的密码: public static void main(String[] args) throws InvalidFormatException, IOException { String filePath = "Sample.docx"; File outputfile = new File("SampleProcessed.docx"); XWPFDocum

我正在使用ApachePOI3.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);
}
publicstaticvoidmain(字符串[]args)抛出InvalidFormatException,IOException{
字符串filePath=“Sample.docx”;
File outputfile=新文件(“SampleProcessed.docx”);
XWPFDocument doc=新的XWPFDocument(OPCPackage.open(filePath));
对于(XWPFParagraph p:doc.getparagraph()){
List runs=p.getRuns();
如果(运行!=null){
用于(XWPFRun r:运行){
String text=r.getText(0);
如果(text!=null&&text.contains(“$VAR”)){
text=text.replace(“$VAR”,“JohnDoe”);
r、 setText(text,0);
}
}
}
}
doc.write(新文件outputstream(outputfile));
doc.close();
系统输出打印项次(“完成”);
Desktop.getDesktop().open(outputfile);
}
这看起来很简单,但是当我运行这段代码时,“Sample.docx”文档也被替换了。最后,我得到了两份内容完全相同的文件

这是POI的正常行为吗?我认为打开文档只会将其加载到内存中,然后执行“doc.write(OutputStream);”会将其刷新到磁盘

我尝试写入同一个“文件路径”,但正如预期的那样,它引发了一个异常,因为我正在尝试写入当前打开的文件

唯一有效的是当我首先复制模板文件并使用该副本时。但是现在,我有3个文件,第一个是原始模板“Sample.docx”,其余2个有相同的内容(SampleProcessed.docx和SampleProcessedOut.docx)

它起作用了,但相当浪费。有什么办法吗?我做错了什么吗?也许我打开word文档时出错了?

因为您正在使用

XWPFDocument doc = new XWPFDocument(OPCPackage.open(filePath));
要创建
XWPFDocument
,在
READ\u WRITE
模式下从
文件路径打开
OPCPackage
。如果此操作将被关闭,它也将被保存。看

OPCPackage
将关闭,而
XWPFDocument
将关闭

但你为什么这么做?为什么不呢

XWPFDocument doc = new XWPFDocument(new FileInputStream(filePath));
?


有了它,
XWPFDocument
将仅使用新的
OPCPackage
在内存中创建,而与文件没有关系。

这就成功了!谢谢我错过了。对不起,我应该事先看一下文档。我认为OPCPackage是打开.docx文件的唯一方法。再次感谢!还有一个版本的open(),它有一个参数PackageAccess,您可以将READ指定为open模式,从而避免回写数据,请参阅@centic:您尝试过这个吗?如果以只读方式打开
OPCPackage
,您将如何更改
Run
s中的文本?