在XWPFTableCell中设置表格的列宽(docx)

15

我正在使用apache-poi生成一个docx文件。在文档中,我添加了表格,其中的列有一个宽度,我希望能够固定。

目前,我使用这里描述的技术:http://apache-poi.1045710.n5.nabble.com/Is-there-a-way-to-set-the-width-of-a-column-in-XWPFTableCell-td5711491.html

基本上,这意味着设置

cell.getCTTc().addNewTcPr().addNewTcW().setW(BigInteger.valueOf(cols[j])); 

对于该列的每个单元格进行操作。

问题在于,虽然该文件在MS Word中打开完美无缺,但是OpenOffice会以不同的方式解释我设置给列宽度的值。尽管MS Word显然假定20分之一点为单位,OpenOffice似乎使用点而不是分,因此当我在OO中打开生成的文档时,所有列的宽度都增加了20倍。

通常,当我在生成的输出中看到奇怪的东西时,我会解压缩docx文件,查看值应该是什么,并更改我的代码。但是OpenOffice似乎无法保存为docx,因此我无法在OO中更改值并将其保存回来,以查看Word是否仍然正确解释文档,以找到跨应用程序的解决方案。

有没有办法设置表列的宽度,使得OO和MS Word都可以以相同的方式解释它?

5个回答

16

不要触碰单个单元格。 添加网格:

XWPFDocument doc = new XWPFDocument();
XWPFTable table = doc.createTable(1,2);
table.getCTTbl().addNewTblGrid().addNewGridCol().setW(BigInteger.valueOf(6000));
table.getCTTbl().getTblGrid().addNewGridCol().setW(BigInteger.valueOf(2000));
table.getRow(0).getCell(0).setText("1A");
table.getRow(0).getCell(1).setText("1B");
XWPFTableRow newrow = table.createRow();
newrow.getCell(0).setText("2A");
newrow.getCell(1).setText("2B");

网格设置整列的宽度,您不需要为每个单元格设置宽度进行任何循环操作。 它在LibreOffice和GoogleDocs中都可以使用。

要在MS Word中查看设置的宽度,您可以在第一行中设置单元格的宽度:

 widthCellsAcrossRow(table, 0, 0, 4000);
 widthCellsAcrossRow(table, 0, 0, 5000);

private static void widthCellsAcrossRow (XWPFTable table, int rowNum, int colNum, int width) {
        XWPFTableCell cell = table.getRow(rowNum).getCell(colNum);
        if (cell.getCTTc().getTcPr() == null)
            cell.getCTTc().addNewTcPr();
        if (cell.getCTTc().getTcPr().getTcW()==null)
            cell.getCTTc().getTcPr().addNewTcW();
        cell.getCTTc().getTcPr().getTcW().setW(BigInteger.valueOf((long) width));
}

如果你将表格布局设置为"fixed",这个功能就能正常工作——请参考上面的注释。 - undefined

11

问题答案摘录:

最近有人指出LibreOffice可以保存为docx格式。通过修改生成的文件并将其保存回来,以及对结果进行反编译,我已经能够解决这个问题。

关键是首先对表格本身设置明确的宽度。Word似乎不在意其存在,并且OpenOffice/LibreOffice能够正确地呈现表格。

因此,在创建表格后,我按照以下方式进行操作:

CTTblWidth width = table.getCTTbl().addNewTblPr().addNewTblW();
width.setType(STTblWidth.DXA);
width.setW(BigInteger.valueOf(9072));

6
在创建表格时,默认情况下布局设置为“auto”,因此单元格的宽度将始终增加以跟随字符串的长度。根据OpenXML标记,它看起来像是这样:
w:tblPr w:tblLayout w:type="auto"
解决方法是将布局设置为fixed并设置各个列的长度
w:tblPr w:tblLayout w:type="fixed" 以下是设置表格布局的poi代码:
XWPFTable table = document.createTable();
CTTblLayoutType type = table.getCTTbl().getTblPr().addNewTblLayout();
type.setType(STTblLayoutType.FIXED);

以下是如何设置单独的宽度:

以下是如何设置单独的宽度:

 int[] cols = {
    4896,
    1872,
    4032,
    1728,
    1440
};

for (int i = 0; i < table.getNumberOfRows(); i++) {
    XWPFTableRow row = table.getRow(i);
    int numCells = row.getTableCells().size();
    for (int j = 0; j < numCells; j++) {
        XWPFTableCell cell = row.getCell(j);
        CTTblWidth cellWidth = cell.getCTTc().addNewTcPr().addNewTcW();
        CTTcPr pr = cell.getCTTc().addNewTcPr();
        pr.addNewNoWrap();
        cellWidth.setW(BigInteger.valueOf(cols[j]));
    }
}

列长以点(dxa)的二十分之一或1/1440英寸为单位。


那就是关键!将表格布局设置为固定。谢谢。我已经做了一切...为表格设置了网格布局,正确设置了单元格大小...但是没有设置表格布局。 现在对我来说可以工作了。 - undefined

0

这是一个非常重要且棘手的元素。我使用自己通用的方法来设置表格单元格的宽度来解决它。

private static void setTableColumnWidths(XWPFTable table) {
    table.getCTTbl().addNewTblGrid().addNewGridCol().setW(BigInteger.valueOf(2000));
    table.getCTTbl().getTblGrid().addNewGridCol().setW(BigInteger.valueOf(3200));
    table.getCTTbl().getTblGrid().addNewGridCol().setW(BigInteger.valueOf(1000));
    table.getCTTbl().getTblGrid().addNewGridCol().setW(BigInteger.valueOf(1000));
    table.getCTTbl().getTblGrid().addNewGridCol().setW(BigInteger.valueOf(1105));
    table.getCTTbl().getTblGrid().addNewGridCol().setW(BigInteger.valueOf(1105));
}

3
嘿,Rahul。请不要乞求“请点赞”之类的东西。如果您发布好的答案(这个不好),则会自动获得声望,但请不要一直乞求。 - Alexander
亚历山大(这个不好)。好的,我会采纳你的建议,但请不要插手。这是分享知识的地方,而不是争论的场所。 - Rahul khanvani
我不会称这个方法为“通用”的。:P 它几乎是尽可能_ad hoc_的。 - Priidu Neemre

0

根据其他答案...

  public static void setTableColumnsWidth(XWPFTable table, long... widths) {
    CTTblGrid grid = table.getCTTbl().addNewTblGrid();
    for (long w : widths) {
      grid.addNewGridCol().setW(BigInteger.valueOf(w));
    }    
  }

使用方法:

setTableColumnsWidth(table, 1440, 2700, 3000, 1440);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接