Reputation: 69
I'm using iText 5.5.9. I have a PdfPTable
that I show inside a ColumnText
.
The ColumnText
has a small column and a large column.
If the table is too large for the small column, it should move to the second, larger column. How can I do this?
I tried using table.setKeepTogether(true)
, but that doesn't work.
I also tried the suggestion from this page (http://itext.2136553.n4.nabble.com/PdfPTable-KeepTogether-and-ColumnText-td2141501.html) to wrap my table inside a second table and use tableWrapper.setSplitRows(false)
. But if I do that, I don't see the table at all anymore.
Here's my code:
public class PdfTest {
private static String filename = "C:/Users/Development/Documents/pdf_test.pdf";
public static void main(String[] args) {
try {
new PdfTest();
File f = new File(filename);
Desktop.getDesktop().open(f);
} catch (DocumentException | IOException e) {
e.printStackTrace();
}
}
public PdfTest() throws DocumentException, IOException {
File file = new File(filename);
OutputStream os = new FileOutputStream(file);
Document document = new Document();
PdfWriter writer = PdfWriter.getInstance(document, os);
document.open();
PdfContentByte canvas = writer.getDirectContent();
printPage1(document, canvas);
document.newPage();
printPage2(document, canvas);
document.close();
os.close();
}
private void printPage1(Document document, PdfContentByte canvas) throws DocumentException {
int cols = 3;
int rows = 15;
PdfPTable table = new PdfPTable(cols);
for (int row = 0; row < rows; row++) {
for (int col = 0; col < cols; col++) {
table.addCell(new Phrase("Cell " + row + ", " + col));
}
}
Paragraph paragraph = new Paragraph();
paragraph.add(table);
ColumnText columnText = new ColumnText(canvas);
columnText.addElement(new Paragraph("This table should keep together!"));
columnText.addElement(paragraph);
int status = ColumnText.START_COLUMN;
Rectangle docBounds = document.getPageSize();
Rectangle bounds = new Rectangle(docBounds.getLeft(20), docBounds.getTop(20) - 200, docBounds.getRight(20), docBounds.getTop(20));
bounds.setBorder(Rectangle.BOX);
bounds.setBorderColor(BaseColor.BLACK);
bounds.setBorderWidth(1);
bounds.setBackgroundColor(new BaseColor(23, 142, 255, 20));
canvas.rectangle(bounds);
columnText.setSimpleColumn(bounds);
status = columnText.go();
if (ColumnText.hasMoreText(status)) {
bounds = new Rectangle(docBounds.getLeft(20), docBounds.getBottom(20), docBounds.getRight(20), docBounds.getBottom(20) + 600);
bounds.setBorder(Rectangle.BOX);
bounds.setBorderColor(BaseColor.BLACK);
bounds.setBorderWidth(1);
bounds.setBackgroundColor(new BaseColor(255, 142, 23, 20));
canvas.rectangle(bounds);
columnText.setSimpleColumn(bounds);
status = columnText.go();
}
}
private void printPage2(Document document, PdfContentByte canvas) throws DocumentException {
int cols = 3;
int rows = 15;
PdfPTable table = new PdfPTable(cols);
for (int row = 0; row < rows; row++) {
for (int col = 0; col < cols; col++) {
table.addCell(new Phrase("Cell " + row + ", " + col));
}
}
PdfPTable tableWrapper = new PdfPTable(1);
tableWrapper.addCell(table);
tableWrapper.setSplitRows(false);
Paragraph paragraph = new Paragraph();
paragraph.add(tableWrapper);
ColumnText columnText = new ColumnText(canvas);
columnText.addElement(new Paragraph("This table should keep together!"));
columnText.addElement(tableWrapper);
int status = ColumnText.START_COLUMN;
Rectangle docBounds = document.getPageSize();
Rectangle bounds = new Rectangle(docBounds.getLeft(20), docBounds.getTop(20) - 200, docBounds.getRight(20), docBounds.getTop(20));
bounds.setBorder(Rectangle.BOX);
bounds.setBorderColor(BaseColor.BLACK);
bounds.setBorderWidth(1);
bounds.setBackgroundColor(new BaseColor(23, 142, 255, 20));
canvas.rectangle(bounds);
columnText.setSimpleColumn(bounds);
status = columnText.go();
if (ColumnText.hasMoreText(status)) {
bounds = new Rectangle(docBounds.getLeft(20), docBounds.getBottom(20), docBounds.getRight(20), docBounds.getBottom(20) + 600);
bounds.setBorder(Rectangle.BOX);
bounds.setBorderColor(BaseColor.BLACK);
bounds.setBorderWidth(1);
bounds.setBackgroundColor(new BaseColor(255, 142, 23, 20));
canvas.rectangle(bounds);
columnText.setSimpleColumn(bounds);
status = columnText.go();
}
}
}
EDIT: I realize now that I'm asking about a solution, rather than about the problem itself. So I'm taking a step back here.
The idea is that the PDF has an optional space for an envelope window on the first page. This window will display an address.
This splits up the rest of the (first) page into two areas above and below the envelope window. I tried solving that with ColumnText
s.
I added a title, which appears neatly above the envelope window. Then I added a table. This table displayed partially above and below the envelope window.
So these letters can contain more than just tables, and possibly multiple tables and paragraphs.
Upvotes: 0
Views: 2057
Reputation: 95918
I would propose using a helper method which first tries to draw the Element
in simulation mode and then really draws it into the first rectangle where it fits.
Such a method could look like this:
Rectangle[] drawKeepTogether(Element element, PdfContentByte canvas, Rectangle... rectangles) throws DocumentException
{
int i = 0;
for (; i < rectangles.length; i++)
{
ColumnText columnText = new ColumnText(canvas);
columnText.addElement(element);
columnText.setSimpleColumn(rectangles[i]);
int status = columnText.go(true);
if (!ColumnText.hasMoreText(status))
break;
}
if (i < rectangles.length)
{
Rectangle rectangle = rectangles[i];
ColumnText columnText = new ColumnText(canvas);
columnText.addElement(element);
columnText.setSimpleColumn(rectangle);
columnText.go(false);
Rectangle[] remaining = new Rectangle[rectangles.length-i];
System.arraycopy(rectangles, i, remaining, 0, remaining.length);
remaining[0] = new Rectangle(rectangle.getLeft(), rectangle.getBottom(), rectangle.getRight(), columnText.getYLine());
return remaining;
}
return new Rectangle[0];
}
(TableKeepTogether.java method drawKeepTogether
)
If used like this:
private void printPage3(Document document, PdfContentByte canvas) throws DocumentException {
int cols = 3;
int rows = 15;
PdfPTable table = new PdfPTable(cols);
for (int row = 0; row < rows; row++) {
for (int col = 0; col < cols; col++) {
table.addCell(new Phrase("Cell " + row + ", " + col));
}
}
table.setSpacingBefore(5);
Rectangle docBounds = document.getPageSize();
Rectangle upper = new Rectangle(docBounds.getLeft(20), docBounds.getTop(20) - 200, docBounds.getRight(20), docBounds.getTop(20));
upper.setBackgroundColor(new BaseColor(23, 142, 255, 20));
Rectangle lower = new Rectangle(docBounds.getLeft(20), docBounds.getBottom(20), docBounds.getRight(20), docBounds.getBottom(20) + 600);
lower.setBackgroundColor(new BaseColor(255, 142, 23, 20));
Rectangle[] rectangles = new Rectangle[] { upper, lower };
for (Rectangle bounds : rectangles)
{
bounds.setBorder(Rectangle.BOX);
bounds.setBorderColor(BaseColor.BLACK);
bounds.setBorderWidth(1);
canvas.rectangle(bounds);
}
rectangles = drawKeepTogether(new Paragraph("This table should keep together!"), canvas, rectangles);
rectangles = drawKeepTogether(table, canvas, rectangles);
}
(TableKeepTogether.java method printPage3
)
The page generated by this method looks like this:
Upvotes: 1