使用.getSplitRenderer作为表格渲染器的iText PDF

时间:2019-08-16 17:15:42

标签: itext7

在iText PDF 7中,我正在使用Table渲染器的.layout方法来确定表是否会在整个页面上中断。

但是,当我将.getSplitRenderer(从布局结果对象返回)添加为Documents渲染器的子代时,出现以下错误:“ java.lang.IndexOutOfBoundsException”。

我正在以Java形式使用iText PDF版本7.1.7。 stacktrace中的最后三个条目是:

java.util.ArrayList$SubList.rangeCheck(ArrayList.java:1225)
java.util.ArrayList$SubList.get(ArrayList.java:1042)
com.itextpdf.layout.renderer.TableBorders.processAllBordersAndEmptyRows(TableBorders.java:139)

这是触发错误的简单代码版本:

ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
PdfWriter pdfWriter = new PdfWriter(outputStream);
PdfDoc pdfDoc = new PdfDocument(pdfWriter);
PageSize pageSize = new PageSize(612, 792);
Document doc = new Document(pdfDoc, pageSize);

Table table = new Table([50, 50, 50]);
for (int i = 0; i < 1000; i++) {
    for (int j = 0; j < 3; j++) {
        Cell cell = new Cell();
        cell.setHeight(100);
        table.addCell(cell);
    }
}

LayoutContext context = new LayoutContext(doc.getRenderer().getCurrentArea().clone());
TableRenderer tableRenderer = (TableRenderer)table.createRendererSubTree();
LayoutResult result = tableRenderer.setParent(doc.getRenderer()).layout(context);

if (result.getStatus() == result.PARTIAL) {
    tableRenderer = (TableRenderer) result.getSplitRenderer();
    doc.getRenderer().addChild(tableRenderer); // this is where the error occurs
}

1 个答案:

答案 0 :(得分:1)

将孩子添加到DocumentRenderer时,它将自动进行布局和绘制。在大多数情况下,不可能多次布局渲染器(尽管这里可以改进的是异常类型和消息)。

如果要绘制立即适合的零件,可以使用以下行:

tableRenderer.draw(new DrawContext(pdfDocument, new PdfCanvas(pdfDocument.getPage(doc.getRenderer().getCurrentArea().getPageNumber()))));

完成if表达式:

if (result.getStatus() == LayoutResult.PARTIAL) {
    tableRenderer = (TableRenderer) result.getSplitRenderer();
    tableRenderer.draw(new DrawContext(pdfDocument, new PdfCanvas(pdfDocument.getPage(doc.getRenderer().getCurrentArea().getPageNumber()))));
}

在复杂的情况下可能会有一些缺点,因此,如果您要处理复杂的布局或带标签的文档,我建议您使用二进制搜索来确定仍然适合的内容量并将该内容作为元素添加到{{1 }}实例。

这两种方法之间的一种方法是完全添加表,然后从Document中删除多余的页面。在这种情况下,请记住,您将不得不重新创建PdfDocument,因为它无法跟踪低级事件,例如从DocumentRenderer中的页面删除。