Cryn
Cryn

Reputation: 1025

iText: how to repeat table cell content on new page?

I want to generate a table that contains customer orders. The (simplified) table looks like below. If a customer has multiple orders, I just add the customer info in the first row of the customer. So the orders 1 to 3 belong to customer 1 and the orders 4 & 5 to customer 2

   Customer   |  Order   (header row)
 -------------+--------------------------------------------
  Name 1      | Item 1 (Order 1)
  Street      |
  City        |
 -------------+--------------------------------------------
              | Item 1 (Order 2)
              | Item 2
 -------------+--------------------------------------------
              | Item 1 (Order 3)
 -------------+--------------------------------------------
  Name 2      | Item 1 (Order 4)
  Street      | Item 2
  City        | Item 3
              | Item 4
 -------------+--------------------------------------------
              | Item 1 (Order 5)

this works fine, except if I get a page break / new page. In this case, the table will look like this:

   Customer   |  Order
 -------------+--------------------------------------------
  Name 1      | Item 1 (Order 1)
  Street      |
  City        |
 -------------+--------------------------------------------
              | Item 1 (Order 2)
              | Item 2
 ### new page ###
   Customer   |  Order
 -------------+--------------------------------------------
              | Item 1 (Order 3)
 -------------+--------------------------------------------
  Name 2      | Item 1 (Order 4)
  Street      | Item 2
  City        | Item 3
              | Item 4
 -------------+--------------------------------------------
              | Item 1 (Order 5)

but I want the customer 1 repeated in the first customer cell on the new page, so it looks like this:

   Customer   |  Order
 -------------+--------------------------------------------
  Name 1      | Item 1 (Order 1)
  Street      |
  City        |
 -------------+--------------------------------------------
              | Item 1 (Order 2)
              | Item 2
 ### new page ###
   Customer   |  Order
 -------------+--------------------------------------------
  Name 1      | Item 1 (Order 3)
  Street      |
  City        |
 -------------+--------------------------------------------
  Name 2      | Item 1 (Order 4)
  Street      | Item 2
  City        | Item 3
              | Item 4
 -------------+--------------------------------------------
              | Item 1 (Order 5)

I think filling the cell could be done with a combined page/cell event, but this would require to set the minimum height of all customer-cells to the height of the filled customer cell, since I don't know when/where the new page will occur. This would waste a lot of space if I have large customer cells and small order cells. Any ideas, how I can build a table like the one above and repeat the contents of a certain cell after a page break / new page?

Upvotes: 2

Views: 1708

Answers (2)

LompaT
LompaT

Reputation: 63

I stumbled over the same problem recently. You can achieve this by using IText's afterSplitTable event.

 public void afterSplitTable(PdfPTable table, PdfPRow startRow, int startIdx) { 

     // Get the previous value
     Phrase previous = table.getRow(startIdx - 1).getCells()[0].getPhrase();

     // The cell to add the previous value in
     PdfPCell newCell = table.getRow(startIdx).getCells()[0];

     // Check if the new cell is empty to prevent overwriting some content
     if (newCell.getPhrase().getContent() == ""){
          // set the phrase of the new cell to the phrase of the previous one
          newCell.setPhrase(previous);
     }
 }

Upvotes: 2

Cryn
Cryn

Reputation: 1025

I found a start for a possible solution (for iText 5.1+):

  • add the table to a ColumnText
  • write the table to the document using ColumnText.go() in a loop.
  • after each go() get the number of rows written via ColumnText.getRowsDrawn()
  • create a new PdfPTable (with the same settings as the original table)
  • copy all rows from ColumnText.getRowsDrawn() to the end of the original table to the new table cellwise. Now I can replace the first empty cell of the first row with the data wanted.
  • delete the original table from the ColumnText with ColumnText.setText(null)
  • add the copy to the ColumnText

don't forget to replace the "original" table with the copy or you'll get an infinite loop. don't forget to copy and set any header or footer rows from the original first, before adding any content.

Upvotes: 1

Related Questions