Hi,
I've been trying to generate PDF documents using a combination of iText
and UJAC. The documents have multiple tables, always nested inside other
containers.
I noticed that, even though UJAC has a keepTogether attribute for
tables, that tables are still split across two pages even if it would
fit on a single page if a new page would have been started first. This
only occurs when tables are nested inside other containers (chapters,
sections), not when the table is directly added to a page.
The keepTogether attribute works by calling PdfDocument's fitsPage
method. However, after checking this the table is added to its current
container and not committed to the document just yet. This only happens
when the entire container embedding multiple tables is added to the
document. Therefore, the fitsPage test is useless at this point because
the content of the page only changes as the entire container is added.
To fix this problem, I decided to move the fitsPage check to iText
itself, when a PdfPTable object is actually added to the document
directly. I've attached the patch (for the CVS repository) to do this.
For it to work correctly, UJac also has to be patched because it has to
set the (new) keepTogether attribute for PdfPTable objects. But that's
for another mailing list..
I was hoping this could be included if deemed a sensible solution. If
there was another solution that I somehow overlooked or if the problem
is not clear, then I'd be more than hapy to hear about it.
Regards,
Bram
Index: com/lowagie/text/pdf/PdfDocument.java
===================================================================
RCS file: /cvsroot/itext/src/com/lowagie/text/pdf/PdfDocument.java,v
retrieving revision 1.214
diff -u -r1.214 PdfDocument.java
--- com/lowagie/text/pdf/PdfDocument.java 1 Nov 2005 12:27:04 -0000
1.214
+++ com/lowagie/text/pdf/PdfDocument.java 10 Nov 2005 15:20:45 -0000
@@ -968,6 +968,13 @@
Paragraph p = new Paragraph();
p.setLeading(0);
ct.addElement(p);
+
+ //if the table prefers to be on a single page, and it wouldn't
+ //fit on the current page, start a new page.
+ if (ptable.getKeepTogether() && !fitsPage(ptable, 0f))
+ {
+ newPage();
+ }
}
ct.addElement(ptable);
boolean he = ptable.isHeadersInEvent();
@@ -2991,4 +2998,4 @@
void incMarkPoint() {
++markPoint;
}
-}
\ No newline at end of file
+}
Index: com/lowagie/text/pdf/PdfPTable.java
===================================================================
RCS file: /cvsroot/itext/src/com/lowagie/text/pdf/PdfPTable.java,v
retrieving revision 1.64
diff -u -r1.64 PdfPTable.java
--- com/lowagie/text/pdf/PdfPTable.java 30 Oct 2005 10:11:09 -0000 1.64
+++ com/lowagie/text/pdf/PdfPTable.java 10 Nov 2005 15:20:45 -0000
@@ -141,6 +141,12 @@
*/
private boolean splitLate = true;
+ /**
+ * Defines if the table should be kept
+ * on one page if possible
+ */
+ private boolean keepTogether;
+
protected PdfPTable() {
}
@@ -157,6 +163,7 @@
absoluteWidths = new float[relativeWidths.length];
calculateWidths();
currentRow = new PdfPCell[absoluteWidths.length];
+ keepTogether = false;
}
/** Constructs a <CODE>PdfPTable</CODE> with <CODE>numColumns</CODE>
columns.
@@ -171,6 +178,7 @@
absoluteWidths = new float[relativeWidths.length];
calculateWidths();
currentRow = new PdfPCell[absoluteWidths.length];
+ keepTogether = false;
}
/** Constructs a copy of a <CODE>PdfPTable</CODE>.
@@ -230,6 +238,7 @@
splitLate = sourceTable.splitLate;
skipFirstHeader = sourceTable.skipFirstHeader;
horizontalAlignment = sourceTable.horizontalAlignment;
+ keepTogether = sourceTable.keepTogether;
}
/** Sets the relative widths of the table.
@@ -1019,5 +1028,22 @@
public void setSplitLate(boolean splitLate) {
this.splitLate = splitLate;
}
+
+ /**
+ * If true the table will be kept on one page if it fits, by forcing a
+ * new page if it doesn't fit on the current page. The default is to
+ * split the table over multiple pages.
+ *
+ * @param p_KeepTogether whether to try to keep the table on one page
+ */
+ public void setKeepTogether(boolean p_KeepTogether)
+ {
+ keepTogether = p_KeepTogether;
+ }
-}
\ No newline at end of file
+ public boolean getKeepTogether()
+ {
+ return keepTogether;
+ }
+
+}