iText Tutorial SourceForge.net Logo iText, a Free Java-PDF library
by
Bruno Lowagie
[Home] [Previous] [TOC] [Next] [PDF]

Part I: Simple iText

Chapter 5: Tables

IMPORTANT: if you only have to generate PDF (no XML, HTML, RTF,...), it is better to use the class PdfPTable instead of class Table.

Some simple tables
A Table is a Rectangle that contains Cells, ordered in some kind of matrix.
The matrix of a table is not necessarily an m x n-matrix. It can contain holes or cells that are bigger than the unit.

The most common way to construct a table, is to say in advance how many columns and rows you will need:
public Table(int columns, int rows) throws BadElementException;

In example 1 we construct a very simple table:
Table aTable = new Table(2,2);
aTable.addCell("0.0");
aTable.addCell("0.1");
aTable.addCell("1.0");
aTable.addCell("1.1");

This table has 2 columns and 2 colums. Cells are added automatically, starting with the first column in the first row, than the second column. When a row if full, the next cell is added in the first column of the next row. You can see this in the PDF-file generated by example 1.

It is also possible to add cells at a certain position in the table. This is shown in example 2 and its resulting PDF. We made a table we 4 columns and 4 rows and then added some cells at random positions:
Table aTable = new Table(4,4);
aTable.setAutoFillEmptyCells(true);
aTable.addCell("2.2", new Point(2,2));
aTable.addCell("3.3", new Point(3,3));
aTable.addCell("2.1", new Point(2,1));
aTable.addCell("1.3", new Point(1,3));

As you can see we have to set a parameter 'AutoFillEmptyCells' to true. This automagically fills the empty cells with a cell that follows the default cell layout. If we forget to do this (as in the second table in the example), there will be no extra cells added and rows that don't contain any cells will be omitted. In the example, the first row is not shown, because it is empty.

Often a table will be filled with the results of a database query. In most cases, you don't know in advance how many rows you will need. That's why there is also a second constructor:
public Table(int columns) throws BadElementException;

iText automatically adds rows when needed. In example 3, we initially start with 4 colums and 4 rows. When we add cells in the 6th and 7th row, iText automatically increments the number of rows to 7. See the resulting PDF.

Incrementing the number of colums is also possible, but it's a little bit more difficult. It doesn't work automatically. You have to use the method addColumns and set the widths of the columns. This is shown in example 4 and its resulting PDF.

Some Table parameters
The tables in the previous examples weren't very nice. We can set a lot of table parameters to change the look of the table. Class Table and class Cell are derived from class Rectangle and we can use a lot of typical rectangle-methods. Let's take a look at example 5 (Chap0505.pdf):
      Table table = new Table(3);
      table.setBorderWidth(1);
      table.setBorderColor(new Color(0, 0, 255));
      table.setCellpadding(5);
5.  table.setCellspacing(5);
      Cell cell = new Cell("header");
      cell.setHeader(true);
      cell.setColspan(3);
      table.addCell(cell);
10.  cell = new Cell("example cell with colspan 1 and rowspan 2");
      cell.setRowspan(2);
      cell.setBorderColor(new Color(255, 0, 0));
      table.addCell(cell);
      table.addCell("1.1");
15.  table.addCell("2.1");
      table.addCell("1.2");
      table.addCell("2.2");
      table.addCell("cell test1");
      cell = new Cell("big cell");
20.  cell.setRowspan(2);
      cell.setColspan(2);
      cell.setBackgroundColor(new Color(0xC0, 0xC0, 0xC0));
      table.addCell(cell);
      table.addCell("cell test2");
25.  document.add(table);


cellspacing / cellpadding:
In line 4, we set the padding of the table. This is the amount of space that is between the cellborder and its content. In the previous examples, we saw that the text was glued to the border. By using a certain padding, we can avoid this.
In line 5, we set the spacing of the table. This is the amount of space that is between the cells and the table border and half of the amount of space between the different cells.
In example 6, you can see the effect on the table in the resulting PDF file when you change these values.

cellwidth / cellheight:
The cellwidth is determined at the level of the table: you decide the total percentage the table will take on the page (the default is 80%). You also set the relative widths of all cells. If you set the widths of a 3 column table like this: { 1, 1, 2 }; the first and second column will use 25% of the total space; the third column will take 50%.
The height of the cell depends on the content and the alignment of the cell. You can't control it yourself. If you have only one line in your cell, you can use the method Cell.setLeading to change the height.

alignment:
In example 6, we have also changed the alignment of the 'big cell'.
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);

Remark: you can't always trust on the vertical alignment.

borders:
If we add a cell as we do in line 14, a default cell layout is used (this default layout can be changed using some setDefault-methods). If we add a cell using a Cell-object, we can control the layout cell per cell.
In line 2 and 3, we set the borderwidth and bordercolor of the complete table. We can use the same methods on a cell, see line 12. Each cell is drawn with a 'box' as border (as in HTML), but example 7 (Chap0507.pdf) shows us that we have a lot more possibilities in PDF.

colors:
You can also define the backgroundcolor of a cell as in line 22. In example 7 we don't use a color, but a 'grayfill' percentage.

rowspan / colspan:
Finally you can also set the rowspan (line 11 / 20) and the colspan (line 8 / 21) of a cell. This way you can merge several cells into one big cell.

Remark:
line 7 has no meaning in PDF, it is of use if you generate HTML it's not always possible to have the same layout in HTML. The PDF table looks a little bit like this:
header
example cell with colspan 1 and rowspan 2 1.1 2.1
1.2 2.2
cell test1 big cell
cell test2

Table splitting:
If a table doesn't fit on the page, it is split automatically. Example 8 (Chap0508.pdf) shows you what happens when a table reaches the end of the page. This is explained in depth in the next section.

Large tables
Tables that span multiple pages are cut into different parts automatically.
Example 9 (Chap0509.pdf shows a report that spans multiple pages. This report has a table header. If you want this table header to be repeated on every page, you can mark the end of the header section by using the method endHeaders(). This is done in Example 10 (see Chap0510.pdf).
For reports like this, it is advised to set the cellspacing to 0 and to use only a certain cellpadding.
You may have noticed that when a table is split, some borders seem to be missing. This is because cells that are completely drawn on the previous page, are not transfered to the next page. They are gone and their border isn't drawn.

Force a table or a cell to fit a page
In some cases, you may want to avoid cells or even the complete table to be split into two parts. Example 11 has almost exactly the same code as Example 8, but we have set the parameter 'TableHasToFit' to true.Take a look at the differences between the original example 8 and example 11. In example 12 we have changed Example 10 and we have set the parameter 'CellsHaveToFit' to true. (Compare Chap0510.pdf and Chap0512.pdf.)

Memory management
When you add objects to a Document, these objects are written to the outputstream as soon as possible. But when you construct a table, the Table-object keeps on growing. For really large tables, this can become a problem.
Also, if you are writing to a the outputstream of a HttpServletResponse-object, the timeout of the browser can be reached.
That is why it can be useful to control the 'table-breaks' yourself, using the fitsPage()-methods in class PdfWriter. Example 13 (Chap0513.pdf) shows you how to do this.

Nested tables
There are 2 different ways to nest tables. The first way, is to explicitly insert one table into another table, using the method 'insertTable'. Example 14 (Chap0514.pdf) shows 5 tables that were constructed by inserting tables into eachother. As you can see in the first 2 tables, all empty cells automatically get split, thus changing the original table grid. If a cell isn't empty, the colspan and/or rowspan are adjusted to the new situation. The third table on this page shows that all the relative widths of the columns in the original tables are preserved. The fourth table shows we can add other cells after we have inserted a table: the cell is added in the next cell that is free. Finally there is a table that uses 'deep nesting'.

When you use the 'insertTable' method, the widthpercentage of the table you are inserting is not taken into account. If you want the table to take only 80% of the width of the cell (this is the default width percentage), you have to wrap the table into a Cell. This is shown in example 15 (Chap0515.pdf). This is also to only way to have a table in combination with other elements in the same cell. This is demonstrated in example 16 (Chap0516.pdf).
Remark: you can only add a Table to a Cell with colspan and rowspan equal to 1.

Table offset
Before a table is added to a document. A newline is added using the current leading (i.e. the leading of the previous object that was added). Sometimes you don't want this because the space between the table and the previous object is to large/small. If you want to change this space, you have to set the offset of the table as shown in Example 17 (Chap0517.pdf).

Tables at an absolute position
com.lowagie.text.Table is a rather simple class that generates tables in a standard way, but sometimes you want a table to have some specific behaviour. In those cases you will need to use the more complex class com.lowagie.text.pdf.PdfPTable. Example 18 (Chap0518.pdf) is a very simple example. In Chapter 10 and Chapter 12 some more complex examples will follow.



[Top] [Previous] [TOC] [Next] [PDF]
Page Updated: $Date: 2004/02/07 10:48:06 $
Copyright © 2000, 2001 by Bruno Lowagie
Adolf Baeyensstraat 121, 9040 Gent, BELGIUM,
tel +00 32 92 28 10 97 mailto:itext-questions@lists.sourceforge.net