我使用Apache POI替换docx的单词。对于正常段落,我成功使用XWPFParagraph和XWPFRun来替换单词。然后我尝试替换文本框中的单词。我引用了此https://stackoverflow.com/a/25877256来获取文本框中的文本。我成功在控制台中打印文本。但是,我无法替换文本框中的单词。 以下是我的一些代码:
for (XWPFParagraph paragraph : doc.getParagraphs()) {
XmlObject[] textBoxObjects = paragraph.getCTP().selectPath("declare namespace w='http://schemas.openxmlformats.org/wordprocessingml/2006/main' declare namespace wps='http://schemas.microsoft.com/office/word/2010/wordprocessingShape' .//*/wps:txbx/w:txbxContent");
for (int i =0; i < textBoxObjects.length; i++) {
XWPFParagraph embeddedPara = null;
try {
XmlObject[] paraObjects = textBoxObjects[i].
selectChildren(
new QName("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "p"));
for (int j=0; j<paraObjects.length; j++) {
embeddedPara = new XWPFParagraph(CTP.Factory.parse(paraObjects[j].xmlText()), paragraph.getBody());
List<XWPFRun> runs = embeddedPara.getRuns();
for (XWPFRun r : runs) {
String text = r.getText(0);
if (text != null && text.contains(someWords)) {
text = text.replace(someWords, "replaced");
r.setText(text, 0);
}
}
}
} catch (XmlException e) {
//handle
}
}
}
我认为问题在于我创建了一个新的XWPFParagraph embeddedPara,它取代了embeddedPara的单词而不是原始段落。因此,在我写入文件后,单词仍然没有改变。
如何在不创建新的XWPFParagraph的情况下阅读和替换文本框中的单词?
答案 0 :(得分:6)
出现此问题是因为Word
文本框可能包含在XmlObjects
版本的多个不同Word
依赖项中。那些XmlObjects
也可能位于非常不同的名称空间中。因此selectChildren
无法跟随名称空间路由,因此它将返回XmlAnyTypeImpl
。
所有文本框实现的共同点是它们的运行位于路径.//*/w:txbxContent/w:p/w:r
中。所以我们可以使用选择该路径的XmlCursor
。然后,我们会在XmlObjects
中收集所有选定的List<XmlObject>
。然后我们从那些对象中解析CTR
,这些对象当然只在文档上下文之外CTR
。但是我们可以从那些创建XWPFRuns
,在那里替换,然后set
将XWPFRuns
的XML内容返回到对象。在此之后,我们有包含替换内容的对象。
示例:
import java.io.FileOutputStream;
import java.io.FileInputStream;
import org.apache.poi.xwpf.usermodel.*;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlCursor;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTR;
import java.util.List;
import java.util.ArrayList;
public class WordReplaceTextInTextBox {
public static void main(String[] args) throws Exception {
XWPFDocument document = new XWPFDocument(new FileInputStream("WordReplaceTextInTextBox.docx"));
String someWords = "TextBox";
for (XWPFParagraph paragraph : document.getParagraphs()) {
XmlCursor cursor = paragraph.getCTP().newCursor();
cursor.selectPath("declare namespace w='http://schemas.openxmlformats.org/wordprocessingml/2006/main' .//*/w:txbxContent/w:p/w:r");
List<XmlObject> ctrsintxtbx = new ArrayList<XmlObject>();
while(cursor.hasNextSelection()) {
cursor.toNextSelection();
XmlObject obj = cursor.getObject();
ctrsintxtbx.add(obj);
}
for (XmlObject obj : ctrsintxtbx) {
CTR ctr = CTR.Factory.parse(obj.xmlText());
//CTR ctr = CTR.Factory.parse(obj.newInputStream());
XWPFRun bufferrun = new XWPFRun(ctr, (IRunBody)paragraph);
String text = bufferrun.getText(0);
if (text != null && text.contains(someWords)) {
text = text.replace(someWords, "replaced");
bufferrun.setText(text, 0);
}
obj.set(bufferrun.getCTR());
}
}
document.write(new FileOutputStream("WordReplaceTextInTextBoxNew.docx"));
document.close();
}
}