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

标签 java apache-poi xwpf

我正在使用 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)。

它有效,但非常浪费。有什么办法吗?我做错了什么,也许我打开了错误的文档?

最佳答案

因为你正在使用

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 在内存中创建,与文件无关。

关于Java如何在Apache POI上进行搜索和替换时避免覆盖模板文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35389122/

相关文章:

java - 如何在 Java 的 POI 中使用 XWPFTable 合并单元格(或应用 colspan)?

java - XWPFTable 的行跨度

java - 与 C++ 相比,Java 中的访问修饰符

java - 如果套接字已打开,则强制关闭该套接字

java - 从 Excel 工作表读取日期值 (Java)

java - Apache POI 和自动行高以及合并单元格

java - 如何使用 Apache POI XWPFDocument 在 Java 中生成多级嵌套编号列表?

java - 通过 JDBC 连接到 Derby 数据库失败

java - JAXB 2.1 绑定(bind)自定义选项

java - 使用 Apache POI 在 Word 文档中添加水印