I have group of tables with dynamic rows. There are some scenarios where a table is splitted between pages. In some scenarios, only the last row is split into next page. Suppose if a table has 10 rows, the rows 1 thru 9 are displayed in page 1 and row 10 is displayed in page 2.
I am looking for a solution to have a page break (document.newpage()) to happen to move the entire table to next page in this scenario. I tried below code and it was working for some scenarios but not for all. I would like to find out when a table last row is going to split so I can add page break to move the complete table to next page to avoid last row orphan.
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);
}
}
I tried Johannes' solution, but it did not work, I don't know why. Anyways, I found an own solution. I tested it with some random scenarios and it worked. The solution I found is to put the code below before adding the table to the document with
document.add(table)
.Here's the complete working example as explained here... I used iText 2.1.7.
And the output it produces is here. Isn't that what you expected to achieve?
Yeah, it works as following:
At the beginning of your loop
for (int k = 1; ...
you have to add:and at it's end, you replace the
document.add(table);
with:And this is it... :-)
You should then remove your debug outputs and you can remove the "continued" header thing and its corresponding
table.setSkipFirstHeader(true);
. It's enough that you havetable.setHeaderRows(1);
.To be a bit lazier, since your original table has only one column as well, you can create your
outerTable
withPdfPTable outerTable = new PdfPTable(table);
after you initialized yourtable
with its width and spacings. But you have to create it before you add your content to yourtable
.