概述 | 第 1 页(共7 页) |
既然您已经了解了定义打印页面外观的基本元素,现在让我们研究其它 XSL-FO 元素,这些元素可以使 PDF 文档看上去更专业。本章将讨论下列主题:
- 定义多页布局
- 添加页眉和页脚
- 对页面编号
- 用“Page x of y”样式对页面编号
用 XSL-FO 词汇表添加这些特性会比较简单。XSL-FO 元素是专门为上述的大多数任务设计的,FOP 工具为其余任务提供了一些扩展元素。
多页布局 | 第 2 页(共7 页) |
本教程的第一个 XSL-FO 示例文档定义了单页布局。您往往希望文档的不同章节有不同的页面布局。例如,页号通常出现在页面底部,对于偶数页,出现在左边;对于奇数页,出现在右边。页眉通常不会在某一节的第一页上出现,但它们确实常常出现在该章节随后的页面上。
要处理文档基本布局上的这些变化,可以定义几个页面布局,然后描述每个布局的内容。下面是一个较复杂的 <fo:layout-master-set>
,它包含三个 <fo:simple-page-master>
元素:
<fo:layout-master-set>
<fo:simple-page-master master-name="first"
margin-right="75pt" margin-left="75pt"
page-height="11in" page-width="8.5in"
margin-bottom="25pt" margin-top="75pt">
<fo:region-body margin-bottom="50pt"/>
<fo:region-after region-name="ra-right" extent="25pt"/>
</fo:simple-page-master>
<fo:simple-page-master master-name="left"
margin-right="75pt" margin-left="75pt"
page-height="11in" page-width="8.5in"
margin-bottom="25pt" margin-top="25pt">
<fo:region-before region-name="rb-left" extent="25pt"/>
<fo:region-body margin-top="50pt" margin-bottom="50pt"/>
<fo:region-after region-name="ra-left" extent="25pt"/>
</fo:simple-page-master>
<fo:simple-page-master master-name="right"
margin-right="75pt" margin-left="75pt"
page-height="11in" page-width="8.5in"
margin-bottom="25pt" margin-top="25pt">
<fo:region-before region-name="rb-right" extent="25pt"/>
<fo:region-body margin-top="50pt" margin-bottom="50pt"/>
<fo:region-after region-name="ra-right" extent="25pt"/>
</fo:simple-page-master>
该代码样本定义了三个名称分别为 first
、left
和 right
的 <fo:simple-page-master>
。这些页面布局分别控制每章的第一页、左侧页面(偶数页)和右侧页面(奇数页)。
还请注意:代码将特定名称指定给页面布局的<fo:region-before>
和 <fo:region-after>
区域。您需要给这些区域起不同的名称,因为它们将有不同的内容。最后要说明的是:代码没有为第一页布局定义 <fo:region-before>
,因为在章节标题之前不出现页眉。
页面布局序列 | 第 3 页(共7 页) |
一旦定义了所有您需要的 <fo:simple-page-layout>
,那么如何使用它们呢?答案在于 <fo:conditional-page-master-reference>
元素。下面是完整的 XSL-FO 结构,它用于定义一个页面布局序列:
<fo:page-sequence-master master-name="standard">
<fo:repeatable-page-master-alternatives>
<fo:conditional-page-master-reference
master-reference="first" page-position="first"/>
<fo:conditional-page-master-reference
master-reference="left" odd-or-even="even"/>
<fo:conditional-page-master-reference
master-reference="right" odd-or-even="odd"/>
</fo:repeatable-page-master-alternatives>
</fo:page-sequence-master>
</fo:layout-master-set>
该示例定义一个名为 standard
的页面布局序列。它将名为 first
的页面布局用于第一页,将名为 left
的布局用于所有偶数页,将名为 right
的布局用于所有奇数页。(请注意:<fo:page-sequence-master>
与所有 <fo:simple-page-master>
一起出现在 <fo:layout-master-set>
元素内部。)
一旦定义了所有页面布局及何时使用它们后,可以使用<fo:page-sequence>
元素来着手编写文档内容。下面是一个简单的(不太有用)<fo:page-sequence>
元素:
<fo:page-sequence master-reference="standard">
<fo:flow flow-name="xsl-region-body">
...
</fo:flow>
</fo:page-sequence>
这不太有用,因为它对不同的页面布局不起任何作用。为了真正使 <fo:page-sequence>
能让 PDF 文件具有一个专业的外观,需要创建不同的页眉和页脚。
页眉和页脚 | 第 4 页(共7 页) |
在先前对 <fo:region-body>
元素的描述(请参阅“XSL Formatting Objects basics”教程的“XSL-FO document function and structure”一节中的“<fo:region-body> 元素”)中,您学习了页面的五个区域。您已经了解了下面定义页面主区域内容的元素:
<fo:flow flow-name="xsl-region-body">
...
</fo:flow>
当使用 <fo:flow>
元素,而且 flow-name
为 xsl-region-body
时,您告诉显示引擎:<fo:flow>
元素内的所有内容都是页面主体。要在页面上创建浮于文本主体上下的页眉和页脚,可以使用 <fo:static-content>
元素,flow-name
分别为 xsl-region-before
和xsl-region-after
。
当然,这里的问题是这些名称是所有页面布局的通用区域名称。以前,当示例定义了所有 <fo:simple-page-layout>
时,它定义了四个不同的区域名称:
ra-left
,用于左侧页面的region-above
rb-left
,用于左侧页面的region-below
ra-right
,用于右侧页面的region-above
rb-right
,同时用于右侧页面和第一页的region-below
请注意:该示例对右侧页面和第一页的 region-below
使用了相同的区域名称。因为那些区域的布局是相同的,所以不必给它们起不同的名称。
一旦定义了您所需要的页面区域,就可以定义这些区域中的内容了。为此使用 <fo:static-content>
元素。下面是用于其中两个区域(总共四个)的 <fo:static-content>
元素:
<fo:static-content flow-name="ra-right">
<fo:table font-size="10pt" text-align-last="end">
<fo:table-column column-width="350pt"/>
<fo:table-column column-width="75pt"/>
<fo:table-body>
<fo:table-row>
<fo:table-cell>
<fo:block text-align="start">
XSL Formatting Objects
</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block text-align="end">Page
<fo:page-number/></fo:block>
</fo:table-cell>
</fo:table-row>
</fo:table-body>
</fo:table>
</fo:static-content>
<fo:static-content flow-name="rb-right">
<fo:table font-size="10pt" text-align-last="end">
<fo:table-column column-width="350pt"/>
<fo:table-column column-width="75pt"/>
<fo:table-body>
<fo:table-row>
<fo:table-cell>
<fo:block text-align="end">
Presented by your friends at developerWorks
</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block text-align="start" font-weight="bold"
font-family="monospace">
ibm.com/developerWorks
</fo:block>
</fo:table-cell>
</fo:table-row>
</fo:table-body>
</fo:table>
</fo:static-content>
在这些区域中,表与文本对齐;第一个单元格是左对齐,而第二个单元格是右对齐。从理论上讲,在没有表的情况下也可以对齐文本(例如,使用 <fo:leader>
),但我还不能使 FOP 和对齐功能一起使用。虽然它可能不太雅观,但该示例仍可以工作,这就是我们在 developerWorks 上所使用的。
您可以已经在页眉和页脚中注意到:示例代码在页脚文本(区域名为 生成的文本类似于: 请注意:该示例将静态文本与 该代码告诉格式化引擎:应该将页面编号为 |
更改第一页编号 | 第 6 页(共7 页) |
在某些情况下,您可能需要更改某一节的起始页号。XSL-FO 提供了 <fo:page-sequence>
元素的 initial-page-number
特性,尽管这还没有人所共知。它类似于:
<fo:page-sequence master-reference="standard"
initial-page-number="57"/>
该标记使编号页面从 57
开始。只要使用<fo:page-number>
或 <page-number-citation>
元素,那些值就将从 57
开始。
“Page x of y”的编号样式 | 第 7 页(共7 页) |
对页面进行编号的常规方法是“Page 3 of 47”
样式。当您不知道文档共有多少页时,您如何做到这种样式呢?答案是将带 id
的格式化对象放在 <fo:flow>
区域的末尾。然后,对出现在文档最后一页的标号块执行 <fo:page-number-citation>
。标记类似于:
<fo:flow flow-name="xsl-region-body">
... Lots and lots of content here
<fo:block id="TheVeryLastPage"> </fo:block>
</fo:flow>
代码创建 id
为 TheVeryLastPage
(任何人都不太可能使用的一个值)的块,现在可以引用该 id
来获得文档最后一页的页号。<fo:static-content>
区域中的内容应该类似于:
<fo:block text-align="end">
Page <fo:page-number/> of
<fo:page-number-citation
ref-id="TheVeryLastPage"/>
</fo:block>
当 FOP 格式化该标记时,它会生成类似“Page 4 of 28”
的内容。