Contents | < Absolute Positioning | Lists >

Tables

Tables are described in XSL-FO using fo:table element. A table can have a header (fo:table- header), 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="12pt" font-family="Arial"Œ 
       font-style="italic">
    <fo:table-column column-width="3in" background-color="rgb(255,246,206)"/ >
    <fo:table-column column-width="50%"/ >Ž
    <fo:table-column column-width="50%"/>
    <fo:table-header  color="rgb(255,255,255)" background-color="rgb(125,73,2)" 
                        font-weight="bold">
        <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>Price</fo:block>
            </fo:table-cell>
        </fo:table-row>
    </fo:table-header>
    <fo:table-body >
        <fo:table-row>
            <fo:table-cell padding="2pt" border="1pt solid black">
                <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">
                <fo:block>$226.95</fo:block>
            </fo:table-cell>
        </fo:table-row>
        <fo:table-row>
            <fo:table-cell padding="2pt" border="1pt solid black" 
                              number-rows-spanned="2" >
                <fo:block>Fuente Fuente Opus X</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">
                <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>25</fo:block>
            </fo:table-cell>
            <fo:table-cell padding="2pt" border="1pt solid black">
                <fo:block>$699.95</fo:block>
            </fo:table-cell>
        </fo:table-row>
        ...
    </fo:table-body>
</fo:table>
For the complete source code for this code example see "Tutorial/Table.fo" located under XML Documents Samples/Tutorial folder.

Figure 1

Things to notice:

Œ The fo:table element is defined. This table has the border-collapse attribute set to "collapse", which will cause cell borders to merge.

Columns can have either a fixed width (column ) or a percentual width (column Ž).

 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.

 Each fo:table-cell can span multiple rows and/or columns.


The content of the cell is aligned vertically according to display-align property.

Please note, that 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" display-align="center" 
                               height="2.4cm"  overflow="hidden" > Œ
                <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>
For the complete source code for this code example see "Tutorial/Table Cell Clip.fo" located under XML Documents Samples/Tutorial folder.

The rendering result is displayed in the next figure.

Figure 2

This example also shows how to create fixed height rows by using height attribute (cell Œ).

Table Columns

As noted in the example above, a column can have a proportional width or a fixed width.

A fixed width includes the 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 background-color="rgb(225,225,225)">
    <fo:table start-indent="1in" background-color="white">
        <fo:table-column column-width="50%"/>
        <fo:table-column column-width="50%"/>
        <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>

		

The rendering result is presented in the following figure:

Figure 3

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, it's children (in out example, the table and it's cell).


The different behaviour is however correct, because:


To indent only the table, you can either:

 

Contents | < Absolute Positioning | Lists >