Search code examples
javaitexttabular

List items in table cell are not formatted


I have a problem with PDF, generated using iText (version 5.5.2). I have a table which should contain various elements, including lists.

However, the list inside the cell is wrongly displayed - it's not rendered at all as list, instead list items are displayed one by another.

So instead

  1. item1
  2. item2
  3. item3

I got

item1item2item3

I'm using the following code:

private static Paragraph list(String... items) {
    Paragraph para = new Paragraph();
    com.itextpdf.text.List list = new com.itextpdf.text.List(true, 10);
    for (String item : items) {
        list.add(new ListItem(item));
    }
    para.add(list);
    return para;
}

    document.add(list("item1","item2","item3));
    PdfPTable table = new PdfPTable(2);
    table.addCell("Some list");
    table.addCell(list("item1","item2","item3));
    document.add(table);

The element that is added to the table is identical to that that is added to the document. The difference is, first is displayed correctly, as list, and second has no list formatting.

What I'm doing wrong here?


Solution

  • You are adding a List to a PdfPTable in text mode. That can never work. You should add the List in composite mode. The difference between text mode and composite mode is explained in the answer to the following questions:

    If you want to find more useful answers explaining the difference between these two concepts, please download the free ebook The Best iText Questions on StackOverflow (that's where I found the link to the above questions).

    I've also searched the sandbox examples on the official iText website and that's how I found the ListInCell example showing many different ways to add a list to a PdfPCell:

    // We create a list:
    List list = new List();                
    list.add(new ListItem("Item 1"));
    list.add(new ListItem("Item 2"));
    list.add(new ListItem("Item 3"));
    
    // We wrap this list in a phrase:     
    Phrase phrase = new Phrase();
    phrase.add(list);
    // We add this phrase to a cell
    PdfPCell phraseCell = new PdfPCell();
    phraseCell.addElement(phrase);           
    
    // We add the cell to a table:
    PdfPTable phraseTable = new PdfPTable(2);
    phraseTable.setSpacingBefore(5);
    phraseTable.addCell("List wrapped in a phrase:");
    phraseTable.addCell(phraseCell);
    
    // We wrap the phrase table in another table:
    Phrase phraseTableWrapper = new Phrase();
    phraseTableWrapper.add(phraseTable);
    
    // We add these nested tables to the document:
    document.add(new Paragraph("A list, wrapped in a phrase, wrapped in a cell, wrapped in a table, wrapped in a phrase:"));
    document.add(phraseTableWrapper);
    
    // This is how to do it:
    
    // We add the list directly to a cell:
    PdfPCell cell = new PdfPCell();
    cell.addElement(list);
    // We add the cell to the table:
    PdfPTable table = new PdfPTable(2);
    table.setSpacingBefore(5);
    table.addCell("List placed directly into cell");
    table.addCell(cell);
    

    The resulting PDF (list_in_cell.pdf) looks the way I'd expect it.

    However, there are two caveats:

    • The example mentions "This example was written by Bruno Lowagie for a prospective customer. The code in this sample works with the latest version of iText. It doesn't work with versions predating iText 5" and I don't know if it will work with iText 5.5.2.
    • I know that nested lists aren't supported in tables. So if you need a list inside a list inside a cell, you'll get results that don't look the way you want it.