You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Apache POI操作Word(docx)文档:修改后另存为新文件时的源文件变更异常问题咨询

为什么关闭XWPFDocument会修改原文件?

这个问题的核心在于Apache POI中OPCPackage的默认打开模式和文档修改后的同步逻辑,我来帮你拆解三种运行场景背后的原因:

先理清核心机制

当你用XWPFDocument doc = new XWPFDocument(OPCPackage.open(source));打开文档时,OPCPackage.open(source)默认是以**读写模式(PackageAccess.READ_WRITE)**打开原文件的。此时,原文件的内容会被加载到内存中,但底层的OPCPackage会保留对原文件的写入权限。

另外,你对XWPFParagraph、XWPFRun的修改,最初只存在于XWPF的内存对象模型中,并不会自动同步到底层的OPCPackage缓存——只有当你调用doc.write()方法时,POI才会把内存中的修改同步到OPCPackage里,并标记它为"脏数据"(需要写入磁盘)。

三种场景的具体解释

  • 仅关闭文档,不写入目标文件
    你修改了内存中的XWPFRun,但没有调用doc.write(),所以这些修改只停留在XWPF的对象模型里,没有同步到OPCPackage。此时调用doc.close()关闭文档,OPCPackage因为没有脏数据,所以不会写回原文件,原文档自然保持不变,也不会生成目标文件。

  • 写入目标文件后关闭文档
    调用doc.write(fos)时,POI不仅会把内存中的文档内容写入目标文件,还会同步更新底层的OPCPackage,把修改标记为脏数据。当你接着调用doc.close(),OPCPackage会以读写模式关闭,自动将脏数据写回原文件,导致原文档被修改。

  • 写入目标文件但不关闭文档
    调用doc.write(fos)同样会同步修改到OPCPackage并标记为脏数据,但因为你没有调用doc.close(),OPCPackage没有触发关闭时的自动写入逻辑,所以原文件不会被修改,而目标文件已经生成了符合预期的内容。

正确的解决方案

要避免原文件被意外修改,最稳妥的方式是以只读模式打开原文件的OPCPackage。这样不管后续怎么修改内存中的文档对象,OPCPackage都没有写入原文件的权限,关闭时也不会触发写回操作。修改后的代码如下:

public void copyTesting(String source, String destination) throws IOException, InvalidFormatException {
    // 以只读模式打开原文件的OPCPackage
    OPCPackage pkg = OPCPackage.open(source, PackageAccess.READ);
    XWPFDocument doc = new XWPFDocument(pkg);
    
    // 你的修改逻辑不变
    for (XWPFParagraph par : doc.getParagraphs()) {
        List<XWPFRun> runs = par.getRuns();
        if (runs.size() > 0) {
            XWPFRun run = par.getRuns().get(0);
            String text = run.getText(0);
            text = text + "!";
            run.setText(text, 0);
        }
    }
    
    // 写入目标文件并正常关闭资源
    try (FileOutputStream fos = new FileOutputStream(destination)) {
        doc.write(fos);
    } finally {
        doc.close();
        pkg.close();
    }
}

这样修改后,无论你是否关闭文档,原文件都不会被修改,同时能正常生成带有修改内容的目标文件,符合你的需求。

内容的提问来源于stack exchange,提问作者arcy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 14:08:12