What's an easy to print "first right, then down"?

I would like to print a PdfPTable containing many more rows and columns than fit in one page of the PDF. I would like to print "first right, then down", which is similar to row-major order. Print

I would like to print a PdfPTable containing many more rows and columns than fit in one page of the PDF.

I would like to print "first right, then down", which is similar to row-major order. Print the first page-full of rows, but all columns for those rows. Then print the next page-full of rows, and again all columns for those rows.

As I understand it, iText can handle a PdfPTable containing more rows than fit on a page, but can't handle more columns than fit on a page. So I split the columns myself. But that means that I end up printing "first down, then right", which is not what I want.

Is there an easy way to do what I want? Note that I do not know the row heights ahead of time, because I call setMinimumHeight() on the PdfPCell objects.

The only way I can think of, which is clumsy, is to first split columns, as before. Then, for each sequence of columns that fit on one page, add rows one by one to a PdfPTable as long as they fit. When they don't, that's where we need to split the rows. At the end of this, we end up with PdfPTable objects for each set of rows and columns. We need to keep all of them in memory and add them to the PDF Document in the right (row-major) order.

This seems rather inelegant, so I wanted to check if there's a cleaner solution.

Posted on StackOverflow on Feb 28, 2014 by Kartick Vaddadi

If you have really large tables, the most elegant way to maintain the overview and to distribute the table over different pages, is by adding the table to one really large PdfTemplate object and then afterwards add clipped parts of that PdfTemplate object to different pages.

That's what I've done in the TableTemplate example.

I create a table with 15 columns a total width of 1500pt.

Table table = new Table(15);
table.setWidth(1500);
Cell cell;
for (int r = 'A'; r 

Now I write this table to a Form XObject that measures 1500 by 1300. Note that 1300 is the total height of the table. You can get it if you multiply the 26 rows on (height + border (0.5) * 2 )

PdfContentByte canvas = writer.getDirectContent();
PdfTemplate tableTemplate = canvas.createTemplate(1500, 1300);
table.writeSelectedRows(0, -1, 0, 1300, tableTemplate);

Now that you have the PdfFormXObject, you can reuse it on every page like this:

PdfFormXObject tableTemplate = new PdfFormXObject(new Rectangle(1500, 1300));
Canvas canvas = new Canvas(tableTemplate, pdfDoc);
canvas.add(table);
PdfFormXObject clip;
for (int j = 0; j  0; i -= 650) {
        clip = new PdfFormXObject(new Rectangle(500, 650));
        new PdfCanvas(clip, pdfDoc).addXObject(tableTemplate, -j, 650 - i);
        new PdfCanvas(pdfDoc.addNewPage()).addXObject(clip, 36, 156);
    }
}

The result is table_template.pdf where we have cells A1 to M5 on page 1, cells N1 to Z5 on page 2, cells A6 to M10 on page 3, cells N6 to Z10 on page 4, cells A11 to M15 on page 5 and cells N11 to Z15 on page 6.

Click this link if you want to see how to answer this question in iText 5.



Ready to use iText?

Try our iText 7 Library and add-ons FREE for 30 days. Test your proof of concept, and see if our solution is right for you.

Get my FREE trial
Contact

Still have questions? 

We're happy to answer your questions. Reach out to us and we'll get back to you shortly.

Contact us
Stay updated

Join 11,000+ subscribers and become an iText PDF expert by staying up to date with our new products, updates, tips, technical solutions and happenings.

Subscribe Now