如何使用 iText7 同时呈现两个表格(表格的内容超过单页)

How to render two tables simultaneously (tables are having content more than single page) using iText7

我需要在从第 1 页开始的 2 个平行栏中添加 2 个 table,并且两个 table 的内容都超过一页。 Table1 在页面的左半部分运行,table2 在右半部分运行。我开始渲染 table 1 并且它溢出了。现在,在继续下一页之前,我想开始渲染 table 2(添加新页面会使上一页无法访问)。 iText5 中的实现是使用 CoulmnText 完成的。在 iText5 中,我使用 'ColumnText.hasMoreText(status)' 来检查 table 的溢出性质。 但在 iText7 中,这种方法有所不同。这是我试图解决所述问题的 iText7 中的示例代码。

public void createPdf(String dest) throws FileNotFoundException {
    Rectangle[] columnsEven = {new Rectangle(200, 100, 100, 500), new Rectangle(500, 100, 100, 500)};

    PdfWriter writer =new PdfWriter(DEST);
    PdfDocument pdfDoc = new PdfDocument(writer);
    Document document = new Document(pdfDoc);

    Table table1 = new Table(2);
    Table table2 = new Table(2);

    String cellContent1="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam metus elit, ornare et justo nec, ornare dignissim leo. Praesent in egestas erat. Donec id nunc libero. Nullam aliquam sodales sollicitudin. Proin ac egestas nunc. Nunc et suscipit augue. Curabitur porta tempor nunc vel suscipit. Suspendisse imperdiet nunc id quam aliquet fermentum. Pellentesque ut dolor non odio congue blandit. Morbi laoreet magna quam, quis suscipit nunc pulvinar et. Nullam sit amet semper odio, sagittis dictum erat.\n"+

        "Curabitur sagittis arcu turpis, et tincidunt quam congue in. Nullam vitae felis id dui fringilla tincidunt. Nulla ullamcorper nisi non arcu fermentum, eu tempor lectus mattis. Aliquam leo purus, vulputate et ornare in, tincidunt sit amet mi. Sed sollicitudin et sapien vel hendrerit. Morbi id sodales sapien. In non nisl velit. Mauris maximus sodales lectus, ac dignissim elit cursus ac. Nulla viverra, velit sed cursus tincidunt, ex risus posuere diam, lobortis congue metus eros at lorem. Cras a ligula tortor. Vestibulum efficitur diam eros, eget dapibus magna cursus sed.\n"+
        "Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aliquam ut velit pretium diam vestibulum consectetur. Praesent dignissim id sapien eget ultrices. Nam non libero iaculis dolor mattis egestas et quis leo. Sed vitae libero a enim viverra finibus sit amet sed nulla. Sed vitae sem hendrerit, posuere justo sagittis, placerat justo. Aenean felis nisi, tincidunt faucibus sem at, egestas interdum nibh. Curabitur venenatis neque nec volutpat mollis. Phasellus vel tellus ut nisl consequat gravida. Maecenas eget ligula vestibulum, finibus turpis a, hendrerit est. Cras eleifend mollis commodo.\n"+

        "Morbi quam velit, elementum nec turpis porttitor, venenatis sagittis nunc. Sed et nisi ipsum. Maecenas eget tellus in dui condimentum dictum a tempus sem. Maecenas consectetur nisl sit amet accumsan volutpat. Sed dictum massa vitae urna aliquam imperdiet. Nam at ex feugiat dolor vestibulum vehicula. Nullam leo magna, porta ac ex vitae, malesuada fermentum turpis. Donec vel turpis quis ligula feugiat molestie quis at nisi. Quisque efficitur velit odio, id rhoncus diam varius eu. Duis dui mi, scelerisque at faucibus ac, sodales sed est. Sed dictum aliquet semper.\n"+


        "Sed erat ipsum, vehicula nec magna sed, aliquam volutpat lorem. Integer et auctor nisl, at auctor lorem. Nam bibendum urna nec quam cursus, vitae rhoncus justo semper. Morbi posuere dapibus quam vel euismod. Morbi id maximus augue, ut vulputate turpis. Cras posuere auctor justo, in ultricies nunc tincidunt id. Sed luctus nisl lacus, in facilisis erat ultricies id. Aliquam erat volutpat. Morbi accumsan lectus nec dolor ultricies dignissim. Sed quis finibus lectus.\n"+

                "Pellentesque aliquet ex eget cursus accumsan. In ultrices tempus orci sed ultrices. Maecenas lectus nunc, consectetur ac suscipit et, tempus rutrum ipsum. Nulla accumsan tincidunt dignissim. Sed malesuada sapien elit, ac semper urna maximus at. Nunc eleifend tortor nec ligula auctor, sit amet sagittis turpis sagittis. Nam laoreet justo sed gravida iaculis. Fusce ornare quam quis arcu gravida rutrum. Aliquam vitae augue sit amet nisi finibus ullamcorper. Proin quis placerat velit. Integer malesuada erat nec massa tempus pretium.";

    Cell cell = new Cell().add(new Paragraph("INDIA"));
    table1.addCell(cell);   
    table2.addCell(cell);
    cell = new Cell().add(new Paragraph(cellContent1));
    table1.addCell(cell);
    table2.addCell(cell);
    drawTables(pdfDoc, document, new Table[] {table1, table2}, columnsEven);
    document.close();

}

public void drawTables(PdfDocument pdfDoc, Document document, Table[] tables , Rectangle[] rects) {
    // for table 1
    DocumentRenderer renderer1= new MyColumnDocumentRenderer(document, new Rectangle[] {rects[0]});
    document.add(table1);
    // for table 2
    DocumentRenderer renderer2= new MyColumnDocumentRenderer(document, new Rectangle[] {rects[1]});
    document.add(table2);

}
public class MyColumnDocumentRenderer extends DocumentRenderer {
    protected Rectangle column;

    public MyColumnDocumentRenderer(Document document, Rectangle[] column) {
        super(document);
        this.column = column[0];        
    }

    @Override
    protected LayoutArea updateCurrentArea(LayoutResult overflowResult) {
        if(overflowResult!=null && overflowResult.getStatus()== LayoutResult.PARTIAL) {

            column = new Rectangle(300, 100, 200, 600);
        }
        super.updateCurrentArea(overflowResult);


        return (currentArea = new RootLayoutArea(currentPageNumber, column.clone()));
    }

我正在将 iText5 迁移到 iText7。你能建议我实现所述问题的最佳方法吗?

对于以下问题,我也需要一些帮助。 是否可以同时处理 document.add(table1) 和 document.add(table2)?我们可以在渲染另一个 table 时保存一个 table 的文档渲染器状态吗?

你总是可以在许多过程中这样做:以戳记模式打开文档(使用PdfReaderPdfWriter),添加必要的内容,关闭文档,然后打开新版本的文档、添加更多内容、关闭文档等。

开箱即用的实现不支持跨多个页面同时布局多个对象的情况。然而,整个布局框架足够灵活,所以如果你深入研究源代码,你可以从现有的实现中扩展,只需稍微修改它们就可以实现你的情况。

我们将从 ColumnDocumentRenderer 扩展到可以访问某些 protected 字段,并增加返回渲染器第一页的可能性。请注意,为了使此解决方案起作用,我们需要将 immediateFlush=false 传递给父级的构造函数,这会稍微增加内存占用。 另请注意,该解决方案在一定程度上取决于实施细节,因此即使在补丁升级期间它也可能停止工作。不过这更多是理论上的可能性,大家多多关注吧。

private static final class ResettingColumnDocumentRenderer extends ColumnDocumentRenderer {
    public ResettingColumnDocumentRenderer(Document document, Rectangle[] columns) {
        super(document, false, columns);
    }

    public void resetToFirstPage() {
        currentArea = null;
        currentPageNumber = 0;
        nextAreaNumber = 0;
    }
}

现在我们有了自定义文档呈现器实现,我们可以概括您的 drawTables 方法以支持呈现 N 个表的情况:

public void drawTables(Document document, Table[] tables , Rectangle[] rects) {
    for (int i = 0; i < tables.length; i++) {
        ResettingColumnDocumentRenderer renderer = new ResettingColumnDocumentRenderer(document, new Rectangle[] {rects[i]});
        document.setRenderer(renderer);
        document.add(tables[i]);
        renderer.resetToFirstPage();
        renderer.flush();
    }
}

最后,这是外部调用代码,与您的原始版本相比几乎没有任何修改:

public void createPdf() throws FileNotFoundException {
    Rectangle[] columnsEven = {new Rectangle(70, 100, 200, 500), new Rectangle(350, 100, 200, 500)};

    PdfWriter writer =new PdfWriter("C:/Users/Alexey/Desktop/23423423.pdf");
    PdfDocument pdfDoc = new PdfDocument(writer);
    Document document = new Document(pdfDoc);

    Table table1 = new Table(2);
    Table table2 = new Table(2);

    String cellContent1="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam metus elit, ornare et justo nec, ornare dignissim leo. Praesent in egestas erat. Donec id nunc libero. Nullam aliquam sodales sollicitudin. Proin ac egestas nunc. Nunc et suscipit augue. Curabitur porta tempor nunc vel suscipit. Suspendisse imperdiet nunc id quam aliquet fermentum. Pellentesque ut dolor non odio congue blandit. Morbi laoreet magna quam, quis suscipit nunc pulvinar et. Nullam sit amet semper odio, sagittis dictum erat.\n"+

            "Curabitur sagittis arcu turpis, et tincidunt quam congue in. Nullam vitae felis id dui fringilla tincidunt. Nulla ullamcorper nisi non arcu fermentum, eu tempor lectus mattis. Aliquam leo purus, vulputate et ornare in, tincidunt sit amet mi. Sed sollicitudin et sapien vel hendrerit. Morbi id sodales sapien. In non nisl velit. Mauris maximus sodales lectus, ac dignissim elit cursus ac. Nulla viverra, velit sed cursus tincidunt, ex risus posuere diam, lobortis congue metus eros at lorem. Cras a ligula tortor. Vestibulum efficitur diam eros, eget dapibus magna cursus sed.\n"+
            "Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aliquam ut velit pretium diam vestibulum consectetur. Praesent dignissim id sapien eget ultrices. Nam non libero iaculis dolor mattis egestas et quis leo. Sed vitae libero a enim viverra finibus sit amet sed nulla. Sed vitae sem hendrerit, posuere justo sagittis, placerat justo. Aenean felis nisi, tincidunt faucibus sem at, egestas interdum nibh. Curabitur venenatis neque nec volutpat mollis. Phasellus vel tellus ut nisl consequat gravida. Maecenas eget ligula vestibulum, finibus turpis a, hendrerit est. Cras eleifend mollis commodo.\n"+

            "Morbi quam velit, elementum nec turpis porttitor, venenatis sagittis nunc. Sed et nisi ipsum. Maecenas eget tellus in dui condimentum dictum a tempus sem. Maecenas consectetur nisl sit amet accumsan volutpat. Sed dictum massa vitae urna aliquam imperdiet. Nam at ex feugiat dolor vestibulum vehicula. Nullam leo magna, porta ac ex vitae, malesuada fermentum turpis. Donec vel turpis quis ligula feugiat molestie quis at nisi. Quisque efficitur velit odio, id rhoncus diam varius eu. Duis dui mi, scelerisque at faucibus ac, sodales sed est. Sed dictum aliquet semper.\n"+


            "Sed erat ipsum, vehicula nec magna sed, aliquam volutpat lorem. Integer et auctor nisl, at auctor lorem. Nam bibendum urna nec quam cursus, vitae rhoncus justo semper. Morbi posuere dapibus quam vel euismod. Morbi id maximus augue, ut vulputate turpis. Cras posuere auctor justo, in ultricies nunc tincidunt id. Sed luctus nisl lacus, in facilisis erat ultricies id. Aliquam erat volutpat. Morbi accumsan lectus nec dolor ultricies dignissim. Sed quis finibus lectus.\n"+

            "Pellentesque aliquet ex eget cursus accumsan. In ultrices tempus orci sed ultrices. Maecenas lectus nunc, consectetur ac suscipit et, tempus rutrum ipsum. Nulla accumsan tincidunt dignissim. Sed malesuada sapien elit, ac semper urna maximus at. Nunc eleifend tortor nec ligula auctor, sit amet sagittis turpis sagittis. Nam laoreet justo sed gravida iaculis. Fusce ornare quam quis arcu gravida rutrum. Aliquam vitae augue sit amet nisi finibus ullamcorper. Proin quis placerat velit. Integer malesuada erat nec massa tempus pretium.";

    Cell cell = new Cell().add(new Paragraph("INDIA"));
    table1.addCell(cell);
    table2.addCell(cell);
    cell = new Cell().add(new Paragraph(cellContent1));
    table1.addCell(cell);
    table2.addCell(cell);
    drawTables(document, new Table[] {table1, table2}, columnsEven);
    document.close();

}