12

我正在用 apache-poi 生成一个 docx 文件。在 wordfile 中,我添加了表格,其列的宽度我希望看到固定。

目前,我使用这里描述的技术: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 中完美打开,但 open office 会以不同方式解释我设置为 columnwidth 的值。虽然 MS Word 显然假设 20 个点为单位,但开放式办公室似乎使用点,因此当我在 OO 中打开生成的文档时,所有列的宽度都是 20 倍。

通常当我在生成的输出中看到一些奇怪的东西时,我会解压缩 docx 文件,查看值应该是什么并更改我的代码。但是open office好像不能保存到docx,所以不能改OO里面的值保存回去看看Word是否还能正确解释文档,以便找到跨应用的解决方案。

知道如何设置表格列的宽度,以便 OO 和 MS Wordt 对它的解释相同吗?

4

5 回答 5

11

从问题中提取的答案:

最近有人向我指出,LibreOffice 能够保存到 docx。通过更改生成的文件并将其保存回来并反编译结果,我已经能够解决问题。

关键是首先为表格本身设置一个明确的宽度。Word 似乎并不关心它的存在,OpenOffice/LibreOffice 能够正确呈现表格。

因此,在创建表后,我执行了以下操作:

CTTblWidth width = table.getCTTbl().addNewTblPr().addNewTblW();
width.setType(STTblWidth.DXA);
width.setW(BigInteger.valueOf(9072));
于 2015-03-02T23:15:08.407 回答
10

不要触摸单个细胞。添加网格:

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));
}
于 2016-03-03T06:34:29.087 回答
2

创建表格后,布局默认设置为“自动”,因此单元格的宽度将始终随着字符串的长度而增加。根据 OpenXML 标记,看起来 w:tblPr w:tblLayout w:type="auto"
解决方案是将布局设置为固定并设置单个列的长度 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 英寸为单位。

于 2016-12-21T08:40:45.897 回答
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));
}
于 2017-06-20T10:02:31.883 回答
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);
于 2019-04-27T19:36:05.177 回答