Replace text in text box of docx by using Apache POI

一笑奈何 提交于 2019-12-06 10:36:40

The problem occurs because the Word text boxes may be contained in multiple different XmlObjects dependent of the Word version. Those XmlObjects may also be in very different name spaces. So the selectChildren cannot following the name space route and so it will return a XmlAnyTypeImpl.

What all text box implementatrion have in common is that their runs are in the path .//*/w:txbxContent/w:p/w:r. So we can using a XmlCursor which selects that path. Then we collect all selected XmlObjects in a List<XmlObject>. Then we parse CTRs from those objects, which are of course only CTRs outside the document context. But we can creating XWPFRuns from those, do the replacing there and then set the XML content of those XWPFRuns back to the objects. After this we have the objects containing the replaced content.

Example:

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();
 }
}

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!