有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java iText如何查找最后一行被拆分到下一页

我有一组具有动态行的表。在某些情况下,表在页面之间被拆分。在某些情况下,只有最后一行被拆分为下一页。假设一个表有10行,第1页显示第1行到第9行,第2页显示第10行

我正在寻找一种解决方案,使分页符(document.newpage())能够在这种情况下将整个表移动到下一页。我尝试了下面的代码,它适用于某些场景,但不适用于所有场景。我想知道何时拆分表的最后一行,这样我就可以添加分页符,将整个表移动到下一页,以避免最后一行孤立

public class SplitItextLastRow {

final static private String BODY_FONT = FontFactory.getFont("Arial").getFamilyname();

public static void main(String[] args) {
    try {
        Document document = new Document();
        document.setPageSize(PageSize.LETTER);
        document.setMargins(16, 14, 14, 14);
        PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("C:/SplitItext.pdf"));
        document.open();
        document.setPageSize(PageSize.LETTER);
        document.setMargins(16, 14, 14, 14);

        int[] maxCountRows = new int[] { 3, 9, 2, 3, 7, 9, 2, 4, 5, 4, 9, 7, 6, 5, 4, 6, 8, 3 };

        for (int k = 1; k <= maxCountRows.length; k++) {

            PdfPTable table = new PdfPTable(1);
            table.setSpacingAfter(0);
            table.setSpacingBefore(0);
            table.setTotalWidth(document.right() - document.left());
            table.setLockedWidth(true);

            table.setHeaderRows(1);
            table.setSkipFirstHeader(true);
            addHeader(table, "Header Row continued " + k, BaseColor.LIGHT_GRAY);
            addHeader(table, "Header Row normal " + k, BaseColor.LIGHT_GRAY);

            for (int i = 1; i < maxCountRows[k - 1]; i++) {
                StringBuilder sb = new StringBuilder();
                for (int p = 0; p < maxCountRows[k - 1] * 6; p++) {
                    sb.append("Text Row ");
                }
                add(table, sb.toString() + i, BaseColor.WHITE);
            }

            float verticalPosition = writer.getVerticalPosition(true);
            System.out.println("------Table " + k);
            if ((verticalPosition - table.getTotalHeight()) <= document.bottom()) {
                System.out.println("........................................Last Row splitted");
            }

            document.add(table);
        }

        document.close();
    } catch (Exception de) {
        de.printStackTrace();
    }

}

private static void addHeader(PdfPTable table, String text, BaseColor color) {
    PdfPCell pdfCellHeader = new PdfPCell();
    pdfCellHeader.setBackgroundColor(color);
    pdfCellHeader.addElement(new Paragraph(new Phrase(text, FontFactory.getFont(BODY_FONT, 8f, BaseColor.BLUE))));
    table.addCell(pdfCellHeader);
}

private static void add(PdfPTable table, String text, BaseColor color) {
    PdfPCell pdfCellHeader = new PdfPCell();
    pdfCellHeader.setBackgroundColor(color);
    pdfCellHeader.addElement(new Paragraph(new Phrase(text, FontFactory.getFont(BODY_FONT, 5f, BaseColor.GREEN))));
    table.addCell(pdfCellHeader);
}

}


共 (3) 个答案

  1. # 1 楼答案

    下面是完整的工作示例,如所解释的here。。。我使用了iText2.1.7

    import java.awt.Color;
    import java.io.FileOutputStream;
    
    import com.lowagie.text.Document;
    import com.lowagie.text.FontFactory;
    import com.lowagie.text.PageSize;
    import com.lowagie.text.Paragraph;
    import com.lowagie.text.Phrase;
    import com.lowagie.text.pdf.PdfPCell;
    import com.lowagie.text.pdf.PdfPTable;
    import com.lowagie.text.pdf.PdfWriter;
    
    public class SplitItextLastRow
    {
        final static private String BODY_FONT = FontFactory.getFont("Arial").getFamilyname();
    
        public static void main(final String[] args)
        {
            try
            {
                Document document = new Document();
                document.setPageSize(PageSize.LETTER);
                document.setMargins(16, 14, 14, 14);
                PdfWriter writer =
                        PdfWriter.getInstance(document, new FileOutputStream("SplitItext.pdf"));
                document.open();
                document.setPageSize(PageSize.LETTER);
                document.setMargins(16, 14, 14, 14);
    
                int[] maxCountRows = new int[]
                {
                        3, 9, 2, 3, 7, 9, 2, 4, 5, 4, 9, 7, 6, 5, 4, 6, 8, 3
                };
    
                for (int k = 1; k <= maxCountRows.length; k++)
                {
                    PdfPTable table = new PdfPTable(1);
                    table.setSpacingAfter(0);
                    table.setSpacingBefore(0);
                    table.setTotalWidth(document.right() - document.left());
                    table.setLockedWidth(true);
    
                    PdfPTable outerTable = new PdfPTable(table);
    
                    table.setHeaderRows(1);
                    table.setSkipFirstHeader(true);
                    addHeader(table, "Header Row continued " + k, Color.LIGHT_GRAY);
                    addHeader(table, "Header Row normal " + k, Color.LIGHT_GRAY);
    
                    for (int i = 1; i < maxCountRows[k - 1]; i++)
                    {
                        StringBuilder sb = new StringBuilder();
                        for (int p = 0; p < (maxCountRows[k - 1] * 6); p++)
                        {
                            sb.append("Text Row ");
                        }
                        add(table, sb.toString() + i, Color.WHITE);
                    }
    
                    float verticalPosition = writer.getVerticalPosition(true);
                    System.out.println("   Table " + k);
                    if ((verticalPosition - table.getTotalHeight()) <= document.bottom())
                    {
                        System.out.println("........................................Last Row splitted");
                    }
    
                    outerTable.addCell(new PdfPCell(table));
                    document.add(outerTable);
                }
    
                document.close();
            }
            catch (Exception de)
            {
                de.printStackTrace();
            }
        }
    
        private static void addHeader(final PdfPTable table, final String text, final Color color)
        {
            PdfPCell pdfCellHeader = new PdfPCell();
            pdfCellHeader.setBackgroundColor(color);
            pdfCellHeader.addElement(new Paragraph(new Phrase(text, FontFactory.getFont(BODY_FONT, 8f,
                    Color.BLUE))));
            table.addCell(pdfCellHeader);
        }
    
        private static void add(final PdfPTable table, final String text, final Color color)
        {
            PdfPCell pdfCellHeader = new PdfPCell();
            pdfCellHeader.setBackgroundColor(color);
            pdfCellHeader.addElement(new Paragraph(new Phrase(text, FontFactory.getFont(BODY_FONT, 5f,
                    Color.GREEN))));
            table.addCell(pdfCellHeader);
        }
    }
    

    它产生的输出是here。这不是你所期望的吗

  2. # 2 楼答案

    是的,它的工作原理如下:

    在循环开始时for (int k = 1; ...必须添加:

    PdfPTable outerTable = new PdfPTable(1);
    outerTable.setSpacingAfter(0);
    outerTable.setSpacingBefore(0);
    outerTable.setTotalWidth(document.right() - document.left());
    outerTable.setLockedWidth(true);
    

    最后,将document.add(table);替换为:

    outerTable.addCell(new PdfPCell(table));
    document.add(outerTable);
    

    就是这样…:-)
    然后,您应该删除调试输出,您可以删除“continued”头内容及其相应的table.setSkipFirstHeader(true);。你有table.setHeaderRows(1);就足够了

    更懒一点,因为您的原始表也只有一列,所以您可以在使用宽度和间距初始化table之后,使用PdfPTable outerTable = new PdfPTable(table);创建outerTable。但在将内容添加到table之前,必须先创建它

  3. # 3 楼答案

    我尝试了约翰的解决方案,但没有成功,我不知道为什么。无论如何,我找到了自己的解决办法。我用一些随机的场景进行了测试,结果成功了。我找到的解决方案是在使用document.add(table)将表添加到文档之前,将代码放在下面

    int headerRowsCount = table.getHeaderRows();
    float headerRowsHeight = 0f;
    for (int j = 0; j < headerRowsCount; j++) {
        headerRowsHeight += table.getRowHeight(j);
    }
    float totalTableHeight = table.getTotalHeight() - headerRowsHeight;
    float lastRowHeight = table.getRowHeight(table.getRows().size() - 1);
    float tableHeightExceptLastRow = totalTableHeight - lastRowHeight + document.bottom();
    float tableGap = verticalPosition - tableHeightExceptLastRow;
    boolean lastRowSplit = (tableGap > -35 && (tableGap < lastRowHeight) && tableHeightExceptLastRow > 0);
    if (lastRowSplit) {
        document.newPage();
    }