我一直在寻找答案,但是找不到很好的教程。我正在使用Java itext生成pdf。我有一张桌子,上面打印了50多行,约占2页。在继续打印列表之前,我需要将上一页的最后5行打印到下一页。

Example:row 31row 32row 33row 34row 35row 36--end of page 1--row 32row 33row 34row 35row 36row 37

关于如何执行此操作的任何想法?

Currently it prints like this:row 35row 36--end of page 1--row 37row 38

代码:(专注于启动循环,不要介意那些标题)

PdfPTable table = new PdfPTable(4);
table.setWidthPercentage(97);
table.setWidths(new float[] {10, 45, 25, 25});

PdfPCell c1 = new PdfPCell(new Phrase("Logo", FontFactory.getFont(FontFactory.TIMES_ROMAN, 14)));
c1.setPadding(5);
c1.setHorizontalAlignment(Element.ALIGN_LEFT);
c1.setVerticalAlignment(Element.ALIGN_CENTER);
c1.setBorder(0);
c1.setColspan(4);
table.addCell(c1);

c1 = new PdfPCell(new Phrase("09/01/2013 - 09/15/2013", FontFactory.getFont(FontFactory.TIMES_ROMAN, 12)));
c1.setPadding(5);
c1.setHorizontalAlignment(Element.ALIGN_LEFT);
c1.setVerticalAlignment(Element.ALIGN_CENTER);
c1.setBorder(0);
c1.setColspan(4);
c1.setPaddingBottom(20);
table.addCell(c1);

//start header
c1 = new PdfPCell(new Phrase(" ", FontFactory.getFont(FontFactory.TIMES_ROMAN, 12)));
c1.setPaddingBottom(5);
c1.setHorizontalAlignment(Element.ALIGN_LEFT);
c1.setBackgroundColor(WebColors.getRGBColor("#99CCFF"));
c1.setBorder(1);
table.addCell(c1);

c1 = new PdfPCell(new Phrase("Name", FontFactory.getFont(FontFactory.TIMES_ROMAN, 12)));
c1.setPaddingBottom(5);
c1.setHorizontalAlignment(Element.ALIGN_LEFT);
c1.setBackgroundColor(WebColors.getRGBColor("#99CCFF"));
c1.setBorder(1);
table.addCell(c1);

c1 = new PdfPCell(new Phrase("Number", FontFactory.getFont(FontFactory.TIMES_ROMAN, 12)));
c1.setPaddingBottom(5);
c1.setHorizontalAlignment(Element.ALIGN_LEFT);
c1.setBackgroundColor(WebColors.getRGBColor("#99CCFF"));
c1.setBorder(1);
table.addCell(c1);

c1 = new PdfPCell(new Phrase("Amount", FontFactory.getFont(FontFactory.TIMES_ROMAN, 12)));
c1.setPaddingBottom(5);
c1.setHorizontalAlignment(Element.ALIGN_RIGHT);
c1.setBackgroundColor(WebColors.getRGBColor("#99CCFF"));
c1.setBorder(1);
table.addCell(c1);
//end header

//start for loop
for(int a=0; a<50; a++)
{
    int border=0;
    if(a%5==0)
    {border=1;}

    c1 = new PdfPCell(new Phrase((a+1)+"", FontFactory.getFont(FontFactory.TIMES_ROMAN, 12)));
    c1.setHorizontalAlignment(Element.ALIGN_LEFT);
    c1.setBorder(border);
    c1.setPaddingBottom(5);
    table.addCell(c1);

    c1 = new PdfPCell(new Phrase("Last Name, First Name", FontFactory.getFont(FontFactory.TIMES_ROMAN, 12)));
    c1.setHorizontalAlignment(Element.ALIGN_LEFT);
    c1.setBorder(border);
    c1.setPaddingBottom(5);
    table.addCell(c1);

    c1 = new PdfPCell(new Phrase("1", FontFactory.getFont(FontFactory.TIMES_ROMAN, 12)));
    c1.setHorizontalAlignment(Element.ALIGN_CENTER);
    c1.setBorder(border);
    c1.setPaddingBottom(5);
    table.addCell(c1);

    c1 = new PdfPCell(new Phrase("1", FontFactory.getFont(FontFactory.TIMES_ROMAN, 12)));
    c1.setHorizontalAlignment(Element.ALIGN_RIGHT);
    c1.setBorder(border);
    c1.setPaddingBottom(5);
    table.addCell(c1);


}
//end for loop

subCatPart.add(table);

最佳答案

您不能使用document.add()来实现。相反,您需要使用writeSelectedRows()方法编写特定的行。例如,参见RepeatLastRows方法。

在此示例中,我有一个包含99行的表。如果我使用document.add()将此表添加到文档中,它将需要3页,而第三页将仅显示3行。您希望此页面显示5行,比上一页重复2行。

假设我们有一个A4页面的页边距为36pt,这就是完成的过程。这意味着可用表面的尺寸为523乘770磅:

// we create a table that spans the width of the page and that has 99 rows
PdfPTable table = new PdfPTable(1);
table.setTotalWidth(523);
for (int i = 1; i < 100; i++)
    table.addCell("row " + i);


请注意,我设置了总宽度。如果使用writeSelectedRows()而不指定宽度,则会出现异常。

我们初始化一些参数:

PdfContentByte canvas = writer.getDirectContent();
int currentRowStart = 0;
int currentRow = 0;
int totalRows = table.getRows().size();


我们将创建一个循环,只要currentRow低于totalRows,该循环就会继续:

while (true) {
    // available height of the page
    float available_height = 770;
    // how many rows fit the height?
    while (available_height > 0 && currentRow < totalRows) {
        available_height -= table.getRowHeight(currentRow++);
    }
    // we stop as soon as all the rows are counted
    if (currentRow == totalRows)
        break;
    // we draw part the rows that fit the page and start a new page
    table.writeSelectedRows(currentRowStart, --currentRow, 36, 806, canvas);
    document.newPage();
    currentRowStart = currentRow;
}


在此循环中,我们已经填充了两页:一页显示1至48行,另一页显示49至96行。当我们跳出循环时,currentRow为99,currentRowStart为96(这是该行的索引)第97行)。这意味着将仅显示第97、98和99行。我们想显示5行,因此我们相应地更改currentRow的值。

if (currentRow - currentRowStart < 5)
    currentRowStart = currentRow - 5;
table.writeSelectedRows(currentRowStart, currentRow, 36, 806, canvas);


请查看生成的PDF,您将看到第三页从第95行开始(该行已在第2页上显示)。

更新:我误以为我认为只有在最后一页上只有少数几行时才需要重复行。实际要求是每次拆分表时始终重复5行。

我已经稍微更新了我的原始示例。请参见RepeatLastRows2。您更改了currentRowStart的值,以便开始返回5行,但是您忘记了更新currentRow的值。结果,您没有从可用高度中减去足够的空间。

另外,如果只有5行(或更少)容纳单个页面,请一次又一次地重复相同的5行,以确保不会引入无限循环(或ArrayIndexOutOfBoundsExceptions)。

09-27 20:41