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

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

问题描述

我遇到以下代码的问题:

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

此代码多次复制表的第一行,然后从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 的一部分.但是它们是在 XWPFTable.addRow.所以我怀疑 org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl 中的 setTrArray 有问题.似乎正确更新了 XML,但丢失了 CTTblCTRow 的数组(或列表)中的对象关系.但由于 org.openxmlformats.schemas 类的编程类型,这很难确定.至少我做不到.也许这里的另一位专业和狂热的程序员可以?

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天全站免登陆