概述 | 第 1 页(共7 页) |
正如您想象的那样,表有可能相当复杂。XSL-FO 表标记类似于您或许已经熟悉的 HTML 中的那些标记:
XSL-FO 元素 | HTML 元素 |
---|---|
<fo:table> | <table> |
<fo:table-body> | <tbody> (未普遍使用) |
<fo:table-column> | 该信息在 HTML <table> 元素的 cols 属性中。 |
<fo:table-row> | <tr> |
<fo:table-cell> | <td> |
<fo:table-caption> | <caption> ,虽然 XSL-FO 对标题和表必须出现在源文档中的方式施加了更多限制。 |
下面几页将更仔细地研究这些元素。
基本表结构 | 第 2 页(共7 页) |
用 FOP 格式化 XSL-FO 表主要的复杂点在于:您必须指定该表中所有列的宽度。下面是典型 XSL-FO 表的示例:
<fo:table table-layout="fixed">
<fo:table-column column-width="150pt"/>
<fo:table-column column-width="150pt"/>
<fo:table-body>
<fo:table-row>
<fo:table-cell border-style="solid"
border-color="black" border-width="1pt"
padding-before="3pt" padding-after="3pt"
padding-start="3pt" padding-end="3pt">
<fo:block>Some text</fo:block>
</fo:table-cell>
<fo:table-cell border-style="solid"
border-color="black" border-width="1pt"
padding-before="3pt" padding-after="3pt"
padding-start="3pt" padding-end="3pt">
<fo:block>Some more text</fo:block>
</fo:table-cell>
</fo:table-row>
<fo:table-row>
<fo:table-cell border-style="solid"
border-color="black" border-width="1pt"
padding-before="3pt" padding-after="3pt"
padding-start="3pt" padding-end="3pt">
<fo:block>First cell, last row</fo:block>
</fo:table-cell>
<fo:table-cell border-style="solid"
border-color="black" border-width="1pt"
padding-before="3pt" padding-after="3pt"
padding-start="3pt" padding-end="3pt">
<fo:block>Last cell, last row</fo:block>
</fo:table-cell>
</fo:table-row>
</fo:table-body>
</fo:table>
虽然这看起来有点可怕,但请记住您将使用 XSLT 样式表来生成这些文档。文档顶部的两个 <fo:table-column>
元素定义了表中的两个列,每一列的宽度都是 150 个点。
次要的复杂点是:必须定义 <fo:table-cell>
元素的所有特性。遗憾的是,象 border-style
、border-color
和 padding-before
之类的特性不会被继承;必须为表中的每个单元格定义它们。
下面是该表在 PDF 文件中的样子:
基本表元素 | 第 3 页(共7 页) |
<fo:table>
元素作为 XSL-FO 中的基本表元素。该元素包含与表相关的所有其它一切信息。您可能已经注意到基本表结构中的表示例从定义table-layout="fixed"
特性开始。该特性告诉渲染引擎:表中的所有列都是静态定义的。这是 FOP 的局限性,而不是 XSL-FO 限制。因而,将来可能不需要硬编码表中所有列的宽度。
接下来,表定义有一些 <fo:table-column>
元素。再提一下,XSL-FO 不需要这些,但 FOP 需要。样本表(在基本表结构中)定义了每一列的宽度:
<fo:table-column column-width="150pt"/>
<fo:table-column column-width="150pt"/>
这两个 <fo:table-column>
元素告诉渲染引擎:表有两列,每一列的宽度为 150 个点。接下来的 <fo:table-body>
包含所有 <fo:table-row>
元素。接下来,查看 <fo:table-cell>
元素,它执行表的实际工作:
<fo:table-cell border-style="solid"
border-color="black" border-width="1pt"
padding-before="3pt" padding-after="3pt"
padding-start="3pt" padding-end="3pt">
<fo:block>Some text</fo:block>
</fo:table-cell>
该示例定义两种类型的特性:边框特性和填充特性。前三个特性 border-style
、border-color
和 border-width
定义表单元格的所有边都是黑色实线边框。可以使用许多其它特性来控制边框。XSL-FO 规范定义特性border-before-style
、border-after-style
、border-start-style
和 border-end-style
。对于 border-xxx-color
和 border-xxx-width
,存在类似的特性;有关完整的详细信息,请参阅规范。
四个填充特性定义在区域内容(在本例中是表单元格)和区域边缘之间应该留有多少空间。在上面的示例中,在内容的所有边填充了 3 个点。您可以根据需要在表单元格中设置任意数目的填充;根据我们在 developerWorks 上的经验,3 个点正合适。
可以在 <fo:table>
、<fo:table-row>
或 <fo:table-cell>
元素上指定 background-color
。如果在 <fo:table>
级别将 background-color
定义为蓝色,那么表中的所有背景都是蓝色的,除非 <fo:table-row>
或<fo:table-cell>
元素指定其它颜色。background-color
的缺省值是 transparent
。
跨多行或多列的单元格 | 第 4 页(共7 页) |
XSL-FO 规范定义了两个方便的特性 number-columns-spanned
和 number-rows-spanned
,它们允许您将单元格合并起来。<fo:table-cell>
元素的这些特性告诉格式化器:给定的单元格应该使用多少行和列。一旦定义了给定单元格占据的行数和列数,随后的 <fo:table-cell>
元素就被放在下一个可用位置。例如,如果表中有四列,并且有这些 <fo:table-cell>
元素,那么第三个 <fo:table-cell>
元素就放在表的第四列中:
<fo:table>
...
<fo:table-row>
<fo:table-cell>
...
</fo:table-cell>
<fo:table-cell number-columns-spanned="2">
...
</fo:table-cell>
<fo:table-cell>
...
</fo:table-cell>
</fo:table-row>
</fo:table>
XSL-FO 表示例中显示了使用这些特性的复杂示例的抓屏;您也可以研究 所有详细信息。
其它表元素 | 第 5 页(共7 页) |
尽管 FOP 目前不支持其它两个 XSL-FO 表元素,但我还是会向您介绍它们。<fo:table-header>
元素通常包含一个或多个 <fo:table-row>
元素,其中每个元素都依次包含一个或多个 <fo:table-cell>
元素。下面是一个样本:
<fo:table table-layout="fixed">
<table-column column-width="150pt"/>
<table-column column-width="75pt"/>
<table-column column-width="75pt"/>
<fo:table-body>
<fo:table-header>
<fo:table-row>
<fo:table-cell>
<fo:block>Month</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block>Miles flown</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block>Miles earned</fo:block>
</fo:table-cell>
</table-row>
</fo:table-header>
</fo:table-body>
</fo:table>
要获得标题行的效果,可以以某种特殊方法格式化所有<fo:table-cell>
元素;例如,可以对它们设置特殊的 background-color
并以粗体字显示其所有内容。
XSL-FO 规范还定义了 <fo:table-caption>
元素,但 FOP 目前不支持它。要使用表标题,XSL-FO 文件的结构应该如下:
<fo:table-and-caption>
<fo:table-caption>
...
</fo:table-caption>
<fo:table>
...
</fo:table>
</fo:table-and-caption>
要获得 <fo:table-caption>
元素的效果,可以在表的末尾创建另一个 <fo:table-row>
,使它的 number-columns-spanned
特性等于表中的列数。然后,可以决定如何格式化边框、背景色和其它特性以将标题与表的其余部分分开。
另一件不能在 FOP 中工作的事(至少我至今还无法解决它)是不能够在页面上移动表的起始位置。例如,您可能想使表在页面上居中。假设表有四列,每一列的宽度都是 1 英寸(72 个点),页面的左右边距都是 1 英寸宽,留出了 2-1/2 英寸的水平间距。要使表居中,需要将表缩进 1-1/4 英寸(90 个点): 遗憾的是,FOP 将这理解为表中的每个单元格都应该使其内容缩进 90 个点,显然您不想这样。要解决这一问题,只要另添一列到表中,并确保将其 必须对每一行重复该空表单元格;如果您知道表有多少行,则可以将单个 下面是使用这一技术使表在页面上右对齐和居中的 PDF 的抓屏: |
XSL-FO 表示例 | 第 7 页(共7 页) |
我将用一个样本 XSL-FO 文件结束这一章,该文件包含一些样本表。第一个表是先前在构建表中介绍的简单表;第二个表使用不同的文本对齐、背景色和边框宽度使表的外观更专业。另一个表以多种方法合并单元格,使它们跨越多个列和行,而还有一个表则更改表单元格的各种边框特性。源代码在这个文件 中;您可以查看该文件 以了解格式化对象生成的实际 PDF 文件。
下面是 PDF 文件的片段,它显示了大量使用 number-columns-spanned
和 number-rows-spanned
特性的表:
作为额外奖励,样本文件包含一个复杂的表示例,它使用边框特性、背景色和跨越多个行和列的单元格来模仿由荷兰画家 Piet Mondrian 创作的著名抽象画: