0
votes

In a docx document I exchange placeholders by some other value with Apache POI. A special case I don't get realized is when the placeholder is within a paragraph that is within a textbox in a docx file.

For replacement in paragraphs I found this: Replacing a text in Apache POI XWPF which was helpful and works fine for "normal" paragraphs.

Now there is a paragraph (and also a table - but that will be another question) within a textbox. In https://stackoverflow.com/a/25877256/14972917 there is a description how to get text from a paragraph that is embedded in a textbox. This works fine to read the text.

When I call the replace2 method of the first link within the for loop in the second link then it looks like this:

    for (int j = 0; j < paraObjects.length; j++) {
        embeddedPara = new XWPFParagraph(CTP.Factory.parse(paraObjects[j].xmlText()), paragraph.getBody());
        // Here you have your paragraph;
        System.out.println(embeddedPara.getText());
        replace2(null, embeddedPara, normierteDaten);
    }

This code prints out the expected text, calls the replace2 method and actually calls setText at the right XWPFRun, but the output docx still contains the placeholder "${name}".

Can I somehow write back the modified embeddedPara object into the original document? Something like paraObjects[j].setXmlText(embeddedPara.getXml())?

This is how the XML fragment of the paraObject looks (actually there is an additional table after the w:p element):

<xml-fragment xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml">
  <w:p>
    <w:pPr>
      <w:pStyle w:val="FrameContents"/>
      <w:overflowPunct w:val="true"/>
      <w:rPr/>
    </w:pPr>
    <w:r>
      <w:rPr>
        <w:rFonts w:ascii="Arial" w:hAnsi="Arial"/>
        <w:color w:val="FFFFFF"/>
        <w:sz w:val="44"/>
        <w:szCs w:val="44"/>
      </w:rPr>
      <w:t>Hello ${name}!</w:t>
    </w:r>
  </w:p>
1

1 Answers

0
votes

Found it: paraObjects[j].set(embeddedPara.getCTP());.

And a little more further: this is some code to replace placeholders in tables within textboxes, "inspired" by https://stackoverflow.com/a/25877256/14972917 and combined with the replacement mechanism from here https://stackoverflow.com/a/41407196/14972917 :

XWPFTable embeddedTable = null;
try {
    XmlObject[] tableXmlObjects = textBoxObjects[i].selectChildren(
            new QName("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "tbl"));
    for (int j = 0; j < tableXmlObjects.length; j++) {
        embeddedTable = new XWPFTable(CTTbl.Factory.parse(tableXmlObjects[j].xmlText()), paragraph.getBody());
        // Here you have your paragraph;
        replaceInTable(embeddedTable, data);
        tableXmlObjects[j].set(embeddedTable.getCTTbl());
    }
} catch (XmlException e) {
    // inform somebody or do something else
}

... with this method replaceInTable to iterate all paragraphs in a table in a textblock in a docx document:

private static void replaceInTable(XWPFTable tbl, Map<String, String> data)
        throws Exception {
    List<XWPFTableRow> rows = new ArrayList<>(tbl.getRows());
    for (int rowIndex = 0; rowIndex < rows.size(); rowIndex++) {
        XWPFTableRow row = rows.get(rowIndex);
        for (XWPFTableCell cell : row.getTableCells()) {
            for (XWPFParagraph p : cell.getParagraphs()) {
                replace2(cell, p, data);
            }
        }
    }
}