I had to write a custom PDF to do such a thing for work and people are always asking how to do it. Here is my solution.
//This is free for anyone's use/modification. I'd like to receive credit if it gets incorporated into the official itext though. //Copyright 2005. Michael McCaskill ([EMAIL PROTECTED]) import java.util.ArrayList; import java.util.Iterator; import java.util.List; import com.lowagie.text.Document; import com.lowagie.text.DocumentException; import com.lowagie.text.Paragraph; import com.lowagie.text.pdf.PdfContentByte; import com.lowagie.text.pdf.PdfPTable; import com.lowagie.text.pdf.PdfWriter; /** * Class that writes a <code>PdfPTable</code>, and spans it across multiple pages if the columns won't fit on one page */ public class PdfPTableWriter { //Instance variables private PdfPTable table; private PdfWriter writer; private Document document; //List of how many columns per horizontal page private List numberOfColumnsPerPage; //List of how many rows per vertical page private List numberOfRowsPerPage; //Offsets if given private float widthOffset = 0; private float heightOffset = 0; /** * Class Constructor */ public PdfPTableWriter(Document document, PdfWriter writer, PdfPTable table) { this.document = document; this.writer = writer; this.table = table; calculateColumns(); calculateRows(); } /** * Writes the table to the document */ public void writeTable() throws DocumentException { //Begin at row 1 (row after the header) int rowBegin = 1; int rowEnd = 0; //Note the size of numberOfRowsPerPage is how many vertical //pages there are. Iterator rowsIter = numberOfRowsPerPage.iterator(); while (rowsIter.hasNext()) { rowEnd = ((Integer)rowsIter.next()).intValue(); writeSelectedRows(rowBegin, rowEnd); rowBegin = rowEnd; } } /** * Prints the Report's columns (splitting horizontally if necessary) and subsequent rows * @param rowBegin * @param rowEnd * @throws DocumentException */ private void writeSelectedRows(int rowBegin, int rowEnd) throws DocumentException { int colBegin = 0; int colEnd = 0; float pageHeight = document.getPageSize().height() - heightOffset; PdfContentByte contentByte = writer.getDirectContent(); Iterator columnsIter = numberOfColumnsPerPage.iterator(); while (columnsIter.hasNext()) { colEnd = colBegin + ((Integer)columnsIter.next()).intValue(); //Writer table header writeSelectedRows(colBegin, colEnd, 0, 1, widthOffset, pageHeight); //Writes selected rows to the document writeSelectedRows(colBegin, colEnd, rowBegin, rowEnd, widthOffset, pageHeight - table.getHeaderHeight()); //Add a new page document.newPage(); colBegin = colEnd; } } public int getTotalPages() { return numberOfColumnsPerPage.size() * numberOfRowsPerPage.size(); } public void setHeightOffset(float heightOffset) { this.heightOffset = heightOffset; } public void setWidthOffset(float widthOffset) { this.widthOffset = widthOffset; } private void writeSelectedRows(int colBegin, int colEnd, int rowBegin, int rowEnd, float x, float y) { PdfContentByte cb = writer.getDirectContent(); table.writeSelectedRows(colBegin, colEnd, rowBegin, rowEnd, x, y, cb); } private void calculateColumns() { numberOfColumnsPerPage = new ArrayList(); float pageWidth = document.getPageSize().width() - widthOffset; float[] widths = table.getAbsoluteWidths(); if (table.getTotalWidth() > pageWidth) { //tmp variable for amount of total width thus far float tmp = 0f; //How many columns for this page int columnCount = 0; //Current page we're on int currentPage = 0; //Iterate through the column widths for (int i = 0; i < widths.length; i++) { //Add to the temporary total tmp += widths[i]; //If this column will not fit on the page if (tmp > pageWidth) { //Add the current column count to this page numberOfColumnsPerPage.add(new Integer(columnCount)); //Since this column won't fit, the tmp variable should start off the next iteration //as this column's width tmp = widths[i]; //Set column count to 1, since we have moved this column to the next page columnCount = 1; } //If this is will fit on the page else { //Increase the column count columnCount++; } } //Save the remaining columns numberOfColumnsPerPage.add(new Integer(columnCount)); } //All the columns will fit on one horizontal page //Note: -1 means all the columns else { numberOfColumnsPerPage.add(new Integer(-1)); } } private void calculateRows() { numberOfRowsPerPage = new ArrayList(); float pageHeight = document.getPageSize().height() - heightOffset - table.getHeaderHeight(); //If the table won't fit on the first page if (table.getTotalHeight() > pageHeight - table.getHeaderHeight()) { //Temp variables float tmp = 0f; //Determine the start and end rows for each page for (int i = 1; i < table.size(); i++) { //Add this row's height to the tmp total tmp += table.getRowHeight(i); if (tmp > pageHeight) { //This row won't fit so end at previous row numberOfRowsPerPage.add(new Integer(i-1)); //Since this row won't fit, the tmp variable should start off the next iteration //as this row's height tmp = table.getRowHeight(i); } } //Last page always ends on totalRows numberOfRowsPerPage.add(new Integer(table.size())); } //All the rows will fit on one vertical page //Note: -1 means all the rows else { numberOfRowsPerPage.add(new Integer(-1)); } } } ------------------------------------------------------- This SF.Net email is sponsored by: Power Architecture Resource Center: Free content, downloads, discussions, and more. http://solutions.newsforge.com/ibmarch.tmpl _______________________________________________ iText-questions mailing list iText-questions@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/itext-questions