0

PDF with PdfPTable and PdfPCell

I have this PDF document that I made with iText in Java. The PDF Document contains data that is added via PDFPTable objects.

The 'Problem' is that when I have more data then fits on one PDF page, the data is rendered on the next page, leaving me with empty space on the first page. (See the image 'Problem' side).

I would like to have these empty spaces filled with 'PDFPCell' object, see 'Solution' (these PdfPCell object contain another PdfPTable, the data in this PdfPTable must not be 'continued' on the next page of the pdf when it does not fit).

This is a small example in code:

PdfPTable outerTable = new PdfPTable(1);
outerTable.setHorizontalAlignment(Element.ALIGN_LEFT);
outerTable.setWidthPercentage(100);

int i = 0;
while (i < 5)
{
    i++;
    PdfPTable innerTable = new PdfPTable(new float[] {0.25f, 0.25f, 0.25f, 0.25f});
    innerTable .setHorizontalAlignment(Element.ALIGN_LEFT);
    innerTable .setWidthPercentage(100);

    PdfPCell cell = new PdfPCell(innerTable);
    cell.setPadding(0);

    innerTable.addCell(new Phrase("test Data"));
    innerTable.addCell(new Phrase("test Data"));
    innerTable.addCell(new Phrase("test Data"));
    innerTable.addCell(new Phrase("test Data"));

    outerTable.addCell(cell);
}

document.add(outertable);
document.close();
Joris Schellekens
  • 8,483
  • 2
  • 23
  • 54
Igoranze
  • 1,506
  • 13
  • 35

1 Answers1

1

Please take a look at the DropTablePart example. In this example, I add 4 tables with 19 rows to a ColumnText object. As soon as a table doesn't fit the page, I drop the remaining content of the ColumnText object (which will automatically drop the rest of the table) and I start a new page where a new table will start.

Dropping the content of the ColumnText object can be done in two different ways:

Either:

ct = new ColumnText(writer.getDirectContent());

Or:

ct.setText(null);

The result looks like this:

enter image description here

As you can see, rows 10-18 are dropped from inner table 3.

This is the full code:

public void createPdf(String dest) throws IOException, DocumentException {
    Document document = new Document();
    PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(dest));
    document.open();
    Rectangle column = new Rectangle(36, 36, 559, 806);
    ColumnText ct = new ColumnText(writer.getDirectContent());
    ct.setSimpleColumn(column);
    for (int i = 0; i < 4; ) {
        PdfPTable table = new PdfPTable(new float[]{0.25f, 0.25f, 0.25f, 0.25f});
        table.setHorizontalAlignment(Element.ALIGN_LEFT);
        table.setWidthPercentage(100);
        PdfPCell cell = new PdfPCell(new Phrase("inner table " + (++i)));
        cell.setColspan(4);
        table.addCell(cell);
        for (int j = 0; j < 18; j++) {
            table.addCell(new Phrase("test Data " + (j + 1) + ".1"));
            table.addCell(new Phrase("test Data " + (j + 1) + ".1"));
            table.addCell(new Phrase("test Data " + (j + 1) + ".1"));
            table.addCell(new Phrase("test Data " + (j + 1) + ".1"));
        }
        ct.addElement(table);
        if (ColumnText.hasMoreText(ct.go())) {
            document.newPage();
            ct = new ColumnText(writer.getDirectContent());
            ct.setSimpleColumn(column);
        }
    }
    document.close();
}

I didn't use nested tables, because it is generally a bad idea to use nested tables. It has a negative impact on the performance of your application and it usually results in code that is hard to maintain (the programmers who inherit our application will thank you for not using nested tables).

Joris Schellekens
  • 8,483
  • 2
  • 23
  • 54
Bruno Lowagie
  • 75,994
  • 9
  • 109
  • 165
  • Thanks, but it's not what i need, Anyway i "fixed" it with {dataTable.setHeaderRows(1); dataTable.setSkipFirstHeader(true);} On the next page, my first header "Continue" will be displayed. Thats good enough. +1 for your time – Igoranze Apr 11 '16 at 07:36