Can't change row text in .docx file once row is added to table

后端 未结 1 1352
小鲜肉
小鲜肉 2021-01-15 02:53

I have the problem with the following code:

XWPFTable table = ;
CTRow firstRow = table.getRow(0).getCtRow();

for (int i = 0; i <         


        
相关标签:
1条回答
  • 2021-01-15 03:20

    To reproducing the problem do having a source.docx having a first table having at least two rows.

    Then do running following code:

    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import org.apache.poi.xwpf.usermodel.*;
    
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRow;
    
    public class WordInsertTableRow {
    
     static XWPFTableRow insertNewTableRow(XWPFTableRow sourceTableRow, int pos) throws Exception {
      XWPFTable table = sourceTableRow.getTable();
      CTRow newCTRrow = CTRow.Factory.parse(sourceTableRow.getCtRow().newInputStream());
      XWPFTableRow tableRow = new XWPFTableRow(newCTRrow, table);
      table.addRow(tableRow, pos);
      return tableRow;
     }
    
     static void commitTableRows(XWPFTable table) {
      int rowNr = 0;
      for (XWPFTableRow tableRow : table.getRows()) {
       table.getCTTbl().setTrArray(rowNr++, tableRow.getCtRow());
      }
     }
    
     public static void main(String[] args) throws Exception {
    
      XWPFDocument doc = new XWPFDocument(new FileInputStream("source.docx"));
      boolean weMustCommitTableRows = false;
    
      XWPFTable table = doc.getTableArray(0);
    
      // insert new row, which is a copy of row 2, as new row 3:
      XWPFTableRow sourceTableRow = table.getRow(1);
      XWPFTableRow newRow3 = insertNewTableRow(sourceTableRow, 2);
    
      // now changing something in that new row:
      int i = 1;
      for (XWPFTableCell cell : newRow3.getTableCells()) {
       for (XWPFParagraph paragraph : cell.getParagraphs()) {
        for (XWPFRun run : paragraph.getRuns()) {
         run.setText("New row 3 run " + i++, 0);
        }
       }
      }
    System.out.println(newRow3.getCtRow()); // was changed
    System.out.println(table.getRow(2).getCtRow()); // even this is changed
    System.out.println(table.getCTTbl().getTrArray(2)); // but this was not changed, why not?
      weMustCommitTableRows = true;
    
      if (weMustCommitTableRows) commitTableRows(table); // now it is changed
    
      FileOutputStream out = new FileOutputStream("result.docx");
      doc.write(out);
      out.close();
      doc.close();
    
     }
    }
    

    This code creates a copy of second row and inserts it as third row in the table. Then it does changing something in that new third row.

    The issue ist, that the changings do appearing in low level CTRow of the row itself but do not appearing in low Level CTTbl of the table. For me this is not logically and I cannot get the reason of that. It looks as if the new CTRow elements are not part of the CTTbl at all. But they were added to it using ctTbl.setTrArray in XWPFTable.addRow. So I suspect there is something wrong with setTrArray in org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl. It seems updating the XML correctly but losing the object relations in the array (or list) of CTRows in CTTbl. But this is very hard to determining because of the kind of programming the org.openxmlformats.schemas classes. At least I was not able to do so. Maybe another of the professional and enthusiast programmers here may be able?

    I am using the same approach for inserting rows having tthe same styling as a given source row. But after I have done this, I am setting boolean weMustCommitTableRows = true; and then I am doing if (weMustCommitTableRows) commitTableRows(table); before writing out the document. Then all changings will be committed.

    0 讨论(0)
提交回复
热议问题