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

如何使用Apache POI替换.docx中文本框内的文本?

Word文档文本框内容检测与替换问题

我有一份示例文档example document.docx,任务是检测文档中的文本框,分析其中的文本并按需替换。借助Stack Overflow上的回答,我已经能找到文本框内的文本,但不知道如何替换,同时还遇到了重复输出的问题,恳请帮助。

现有代码

public class POITest {

    public static void main(String[] args) throws Exception {

        final var directory = Paths.get("test");
        final var input = directory.resolve("new_debug_input.docx");
        final var output = directory.resolve("new_debug_output.docx");

        try (var open = OPCPackage.open(Files.newInputStream(input))) {
            try (var document = new XWPFDocument(open)) {

                for (XWPFParagraph paragraph : document.getParagraphs()) {
                    printContentsOfTextBox(paragraph, builder);
                }

                document.write(Files.newOutputStream(output,
                        StandardOpenOption.CREATE,
                        StandardOpenOption.TRUNCATE_EXISTING));
            }
        }

    }

    private static void printContentsOfTextBox(XWPFParagraph paragraph, StringBuilder builder) {

        XmlObject[] objects = paragraph.getCTP().selectPath(
                "declare namespace w='http://schemas.openxmlformats.org/wordprocessingml/2006/main'" +
                        "declare namespace wps='http://schemas.microsoft.com/office/word/2010/wordprocessingShape'" +
                        "declare namespace v='urn:schemas-microsoft-com:vml'" +
                        ".//*/wps:txbx/w:txbxContent | .//*/v:textbox/w:txbxContent"
        );

        {
            System.out.println("objects.length = " + objects.length);
            for (XmlObject object : objects) {
                try {
                    XmlObject[] children = object.selectChildren(
                            new QName("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "p")
                    );
                    System.out.println("children.length = " + children.length);
                    for (final XmlObject child : children) {
                        final var childParagraph = new XWPFParagraph(CTP.Factory.parse(child.xmlText()), paragraph.getBody());
                        final var text = childParagraph.getText();
                        if (!text.isEmpty()) {
                            System.out.println(text);
                        }
                    }

                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

}

输出结果

objects.length = 2
children.length = 2
TEXT IN TEXT BOX
TEXT IN TEXT BOX
children.length = 2
TEXT IN TEXT BOX
TEXT IN TEXT BOX

疑问与更新

  • 为何会出现重复输出?
  • 更新1:我理解当前是通过解析XML对象创建新段落来获取现有文本,但修改该段落的文本不会对原文档产生影响。
  • 更新2:尝试使用changeText(paragraph, "REPLACED TEXt")方法无效,替换后文本仍未改变。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 19:18:06