iText7大表autoLayout()

时间:2018-04-18 09:05:45

标签: autolayout itext7

根据文档

  public Table(int numColumns,
             boolean largeTable)
Constructs a Table with specified number of columns. The final column widths depend on selected table layout. Since 7.0.2 table layout algorithms were introduced. Auto layout is default, except large tables. For large table fixed layout set implicitly. Since 7.1 table will have undefined column widths, that will be determined during layout. In oder to set equal percent width as column width, use UnitValue.createPercentArray(int)

我使用https://developers.itextpdf.com/examples/tables/clone-large-tables渲染一张大表 有没有办法定义autoLayout?也许在添加第一行之后,获取单元格宽度并将它们设置在表格中,但这似乎不可能,因为列宽为空,因为我使用的是具有列数的构造函数。 或者在到达最终页面时添加某种autoLayout。 我不想定义列的宽度,因为我们有很多表。

1 个答案:

答案 0 :(得分:1)

首先,我想提一下自动布局需要整个表格的内容。在计算列宽时使用内容。但是您使用的是大表,这可能意味着您拥有大量数据并且您不希望将所有内容保留在内存中(如果不是这样,则不要使用大型表)。

因此,您所能做的就是计算给定一些初始单元格的自动列宽的近似值。基本上,可以实现您的第一个想法,但是,它需要编写一些代码。但是如果你在不同行的单元格中有非常不同的内容(例如图像与内部表格对比某些文本),那么这种方法可能效果不好,因为正如我所说,要估计列宽,你需要所有的内容。

还请记住,这种方法非常脏,可能不适用于某些极端情况。但它确实解决了目标,并使您无需定义列宽。

为了用几个词来描述解决方案,我们获取几个初始行的单元格,将它们添加到临时表并对其进行布局(估计位置等),而不实际将其绘制到任何地方。然后我们从布局步骤信息中提取单元格宽度,并将它们用于大型表构造函数。

估算列宽的方法如下所示:

private UnitValue[] estimateWidths(Document document, Cell[][] cells) {
    int numOfColumns = cells[0].length;
    Table table = new Table(numOfColumns);
    for (int i = 0; i < cells.length; i++) {
        for (int j = 0; j < cells[i].length; j++) {
            table.addCell(cells[i][j]);
        }
    }
    LayoutContext context = new LayoutContext(document.getRenderer().getCurrentArea().clone());
    TableRenderer tableRenderer = (TableRenderer)table.createRendererSubTree();
    LayoutResult result = tableRenderer.setParent(document.getRenderer()).layout(context);
    if (result.getStatus() == LayoutResult.PARTIAL) {
        tableRenderer = (TableRenderer) result.getSplitRenderer();
    }
    UnitValue[] widths = new UnitValue[numOfColumns];
    List<IRenderer> subList = tableRenderer.getChildRenderers().subList(0, numOfColumns);
    for (int i = 0; i < subList.size(); i++) {
        IRenderer cell = subList.get(i);
        widths[i] = UnitValue.createPointValue(cell.getOccupiedArea().getBBox().getWidth());
    }
    return widths;
}

假设你有一个Cell[][] cells个单元格的数组用于初始的几行(也可以是一行,但越多越好),其中cells[i][j]指的是行{{}的单元格1}}和列i,您可以像这样创建大表:

j

但是在添加新内容之前,不要忘记将Table table = new Table(estimateWidths(doc, cells), true); 数组中的单元格显式添加到大表中。