Tables are described in XSL-FO using fo:table element. A table can have a header (fo:tableheader), a body (fo:table-body) and a footer (fo:table-footer).
Each of these groups contain rows (fo:table-row), which in turn contain cells (fo:table-cell).
The columns are described using fo:table-column elements.
...
<fo:table border-collapse="collapse" font-size="14pt" font-family="Arial"> (1)
<fo:table-column column-width="3in" background-color="rgb(255,246,206)"/> (2)
<fo:table-column column-width="50%"/> (3)
<fo:table-column column-width="50%"/>
<fo:table-header color="rgb(255,255,255)" background-color="rgb(125,73,2)"
font-weight="bold"> (4)
<fo:table-row>
<fo:table-cell padding="2pt" border="1pt solid black">
<fo:block>
Name
</fo:block>
</fo:table-cell>
<fo:table-cell padding="2pt" border="1pt solid black">
<fo:block>
Quantity
</fo:block>
</fo:table-cell>
<fo:table-cell padding="2pt" border="1pt solid black">
<fo:block text-align="right">
Price
</fo:block>
</fo:table-cell>
</fo:table-row>
</fo:table-header>
<fo:table-body> (5)
<fo:table-row>
<fo:table-cell padding="2pt" border="1pt solid black"> (6)
<fo:block>Cohiba red dot Corona Especiale Cigars
</fo:block>
</fo:table-cell>
<fo:table-cell padding="2pt" border="1pt solid black">
<fo:block>25</fo:block>
</fo:table-cell>
<fo:table-cell padding="2pt" border="1pt solid black"
text-align="right">
<fo:block>$226.95</fo:block>
</fo:table-cell>
</fo:table-row>
<fo:table-row>
<fo:table-cell padding="2pt" border="1pt solid black">
<fo:block>Fuente Fuente Opus X Perfecxion #4 Cigar cedar wrapped
</fo:block>
</fo:table-cell>
<fo:table-cell padding="2pt" border="1pt solid black">
<fo:block>single</fo:block>
</fo:table-cell>
<fo:table-cell padding="2pt" border="1pt solid black"
text-align="right">
<fo:block>$28.95</fo:block>
</fo:table-cell>
</fo:table-row>
<fo:table-row>
<fo:table-cell padding="2pt" border="1pt solid black">
<fo:block>Montecristo Double Corona Cigars</fo:block>
</fo:table-cell>
<fo:table-cell padding="2pt" border="1pt solid black">
<fo:block>25</fo:block>
</fo:table-cell>
<fo:table-cell padding="2pt" border="1pt solid black"
text-align="right">
<fo:block>$157.95</fo:block>
</fo:table-cell>
</fo:table-row>
</fo:table-body>
</fo:table>
The result of rendering is displayed in following figure:

Figure 17.
Things to notice:
(1) The fo:table element is defined. This table has the border-collapse attribute set to "collapse", which will cause cell borders to merge.
(2),(3) Columns can have either a fixed width or a percentual width.
(4),(5) We define table's header and body. If a page break will occurs, the headers and the footers are displayed on the next page as well.
(6) Each fo:table-cell can span multiple rows and/or columns.
The content of the cell is aligned vertically according to display-align property.
Note:
| • | By default a cell will not clip it's content. To clip the cell's content set overflow attribute to hidden. |
The next sample illustrates these attributes:
...
<fo:table border-collapse="collapse" font-size="14pt" font-family="Arial">
<fo:table-column column-width="50%"/>
<fo:table-column column-width="50%"/>
<fo:table-body>
<fo:table-row>
<fo:table-cell border="1pt solid black" height="2.4cm"
overflow="hidden" display-align="center" text-align="center">
<fo:block font-size="48pt" color="red">Clipped Cell
</fo:block>
</fo:table-cell>
<fo:table-cell border="1pt solid black" display-align="center">
<fo:block>Normal table cell.</fo:block>
</fo:table-cell>
</fo:table-row>
</fo:table-body>
</fo:table>
...
The rendering result is displayed in the next figure:

Figure 18.
This example also shows how to create fixed height rows by using height attribute.
Table Columns
As noted in the example above, a column can have a proportional width or a fixed width.
A fixed width includes length units (in, pt, cm; for example<fo:table-column column-width="3in"/>).
A proportional width is expressed via proportional-column-width function (for example <fo:table-column column-width= "proportional-column-width(20)"/>) or by using a percentage sign (<fo:table-column column-width="20%"/>).
There is a third way to specify a column width: by omitting the column-width attribute, the column will size itself automatically, depending on it's content.
A table can mix fixed, proportional and automatic columns. When a table contains only proportional columns, XF will resize them even if the sum of percentages is not 100.
For example:
<fo:table>
<fo:table-column column-width="50%"/>
<fo:table-column column-width="50%"/>
..
</fo:table>
and
<fo:table>
<fo:table-column column-width="proportional-column-width(1)"/>
<fo:table-column column-width="proportional-column-width(1)"/>
..
</fo:table>
and
<fo:table>
<fo:table-column column-width="proportional-column-width(60)"/>
<fo:table-column column-width="proportional-column-width(60)"/>
..
</fo:table>
will produce the same result.
When fixed columns are included, XF will layout first the fixed columns, then the remaining space is distributed between proportional columns, according with column-width attribute.
When a table includes automatic columns, XF will first layout the fixed columns, then it will calculate the width percentages of the automatic columns based on their contents. The automatic columns have now a percentage width, and the remaining space is distributed between these columns and the proportional columns that have a column-width attribute.
If a column is removed, if the table still have at least one proportional column, the width will be distributed. If the table had only fixed columns, the total table width will be reduced.
Indentation
Consider the following example:
...
<fo:block>
<fo:table start-indent="1in" background-color="rgb(255,255,255)">
<fo:table-column column-width="proportional-column-width(1)"
column-number="1"/>
<fo:table-column column-width="proportional-column-width(1)"
column-number="2"/>
<fo:table-body>
<fo:table-row>
<fo:table-cell>
<fo:block background-color="rgb(153,204,255)">
Cell 1 content
</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block background-color="rgb(153,204,255)">
Cell 2 content
</fo:block>
</fo:table-cell>
</fo:table-row>
</fo:table-body>
</fo:table>
</fo:block>
...
you can notice that although start-indent is specified only for fo:table, not only the table gets indented, but the child fo:block are indented as well.
start-indent is the trickiest property in the XSL-FO specs because it behaves against what most developers find normal: you would expect that the block being indented to move to the left and with it, its children (in our example, the table and it's cell).
The different behaviour is however correct, because:
| • | start-indent is an inheritable property. It is like you specify the same start indent for the cell's content. |
| • | fo:table-cell elements establish a "reference view-port area", that is, a reference point from where the indentation is calculated. |
To indent only the table, you can either:
| • | Use margin-left instead of start-indent. |
| • | Use start-indent for the table, and then use-it again for each table-cell but set it's value to 0. |