You can't achieve this by using document.add()
; instead you need to write specific rows using the writeSelectedRows()
method. See for instance the RepeatLastRows method.
In this example, I have a table with 99 rows. If I would use document.add()
to add this table to a document, it would take 3 pages, and the third page would only show 3 rows. You want this page to show 5 rows, repeating 2 rows from the previous page.
This is how it's done, assuming that we have an A4 page with a margin of 36pt. This means that the available surface measures 523 by 770 pt:
// 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);
Note that I set the total width. You'll get an exception if you use writeSelectedRows()
without specifying a width.
We initialize some parameters:
PdfContentByte canvas = writer.getDirectContent();
int currentRowStart = 0;
int currentRow = 0;
int totalRows = table.getRows().size();
We'll create a loop that continues as long as currentRow
is lower than 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;
}
In this loop, we have already filled two pages: one showing row 1 to 48, another one showing row 49 to 96. When we break out of the loop, the currentRow is 99 and the currentRowStart is 96 (this is the row index for row 97). This means that only row 97, 98 and 99 will be shown. We want to show 5 rows, so we change the value of currentRow
accordingly.
if (currentRow - currentRowStart < 5)
currentRowStart = currentRow - 5;
table.writeSelectedRows(currentRowStart, currentRow, 36, 806, canvas);
Please take a look at the resulting PDF, you'll see that the third page starts with row 95 (a row that was already shown on page 2).
Update: I misinterpreted the question in the sense that I thought that rows needed to be repeated only if there's an orphaned handful of rows on the final page. The actual requirement was to always repeat 5 rows every time the table is split.
I've slightly updated my original example. See RepeatLastRows2. You changed the value of currentRowStart
so that the start goes back 5 rows, but you forgot to update the currentRow
value. As a result, you don't subtract sufficient space from the available height.
Also make sure you don't introduce endless loops (or ArrayIndexOutOfBoundsExceptions
) by repeating the same 5 rows over and over again if only 5 rows (or less) fit a single page.