iText is a Java library for developers looking to enhance web- and other applications with dynamic PDF document generation and/or manipulation.
Constructing tables with the iText library can be thought of as an easy task, but there is much more thought that should be put into this when generating large dynamic tables (variable number of columns and rows). I found a few interesting solutions for some issues that may arise and I will post them here in the hope that they will be useful to others as well.
Splitting tables over several pages
If you have large tables, you cannot expect them to fit on one page. Happily, iText splits the table automatically between rows. If your table has a header that needs to be repeated on every page, you need to tell the table how many rows the header counts. This can be done with the method setHeaderRows. In the example, there is one header row:
Document document = new Document(); PdfWriter.getInstance(document, new FileOutputStream("AddBigTable.pdf")); document.open(); PdfPTable table = new PdfPTable(4); table.setHeaderRows(1); String[] headerStrings = new String[] { "ROWNUM", "COL_A", "COL_B", "COL_C" }; for (String header : headerStrings) { PdfPCell headerCell = new PdfPCell(new Paragraph(header)); headerCell.setGrayFill(0.7f); table.addCell(headerCell); } ResultSet r = s.executeQuery(" SELECT ROWNUM, COL_A, COL_B, COL_C FROM LARGE_TABLE"); while (r.next()) { long row = r.getLong("ROWNUM"); PdfPCell cell = new PdfPCell(new Paragraph(String.valueOf(row))); table.addCell(cell); cell = new PdfPCell(new Paragraph(r.getString("COL_A"))); table.addCell(cell); cell = new PdfPCell(new Paragraph(r.getString("COL_B"))); table.addCell(cell); cell = new PdfPCell(new Paragraph(r.getString("COL_C"))); table.addCell(cell); } document.add(table); document.close(); |
It seems that you do not have to worry about how large your table is – iText will distribute it over different pages. However, in the example above it may be noticed that while iterating through the result set the PdfPTable-object keeps on growing, taking more and more memory that isn’t being released. In real-world applications, this can become a serious problem.
Efficient way to write very large tables
When you add objects to a Document, these objects are written to the output stream ‘as soon as possible’. The objects that have been written are made eligible for destruction. However, when you construct a PdfPTable and keep adding new cells without adding the table to the document the memory needed to store table data can exceed the memory available to your JVM. One solution is to fragment a large table into different small tables that are destroyed once they are added to the document and as the tables are glued to each other (don’t use setSpacingBefore and setSpacingAfter here) nobody will see the difference between one large table or several small tables. Nevertheless, there is a better solution: you can add a partially constructed table to the document, release the data in the table, and continue adding new cells. For example, we can change the loop from the above example as following:
while (r.next()) { long row= r.getLong("ROWNUM"); if (row % 100 == 0) { document.add(table); table.deleteBodyRows(); table.setSkipFirstHeader(true); } PdfPCell cell = new PdfPCell(new Paragraph(String.valueOf(row))); table.addCell(cell); cell = new PdfPCell(new Paragraph(r.getString("COL_A"))); table.addCell(cell); cell = new PdfPCell(new Paragraph(r.getString("COL_B"))); table.addCell(cell); cell = new PdfPCell(new Paragraph(r.getString("COL_C"))); table.addCell(cell); } document.add(table); |
Splitting tables vertically
For tables that have a lot of columns, it may be needed to split the table vertically. To do this, you can use the PdfPTable.writeSelectedRows(int colStart, int colEnd, int rowStart, int rowEnd, float xPos, float yPos, PdfContentByte[] canvases) method.
Finally, there’s another very important peculiarity of what does Cialis that brings it so high above its alternatives. It is the only med that is available in two versions – one intended for use on as-needed basis and one intended for daily use. As you might know, Viagra and Levitra only come in the latter of these two forms and should be consumed shortly before expected sexual activity to ensure best effect. Daily Cialis, in its turn, contains low doses of Tadalafil, which allows to build its concentration up in your system gradually over time and maintain it on acceptable levels, which, consequently, makes it possible for you to enjoy sex at any moment without having to time it.
i want to split the pdf verically by allowing 8 columns in one page and other 8 columns in next page and so on. can u pls help me to do this.
Thanks in advance.
July 14, 2011 at 7:03 am