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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20045921/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 22:39:24  来源:igfitidea点击:

Set columnwidth of a table in XWPFTableCell (docx)

javams-wordapache-poiopenoffice-writerxwpf

提问by Yves V.

I'm generating a docx file with apache-poi. In the wordfile, I add tables, whose columns have a width I would like to see fixed.

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

Currently, I use the technique described here: http://apache-poi.1045710.n5.nabble.com/Is-there-a-way-to-set-the-width-of-a-column-in-XWPFTableCell-td5711491.html

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

Basically, this entails setting

基本上,这需要设置

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

on each cell of that column.

在该列的每个单元格上。

The problem is that while the file opens perfectly in MS Word, open office interprets the values I set to the columnwidth differently. Whereas MS Word apparantly assumes 20-th of a point as units, open office seems to use points instead and therefore all columns are 20 times wider when I open the generated document in OO.

问题是,虽然文件在 MS Word 中完美打开,但 open office 会以不同的方式解释我为列宽设置的值。虽然 MS Word 显然假定点的 20 为单位,但开放式办公室似乎使用点来代替,因此当我在 OO 中打开生成的文档时,所有列的宽度都是 20 倍。

Usually when I see something weird in the generated output, I unpack the docx file, see what the value should be and change my code. But open office does not seem to be able to save to docx, so I can't change the value in OO save it back and see if Word still interprets the document correctly in order to find a cross-application solution.

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

Any idea how I set the width of the table column so that both OO and MS Wordt interprets it the same?

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

回答by Deduplicator

Answer extracted from question:

从问题中提取的答案:

It was recently pointed out to me that LibreOffice is able to save to docx. By changing the generated file and saving it back and decompiling the result, I have been able to resolve the issue.

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

Key is to put an explicit width to the table itself first. Word doesn't seem to care about its presence, and OpenOffice/LibreOffice are able to render the table correctly.

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

So, after creation of the table, I did as follows:

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

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

回答by nEraquasAr

Don't touch single cells. Add a 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");

The grid sets widths for entire columns. You don't need to do any cycles to set a width for every cell. It works in LibreOffice and GoogleDocs.

网格设置整个列的宽度。您不需要执行任何循环来为每个单元格设置宽度。它适用于 LibreOffice 和 GoogleDocs。

To watch the seted width in MS Word too, you may set widths of cells in the first row:

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

回答by sassyshin

Upon creation of the table, the layout is set to "auto" by default hence the width of the cell will always increase to follow the length of the string. As per OpenXML markup, it look's like w:tblPr w:tblLayout w:type="auto"
the solution is to set the layout to fixedand set the individual column length w:tblPr w:tblLayout w:type="fixed"

创建表格后,布局默认设置为“自动”,因此单元格的宽度将始终增加以跟随字符串的长度。根据 OpenXML 标记,看起来 w:tblPr w:tblLayout w:type="auto"
解决方案是将布局设置为固定并设置单个列长度 w:tblPr w:tblLayout w:type="fixed"

Here's the poi code for setting table layout:

这是用于设置表格布局的 poi 代码:

XWPFTable table = document.createTable();
CTTblLayoutType type = table.getCTTbl().getTblPr().addNewTblLayout();
type.setType(STTblLayoutType.FIXED);

Here's how to set the individual width:

以下是设置单个宽度的方法:

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

column lengths are in twentieths of a point (dxa) or 1/1440 inch.

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

回答by Rahul khanvani

This is a major and very tricky element. I solved it using this own generic method of setting the widths of a table cell.

这是一个主要且非常棘手的元素。我使用这种自己的设置表格单元格宽度的通用方法解决了这个问题。

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

回答by mnesarco

Based on other answers...

根据其他答案...

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

Usage:

用法:

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