将行添加到表后,无法更改.docx文件中的行文本 [英] Can't change row text in .docx file once row is added to table

查看:142
本文介绍了将行添加到表后,无法更改.docx文件中的行文本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下代码有问题:

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

此代码将表的第一行复制多次,然后从data复制值.除最后一个运算符外,它的工作原理非常好(文本样式除外),该运算符应该更改某些添加的表行中的文本.另外,"FooBar"字符串甚至不会出现在创建的WORD文档的document.xml中.我看不到调试提供的任何线索,因为看来table.addRow(row);运算符只是将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?

推荐答案

要重现此问题,请使source.docx的第一个表至少包含两行.

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

然后运行以下代码:

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.

问题在于,所做的更改确实出现在行本身的较低级别CTRow中,但没有出现在表的较低级别CTTbl中.对我来说,这在逻辑上是不合理的,我无法理解其原因.看起来新的CTRow元素根本不是CTTbl的一部分.但是使用

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?

我使用相同的方法来插入样式与给定源行相同的行.但是,在完成此操作之后,我将先设置boolean weMustCommitTableRows = true;,然后再执行if (weMustCommitTableRows) commitTableRows(table);,然后再写出文档.然后所有更改都将提交.

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.

这篇关于将行添加到表后,无法更改.docx文件中的行文本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆