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

时间:2013-11-18 10:51:02

标签: java ms-word apache-poi openoffice-writer xwpf

我正在用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会以不同的方式将我设置的值解释为列宽。虽然MS Word显然假设20个点为单位,但开放式办公室似乎使用了点,因此当我在OO中打开生成的文档时,所有列的宽度都要宽20倍。

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

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

5 个答案:

答案 0 :(得分:10)

从问题中提取的答案:

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

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

因此,在创建表之后,我做了如下:

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

答案 1 :(得分:7)

请勿触摸单个细胞。 添加GRID:

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));
}

答案 2 :(得分:2)

创建表格后,布局设置为" auto"默认情况下,单元格的宽度将始终增加,以跟随字符串的长度。根据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英寸的二十分之一。

答案 3 :(得分: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));
}

答案 4 :(得分: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);