Apache POI XWPFRun.setText()无法工作

4

我希望能够利用Apache POI 3.10来操作XWPFDocument中的文本运行,但是XWPFRun.setText()方法并没有按照我的期望发挥作用。以下是我的代码:

XWPFDocument doc = new XWPFDocument(resp.getContent());
for (XWPFParagraph paragraph : doc.getParagraphs()) {
    for (XWPFRun run : paragraph.getRuns()) {
        int textPosition = run.getTextPosition();
        if (run.getText(textPosition) != null) {
            System.out.println("old value: " + run.getText(textPosition));
            run.setText("value changed", textPosition);
            System.out.println("new value: " + run.getText(textPosition));
        }
    }
}

生成输出:
old value: change me
new value: change me

如何在XWPFDocument中正确更新单个运行的方式是什么?


1
更改后貌似没有任何代码将文件再次写出 - 真的这么简单吗? - Gagravarr
@Gagravarr 是的,它就是那么简单... 但是,我不明白为什么需要将文档存储在文件中才能应用更改。 - Artur Malinowski
因为这就是库的工作方式 - 它将其加载到内存中,您在内存中进行更改,然后保存。就像 Word 一样 - 当您完成时需要告诉它保存! - Gagravarr
4
不行。我使用“setText()”在内存中进行更改,所以我想使用“getText()”从内存中读取。对我来说,使用类似getter和setter的方法是很明显的。如果你在Word中替换文本,则可以在不保存的情况下查看替换后的值。 - Artur Malinowski
啊,我明白了!如果你使用 XWPFRun.toString() 来获取运行时的文本,会发生什么呢?你确定你正在使用最新版本的 Apache POI 吗? - Gagravarr
你确实需要保存到文件中,例如doc.write(new FileOutputStream(outfile));。 - sp_nz
3个回答

0
我曾经使用run.toString()来解决类似于你的问题。(org.apache.poi 3.15) 在调用setText(..)之后,.toString()的输出会发生变化。

System.out.println("toString(): " + run.toString());


0

已经有一段时间了,而且解释有点隐藏在注释之间,所以总结一下可能是值得的。

实际上,Apache POI 的行为没有 bug。问题在于命名约定 - 尽管 POI 使用 get/set 方法,但这并不意味着类遵守 JavaBeans 规则。在这个例子中,setText 方法确实完成了工作 - 所有更改都将在保存编辑后的文档后应用。


0
这是对我有效的方法:
for (XWPFParagraph paragraph : document.getParagraphs()) {
    for (XWPFRun run : paragraph.getRuns()) {
        int textPosition = run.getTextPosition();
        if (run.getText(textPosition) != null) {
            System.out.println("old value: " + run.getText(textPosition));
            run.setText("value changed", 0); // <<------ the difference is here
            System.out.println("new value: " + run.getText(textPosition));
        }
    }
}

问题的提问者说你必须在查看更改之前保存文档,而且代码实际上是正确的。我不需要保存任何东西,它对我来说只是起作用了一点点不同:
我必须将0作为pos参数传递给run.setText,而不是之前从run获取的textPosition,这样它就覆盖了文本。
(我还想改变文本,对我来说setText(String value)追加了文本而不是替换它,而setText(String value, int pos)对我来说完成了工作。)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接