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











up vote
1
down vote

favorite












I have the problem with the following code:



XWPFTable table = <get table somehow>;
CTRow firstRow = table.getRow(0).getCtRow();

for (int i = 0; i < data.getRowCount(); i++) {
CTRow ctRow = (CTRow) firstRow.copy();
XWPFTableRow row = new XWPFTableRow(ctRow, table);
XWPFRun cellRuns = row.getTableCells()
.stream()
.map(c -> c.getParagraphs().get(0))
.map(p -> p.getRuns().isEmpty() ? p.createRun() : p.getRuns().get(0))
.toArray(XWPFRun::new);
for (int j = 0; j < cellRuns.length; j++) {
cellRuns[j].setText(data.getValueAt(i, j).toString(), 0);
}
table.addRow(row);
}


table.getRow(1).getTableCells()
.get(0).getParagraphs()
.get(0).getRuns()
.get(0).setText("FooBar", 0); //change text in some added row


This code is copying the first row of the table several times and then copying values from data. Works perfectly fine (except text style) except the last operator, which was supposed to change the text in some added table row. Also, the "FooBar" string doesn't even appear in document.xml of created WORD document. I failed to see any clues from debug, because it seems, that table.addRow(row); operator just copies row pointer to it's internal list of rows. Also, I didn't have problems with altering already existing rows. So do you have any ideas why this could happen?










share|improve this question




















  • 1




    Why don't you try changing your row text (to the "FooBar") in the inner for loop using an if condition while setting the text to the cellRuns array?
    – Abhinav
    Nov 8 at 16:42






  • 1




    See stackoverflow.com/questions/46235410/…: Read second paragraph in my answer.
    – Axel Richter
    Nov 8 at 16:52










  • @Abhinav, I already did this, but I really want to understand what is wrong with the code. It doesn't seem right, cause when I change the existing row, it works. Also, values actually change in debugger after adding, theese changes just are not saved in the docx.
    – Astralogics Ktt
    Nov 8 at 16:55










  • @Astralogics Ktt Would you please edit your question properly by pasting the complete code so that we can better understanding of your problem?
    – Abhinav
    Nov 8 at 17:00










  • @Abhinav, there is similar code in link in Axel Richter's comment. Moving table.addRow(newRow, 2); instruction to newRow declaration should reproduce the problem
    – Astralogics Ktt
    Nov 8 at 17:08















up vote
1
down vote

favorite












I have the problem with the following code:



XWPFTable table = <get table somehow>;
CTRow firstRow = table.getRow(0).getCtRow();

for (int i = 0; i < data.getRowCount(); i++) {
CTRow ctRow = (CTRow) firstRow.copy();
XWPFTableRow row = new XWPFTableRow(ctRow, table);
XWPFRun cellRuns = row.getTableCells()
.stream()
.map(c -> c.getParagraphs().get(0))
.map(p -> p.getRuns().isEmpty() ? p.createRun() : p.getRuns().get(0))
.toArray(XWPFRun::new);
for (int j = 0; j < cellRuns.length; j++) {
cellRuns[j].setText(data.getValueAt(i, j).toString(), 0);
}
table.addRow(row);
}


table.getRow(1).getTableCells()
.get(0).getParagraphs()
.get(0).getRuns()
.get(0).setText("FooBar", 0); //change text in some added row


This code is copying the first row of the table several times and then copying values from data. Works perfectly fine (except text style) except the last operator, which was supposed to change the text in some added table row. Also, the "FooBar" string doesn't even appear in document.xml of created WORD document. I failed to see any clues from debug, because it seems, that table.addRow(row); operator just copies row pointer to it's internal list of rows. Also, I didn't have problems with altering already existing rows. So do you have any ideas why this could happen?










share|improve this question




















  • 1




    Why don't you try changing your row text (to the "FooBar") in the inner for loop using an if condition while setting the text to the cellRuns array?
    – Abhinav
    Nov 8 at 16:42






  • 1




    See stackoverflow.com/questions/46235410/…: Read second paragraph in my answer.
    – Axel Richter
    Nov 8 at 16:52










  • @Abhinav, I already did this, but I really want to understand what is wrong with the code. It doesn't seem right, cause when I change the existing row, it works. Also, values actually change in debugger after adding, theese changes just are not saved in the docx.
    – Astralogics Ktt
    Nov 8 at 16:55










  • @Astralogics Ktt Would you please edit your question properly by pasting the complete code so that we can better understanding of your problem?
    – Abhinav
    Nov 8 at 17:00










  • @Abhinav, there is similar code in link in Axel Richter's comment. Moving table.addRow(newRow, 2); instruction to newRow declaration should reproduce the problem
    – Astralogics Ktt
    Nov 8 at 17:08













up vote
1
down vote

favorite









up vote
1
down vote

favorite











I have the problem with the following code:



XWPFTable table = <get table somehow>;
CTRow firstRow = table.getRow(0).getCtRow();

for (int i = 0; i < data.getRowCount(); i++) {
CTRow ctRow = (CTRow) firstRow.copy();
XWPFTableRow row = new XWPFTableRow(ctRow, table);
XWPFRun cellRuns = row.getTableCells()
.stream()
.map(c -> c.getParagraphs().get(0))
.map(p -> p.getRuns().isEmpty() ? p.createRun() : p.getRuns().get(0))
.toArray(XWPFRun::new);
for (int j = 0; j < cellRuns.length; j++) {
cellRuns[j].setText(data.getValueAt(i, j).toString(), 0);
}
table.addRow(row);
}


table.getRow(1).getTableCells()
.get(0).getParagraphs()
.get(0).getRuns()
.get(0).setText("FooBar", 0); //change text in some added row


This code is copying the first row of the table several times and then copying values from data. Works perfectly fine (except text style) except the last operator, which was supposed to change the text in some added table row. Also, the "FooBar" string doesn't even appear in document.xml of created WORD document. I failed to see any clues from debug, because it seems, that table.addRow(row); operator just copies row pointer to it's internal list of rows. Also, I didn't have problems with altering already existing rows. So do you have any ideas why this could happen?










share|improve this question















I have the problem with the following code:



XWPFTable table = <get table somehow>;
CTRow firstRow = table.getRow(0).getCtRow();

for (int i = 0; i < data.getRowCount(); i++) {
CTRow ctRow = (CTRow) firstRow.copy();
XWPFTableRow row = new XWPFTableRow(ctRow, table);
XWPFRun cellRuns = row.getTableCells()
.stream()
.map(c -> c.getParagraphs().get(0))
.map(p -> p.getRuns().isEmpty() ? p.createRun() : p.getRuns().get(0))
.toArray(XWPFRun::new);
for (int j = 0; j < cellRuns.length; j++) {
cellRuns[j].setText(data.getValueAt(i, j).toString(), 0);
}
table.addRow(row);
}


table.getRow(1).getTableCells()
.get(0).getParagraphs()
.get(0).getRuns()
.get(0).setText("FooBar", 0); //change text in some added row


This code is copying the first row of the table several times and then copying values from data. Works perfectly fine (except text style) except the last operator, which was supposed to change the text in some added table row. Also, the "FooBar" string doesn't even appear in document.xml of created WORD document. I failed to see any clues from debug, because it seems, that table.addRow(row); operator just copies row pointer to it's internal list of rows. Also, I didn't have problems with altering already existing rows. So do you have any ideas why this could happen?







java ms-word apache-poi xmlbeans






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 8 at 17:23

























asked Nov 8 at 16:12









Astralogics Ktt

82




82








  • 1




    Why don't you try changing your row text (to the "FooBar") in the inner for loop using an if condition while setting the text to the cellRuns array?
    – Abhinav
    Nov 8 at 16:42






  • 1




    See stackoverflow.com/questions/46235410/…: Read second paragraph in my answer.
    – Axel Richter
    Nov 8 at 16:52










  • @Abhinav, I already did this, but I really want to understand what is wrong with the code. It doesn't seem right, cause when I change the existing row, it works. Also, values actually change in debugger after adding, theese changes just are not saved in the docx.
    – Astralogics Ktt
    Nov 8 at 16:55










  • @Astralogics Ktt Would you please edit your question properly by pasting the complete code so that we can better understanding of your problem?
    – Abhinav
    Nov 8 at 17:00










  • @Abhinav, there is similar code in link in Axel Richter's comment. Moving table.addRow(newRow, 2); instruction to newRow declaration should reproduce the problem
    – Astralogics Ktt
    Nov 8 at 17:08














  • 1




    Why don't you try changing your row text (to the "FooBar") in the inner for loop using an if condition while setting the text to the cellRuns array?
    – Abhinav
    Nov 8 at 16:42






  • 1




    See stackoverflow.com/questions/46235410/…: Read second paragraph in my answer.
    – Axel Richter
    Nov 8 at 16:52










  • @Abhinav, I already did this, but I really want to understand what is wrong with the code. It doesn't seem right, cause when I change the existing row, it works. Also, values actually change in debugger after adding, theese changes just are not saved in the docx.
    – Astralogics Ktt
    Nov 8 at 16:55










  • @Astralogics Ktt Would you please edit your question properly by pasting the complete code so that we can better understanding of your problem?
    – Abhinav
    Nov 8 at 17:00










  • @Abhinav, there is similar code in link in Axel Richter's comment. Moving table.addRow(newRow, 2); instruction to newRow declaration should reproduce the problem
    – Astralogics Ktt
    Nov 8 at 17:08








1




1




Why don't you try changing your row text (to the "FooBar") in the inner for loop using an if condition while setting the text to the cellRuns array?
– Abhinav
Nov 8 at 16:42




Why don't you try changing your row text (to the "FooBar") in the inner for loop using an if condition while setting the text to the cellRuns array?
– Abhinav
Nov 8 at 16:42




1




1




See stackoverflow.com/questions/46235410/…: Read second paragraph in my answer.
– Axel Richter
Nov 8 at 16:52




See stackoverflow.com/questions/46235410/…: Read second paragraph in my answer.
– Axel Richter
Nov 8 at 16:52












@Abhinav, I already did this, but I really want to understand what is wrong with the code. It doesn't seem right, cause when I change the existing row, it works. Also, values actually change in debugger after adding, theese changes just are not saved in the docx.
– Astralogics Ktt
Nov 8 at 16:55




@Abhinav, I already did this, but I really want to understand what is wrong with the code. It doesn't seem right, cause when I change the existing row, it works. Also, values actually change in debugger after adding, theese changes just are not saved in the docx.
– Astralogics Ktt
Nov 8 at 16:55












@Astralogics Ktt Would you please edit your question properly by pasting the complete code so that we can better understanding of your problem?
– Abhinav
Nov 8 at 17:00




@Astralogics Ktt Would you please edit your question properly by pasting the complete code so that we can better understanding of your problem?
– Abhinav
Nov 8 at 17:00












@Abhinav, there is similar code in link in Axel Richter's comment. Moving table.addRow(newRow, 2); instruction to newRow declaration should reproduce the problem
– Astralogics Ktt
Nov 8 at 17:08




@Abhinav, there is similar code in link in Axel Richter's comment. Moving table.addRow(newRow, 2); instruction to newRow declaration should reproduce the problem
– Astralogics Ktt
Nov 8 at 17:08












1 Answer
1






active

oldest

votes

















up vote
0
down vote



accepted










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.






share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53211749%2fcant-change-row-text-in-docx-file-once-row-is-added-to-table%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    0
    down vote



    accepted










    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.






    share|improve this answer



























      up vote
      0
      down vote



      accepted










      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.






      share|improve this answer

























        up vote
        0
        down vote



        accepted







        up vote
        0
        down vote



        accepted






        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.






        share|improve this answer














        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.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 11 at 8:19

























        answered Nov 11 at 8:05









        Axel Richter

        23.8k21733




        23.8k21733






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53211749%2fcant-change-row-text-in-docx-file-once-row-is-added-to-table%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Xamarin.iOS Cant Deploy on Iphone

            Glorious Revolution

            Dulmage-Mendelsohn matrix decomposition in Python