0
votes

I'm generating an invoice and I've been working with iText for 2 days now.

My question is: How can I split a PdfPTable over multiple pages if I'm not adding them directly in a document but writing it from a PdfContentByte.

this is the output. The things I don't get the hang of:

1: How do I make the header row show up on the new page? (without readding the first row)

2: How can I automate a loop (and not hard code) for many records so it splits the table on multiple pages?

3: Here This is how my invoice should look and at the end of the table I add a footer table that holds information about total cost and cost with VAT. How can I calculate the total height of the table on the last page and add at the end of it my footer table?

this is the code I use to generate the pdf so far:

private void generateTable(Document doc, PdfContentByte cb) throws DocumentException {
TableHeaderFields headerFields = new TableHeaderFields();

PdfPTable invTable = new PdfPTable(7);
invTable.setWidths(new int[] {20, 200, 40, 40, 70, 70, 70});
PdfPCell invCell;
// invTable.getDefaultCell().setBackgroundColor(BaseColor.LIGHT_GRAY);
for (String colTitle : headerFields.getHeaderFields()) {
  invCell = new PdfPCell(new Phrase(colTitle, new Font(bfBold, 8)));
  invCell.setBackgroundColor(BaseColor.LIGHT_GRAY);
  invCell.setHorizontalAlignment(Element.ALIGN_CENTER);
  invTable.addCell(invCell);
}
invTable.setHeaderRows(2);
invTable.setTotalWidth(500);

//   invTable.getDefaultCell().setBackgroundColor(null);
//Sample Content of the table;
List<InvoiceLine> contentList = InvoiceLine.generateListOfInvLine(70);

int nrCrt = 1;
float totalSum = 0;
float height = 0;
for (InvoiceLine invLine : contentList) {
  //      System.out.println(invLine);
  height = invTable.getTotalHeight();

  invCell = new PdfPCell(new Phrase("" + nrCrt++, new Font(bf, 8)));
  invTable.addCell(invCell);

  invCell = new PdfPCell(new Phrase(invLine.getItem_desc(), new Font(bf, 8)));
  invTable.addCell(invCell);

  invCell = new PdfPCell(new Phrase("" + invLine.getUm(), new Font(bf, 8)));
  invCell.setHorizontalAlignment(Element.ALIGN_CENTER);
  invTable.addCell(invCell);

  invCell = new PdfPCell(new Phrase("" + invLine.getQty(), new Font(bf, 8)));
  invCell.setHorizontalAlignment(Element.ALIGN_CENTER);
  invTable.addCell(invCell);

  invCell = new PdfPCell(new Phrase("" + invLine.getPrice(), new Font(bf, 8)));
  invCell.setHorizontalAlignment(Element.ALIGN_CENTER);
  invTable.addCell(invCell);

  invCell = new PdfPCell(new Phrase("" + (float) (invLine.getQty() * invLine.getPrice()), new Font(bf, 8)));
  invCell.setHorizontalAlignment(Element.ALIGN_CENTER);
  invTable.addCell(invCell);

  invCell = new PdfPCell(new Phrase("" + (float) (invLine.getQty() * invLine.getPrice() * 0.24), new Font(bf, 8)));
  invCell.setHorizontalAlignment(Element.ALIGN_CENTER);
  invTable.addCell(invCell);
  totalSum += (invLine.getQty() * invLine.getPrice());
}
invTable.writeSelectedRows(0, 40, 50, 630, cb);
//    if ((PageSize.A4.getHeight() - height) <= 40) {
//      System.out.println("A4 : " + PageSize.A4.getHeight() + " vs " + height);
doc.newPage();
invTable.writeSelectedRows(41, -1, 50, 630, cb);
//    } else
System.out.println("WE'RE OK:" + "A4 : " + PageSize.A4.getHeight() + " vs " + height);

PdfPTable footer = generateFooterForTable(totalSum, (float) 0.24);
footer.setTotalWidth(500);
footer.writeSelectedRows(0, -1, 50, 630 - height, cb);
 }

  private PdfPTable generateFooterForTable(float total, float vatRate) throws DocumentException {
PdfPTable footerTable = new PdfPTable(5);
footerTable.setWidths(new int[] {75, 185, 110, 70, 70,});

PdfPCell invCell = new PdfPCell(new Phrase("Semnatura si\n" + "stampila furnizorului", new Font(bf, 8)));
invCell.setRowspan(2);
footerTable.addCell(invCell);

invCell = new PdfPCell(new Phrase("Numele Delegatului\n" + "Act Delegat" + "Semnatura", new Font(bf, 8)));
invCell.setRowspan(2);
footerTable.addCell(invCell);

invCell = new PdfPCell(new Phrase("TOTAL", new Font(bf, 8)));
invCell.setHorizontalAlignment(Element.ALIGN_CENTER);
footerTable.addCell(invCell);

invCell = new PdfPCell(new Phrase("" + total, new Font(bf, 8)));
invCell.setHorizontalAlignment(Element.ALIGN_CENTER);
footerTable.addCell(invCell);

invCell = new PdfPCell(new Phrase("" + total * vatRate, new Font(bf, 8)));
invCell.setHorizontalAlignment(Element.ALIGN_CENTER);
footerTable.addCell(invCell);

invCell = new PdfPCell(new Phrase("TOTAL GENERAL", new Font(bf, 8)));
invCell.setHorizontalAlignment(Element.ALIGN_CENTER);
footerTable.addCell(invCell);

invCell = new PdfPCell(new Phrase("" + (total + (total * vatRate)), new Font(bfBold, 8)));
invCell.setHorizontalAlignment(Element.ALIGN_CENTER);
invCell.setColspan(2);
footerTable.addCell(invCell);
return footerTable;
}
1

1 Answers

1
votes

When you use writeSelectedRows(), you are responsible to do the math, e.g. to calculate the height of the rows. You can only calculate the height of rows after you've defined the width of the table. In your case, you probably don't want the total height of the table, but you want to know the height of the rows. See for instance the TableHeight example to find out how to use the getRowHeight() method.

Of course: when reading the documentation, you discover that there's a much easier way to add a table to PdfContentByte that doesn't require the use of writeSelectedRows(). Please take a look at the ColumnTable example. In this example, we add the PdfPTable to a ColumnText object. We define a rectangle for the column and we continue adding columns to new pages until the complete table is rendered.