Apache POI - 如何在Word表中设置正确的列宽

时间:2016-12-26 18:52:13

标签: apache-poi

我有一个包含表格的现有Word文档。该表的第一行有两个单元格,但所有其他行都有四个单元格,每个单元格的宽度不同。

我需要通过POI插入新行,这些行也有四个宽度与现有4个单元行相匹配的单元格。

基本代码是:

XWPFTable table = doc.getTableArray(0);

XWPFTableRow oldRow = table.getRow(2);
table.insertNewTableRow(3);
XWPFTableRow newRow = table.getRow(3);

XWPFTableCell cell;
for (int i = 0; i < oldRow.getTableCells().size(); i++) {
    cell = newRow.createCell();
    CTTblWidth cellWidth = cell.getCTTc().addNewTcPr().addNewTcW();
    BigInteger width = oldRow.getCell(i).getCTTc().getTcPr().getTcW().getW();

    cellWidth.setW(width);  // sets width

    XWPFRun run = cell.getParagraphs().get(0).createRun();
    run.setText("NewRow C" + i); 

}

结果是第3行有四个单元格,但它们的宽度与第2行的宽度不匹配。新的行总宽度最终与第2行的前三个单元格的总宽度相同。(对不起) ,我不知道如何在这里粘贴Word表。)

但是,如果我首先手动编辑源文档,以便第一个表行也有四个单元格,那么一切都很完美。类似地,如果我获得对现有行的引用并将其添加到表中,那么单元格宽度也是正确的(但我有两次相同的行对象,因此无法对其进行修改)。

第一行中的单元格数似乎会影响其他行的插入方式。这对任何人都有意义,你能建议如何覆盖它吗?另外,我是否可以在任何地方学习文档以了解其工作原理?感谢。

1 个答案:

答案 0 :(得分:1)

根据您的提及:&#34;表格的第一行有两个单元格,但所有其他行都有四个单元格,每个单元格的宽度不同。&#34;我怀疑这将是一个非常混乱的表。虽然Word支持这样的表,但我会尽量避免这样。但如果必须如此,你需要知道那些凌乱的表也有一个表格。解压缩*.docx并查看/word/document.xml您将找到它。

因此,如果我们想要将行插入到这样的杂乱表中,我们也必须尊重表格。为此,GridSpan中有CTTcPr个元素。我们还必须从oldRow复制,而不仅仅是复制CTTblWidth

此外CTTblWidth不仅有宽度,还有类型。我们也应该复制。

示例:

source.docx看起来像这样:

enter image description here

如您所见,表格总共有10列。 &#34; Cell 2 1&#34;跨越3列,&#34;单元格2 2&#34;跨越3列,&#34; Cell 2 3&#34;跨越0列(是它自己的列),&#34;单元格2 4&#34;跨越3列。

使用代码:

import java.io.*;
import org.apache.poi.xwpf.usermodel.*;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;

import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblWidth;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTcPr;

import java.math.BigInteger;

public class WordInsertTableRow {

 public static void main(String[] args) throws IOException, InvalidFormatException {

  XWPFDocument doc = new XWPFDocument(new FileInputStream("source.docx"));

  XWPFTable table = doc.getTableArray(0);

  XWPFTableRow oldRow = table.getRow(2);
  table.insertNewTableRow(3);
  XWPFTableRow newRow = table.getRow(3);

  XWPFTableCell cell;
  for (int i = 0; i < oldRow.getTableCells().size(); i++) {
   cell = newRow.createCell();

   CTTcPr ctTcPr = cell.getCTTc().addNewTcPr();

   CTTblWidth cellWidth = ctTcPr.addNewTcW();
   cellWidth.setType(oldRow.getCell(i).getCTTc().getTcPr().getTcW().getType());  // sets type of width
   BigInteger width = oldRow.getCell(i).getCTTc().getTcPr().getTcW().getW();
   cellWidth.setW(width);  // sets width

   if (oldRow.getCell(i).getCTTc().getTcPr().getGridSpan() != null) {
    ctTcPr.setGridSpan(oldRow.getCell(i).getCTTc().getTcPr().getGridSpan()); // sets grid span if any
   }

   XWPFRun run = cell.getParagraphs().get(0).createRun();
   run.setText("NewRow C" + i); 
  }

  doc.write(new FileOutputStream("result.docx"));
  doc.close();

  System.out.println("Done");

 }
}

result.docx看起来像:

enter image description here