kobewarui
kobewarui

Reputation: 73

iText java - Split table vertically and horizontally

I am an iText java developer. I have been working with large tables and now I am stuck in splitting a table vertically.

In page 119 of iText in Action, honourable Bruno Lowagie (I got so much respect for this guy) explains how to split a large table so that columns appear in two distinct pages.

I followed his example and it works fine when a document has few rows.

In my case I have 100 rows, maning that the document needs to split 100 rows in several pages while at the same time split columns vertically. I ran my code as follows but only the first 34 rows are displayed.

Can someone kindly explain what could be wrong with this code:

//create a PDFPTable with 24 columns
PdfPTable tbl = new PdfPTable(new float{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1});
//loop through 100 rows
for (int i = 0; i < 100; i++) {
    //insert 24 table cells
}

tbl.setTotalWidth(1500);//set table width
float top = document.top() - document.topMargin() - 30;
PdfContentByte canvas = writer.getDirectContent();
tbl.writeSelectedRows(0, 12, 0, -1, document.leftMargin(), top, canvas);
document.newPage();
// draw the remaining two columns on the next page
tbl.writeSelectedRows(12, -1, 0, -1, 5, top, canvas);

Upvotes: 0

Views: 2477

Answers (1)

Bruno Lowagie
Bruno Lowagie

Reputation: 77606

You don't see 100 rows, because 100 rows don't fit on a singe page. When you use writeSelectedRows(), you need to calculate how many rows fit on the page and only add the selection of rows that fits.

I'm at a conference in Berlin for the moment, but I wrote a quick example that shows more or less what you need to do:

public void createPdf(String dest) throws IOException, DocumentException {
    Document document = new Document(PageSize.A4.rotate());
    PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(dest));
    document.open();
    PdfPTable tbl = new PdfPTable(new float[]{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1});
    //loop through 100 rows
    for (int r = 1; r <= 100; r++) {
        for (int c = 1; c <= 24; c++) {
            tbl.addCell(String.format("r%sc%s", r, c));
        }
    }
    PdfContentByte canvas = writer.getDirectContent();
    tbl.setTotalWidth(1500);//set table width
    float top = document.top() - document.topMargin() - 30;
    float yPos = top;
    int start = 0;
    int stop = 0;
    for (int i = 0; i < 100; i++) {
        yPos -= tbl.getRowHeight(i);
        if (yPos < 0) {
            stop = --i;
            tbl.writeSelectedRows(0, 12, start, stop, document.leftMargin(), top, canvas);
            document.newPage();
            tbl.writeSelectedRows(12, -1, start, stop, 5, top, canvas);
            start = stop;
            document.newPage();
            yPos = top;
        }
    }
    tbl.writeSelectedRows(0, 12, stop, -1, document.leftMargin(), top, canvas);
    document.newPage();
    tbl.writeSelectedRows(12, -1, stop, -1, 5, top, canvas);
    document.close();
}

As you can see, I keep track of the height of the table and as soon as it risks "falling off the page", I render the rows that fit, and I go to the next page.

Upvotes: 2

Related Questions