XSL-FO 教程
XSL-FO 教程
XSL-FO(XSL Formatting Objects,XSL 格式化对象)是 W3C 制定的 XML 文档格式化标准,用于将 XML 内容转换为 PDF、打印文档等物理格式。它是 XSL 家族的第二个语言(第一个是 XSLT 转换语言)。
XSL 家族
| 语言 | 作用 |
|---|---|
| XSLT | 将 XML 转换为其他格式(XML/HTML/文本) |
| XPath | 在 XML 中导航与查询节点 |
| XSL-FO | 将 XML 格式化为 PDF/打印文档 |
工作原理
XML 文档 ↓ XSLT 转换 XSL-FO 文档 ↓ FO 处理器(如 Apache FOP) PDF / 打印输出
XSL-FO 能做什么
- 生成分页的 PDF 文档
- 精确控制页面布局(页眉页脚、页码)
- 格式化表格、列表、图文混排
- 支持字体、颜色、边框等排版属性
第一个 XSL-FO 文档
<?xml version="1.0" encoding="UTF-8"?>
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
<fo:simple-page-master master-name="page">
<fo:region-body/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="page">
<fo:flow flow-name="xsl-region-body">
<fo:block>Hello XSL-FO!</fo:block>
</fo:flow>
</fo:page-sequence>
</fo:root>
XSLFO 简介
XSLFO 简介
1. 什么是 XSL-FO
XSL-FO 是一种基于 XML 的标记语言,描述文档应该如何打印和显示。它定义了格式化对象的集合,每个对象对应文档的一个元素(页面、块、表格等)。
2. 历史背景
- 1998 年 W3C 开始制定 XSL 规范
- 2001 年发布 XSL 1.0 推荐标准(含 XSLT 与 XSL-FO)
- 2012 年发布 XSL-FO 2.0 草案
- Apache FOP、Antenna House、RenderX 是主要实现
3. 核心概念
- 格式化对象(FO):描述输出的 XML 元素,前缀
fo: - 页面主控:定义页面尺寸、边距、页眉页脚区域
- 页序列:一组连续页面,应用相同主控
- 内容流:实际内容被分配到页面区域
4. 典型流程
# 数据(XML) <book><title>XSL-FO 入门</title></book> # 样式(XSLT 生成 FO) <fo:block><xsl:value-of select="title"/></fo:block> # 处理(FOP) fop -xml book.xml -xsl style.xsl -pdf book.pdf
5. 与其他技术对比
| 技术 | 用途 |
|---|---|
| CSS + HTML | Web 屏幕显示 |
| XSL-FO | PDF 与打印(分页排版) |
| LaTeX | 学术论文排版 |
| PDF 直接生成 | 程序化控制(如 iText) |
XSLFO 文档
XSLFO 文档
1. 文档结构
<?xml version="1.0" encoding="UTF-8"?>
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<!-- 1. 页面布局定义 -->
<fo:layout-master-set>
<fo:simple-page-master master-name="A4">
<fo:region-body margin="2cm"/>
</fo:simple-page-master>
</fo:layout-master-set>
<!-- 2. 页面序列(内容) -->
<fo:page-sequence master-reference="A4">
<fo:flow flow-name="xsl-region-body">
<fo:block>内容</fo:block>
</fo:flow>
</fo:page-sequence>
</fo:root>
2. 文档组成元素
- fo:root:文档根元素
- fo:layout-master-set:包含所有页面主控定义
- fo:page-sequence:一个文档由多个页序列组成
- fo:flow:页序列内的内容流
- fo:block:块级元素(段落、标题等)
- fo:inline:行内元素
3. 命名空间
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> <!-- 所有格式化对象必须使用 fo: 前缀 -->
4. 简单完整示例
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
<fo:simple-page-master master-name="main"
page-width="21cm" page-height="29.7cm">
<fo:region-body margin="2.5cm"/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="main">
<fo:flow flow-name="xsl-region-body">
<fo:block font-size="24pt" text-align="center">
报告标题
</fo:block>
<fo:block space-before="12pt">
第一段正文内容...
</fo:block>
</fo:flow>
</fo:page-sequence>
</fo:root>
XSLFO 区域
XSLFO 区域
1. 页面区域模型
XSL-FO 的每个页面被划分为几个区域:
┌─────────────────────────────┐ │ region-before(页眉) │ ├─────────────────────────────┤ │ region-start │ region-body │ region-end │ (左页边) │ (主体内容) │ (右页边) ├─────────────────────────────┤ │ region-after(页脚) │ └─────────────────────────────┘
2. 定义区域
<fo:simple-page-master master-name="report"
page-width="21cm" page-height="29.7cm">
<!-- 主体区域(正文) -->
<fo:region-body margin="2cm 1.5cm 2cm 1.5cm"/>
<!-- 页眉区域(上方) -->
<fo:region-before extent="1.5cm">
<fo:block text-align="end">公司内部资料</fo:block>
</fo:region-before>
<!-- 页脚区域(下方) -->
<fo:region-after extent="1cm">
<fo:block text-align="center">第 X 页</fo:block>
</fo:region-after>
</fo:simple-page-master>
3. flow-name 对应关系
| 区域 | flow-name |
|---|---|
| 主体 | xsl-region-body |
| 页眉 | xsl-region-before |
| 页脚 | xsl-region-after |
| 左侧 | xsl-region-start |
| 右侧 | xsl-region-end |
4. 向区域填充内容
<fo:page-sequence master-reference="report">
<!-- 页脚内容 -->
<fo:static-content flow-name="xsl-region-after">
<fo:block>
第 <fo:page-number/> 页,共 <fo:page-number-citation ref-id="last"/> 页
</fo:block>
</fo:static-content>
<!-- 主体内容 -->
<fo:flow flow-name="xsl-region-body">
<fo:block>正文...</fo:block>
</fo:flow>
</fo:page-sequence>
5. 区域样式属性
<fo:region-body
margin="2cm" <!-- 边距 -->
background-color="#f5f5f5" <!-- 背景色 -->
overflow="auto"/> <!-- 溢出处理 -->
XSLFO 输出
XSLFO 输出
1. 输出格式
XSL-FO 本身是 XML,必须通过格式化处理器(FO Processor)转换为最终格式:
| 处理器 | 输出 | 说明 |
|---|---|---|
| Apache FOP | PDF、PS、PNG、TXT | 开源免费,最常用 |
| RenderX XEP | PDF、PS、SVG | 商业,支持完整规范 |
| Antenna House | PDF、SVG、XPS | 商业,东亚文字支持好 |
| ibex | 轻量商业处理器 |
2. Apache FOP 使用
# 下载 fop 后命令行转换 fop -fo report.fo -pdf report.pdf # 从 XML+XSLT 直接生成 fop -xml data.xml -xsl style.xsl -pdf report.pdf # 输出 PNG fop -fo report.fo -png report.png
3. Java 程序调用
import org.apache.fop.apps.FopFactory; import org.apache.fop.apps.Fop; import java.io.FileOutputStream; FopFactory fopFactory = FopFactory.newInstance(); Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, out); Transformer transformer = TransformerFactory.newInstance().newTransformer(new StreamSource(styleXsl)); Source src = new StreamSource(dataXml); Result res = new SAXResult(fop.getDefaultHandler()); transformer.transform(src, res);
4. 检查输出质量
- 字体嵌入:确认 PDF 字体可移植
- 分页正确:表格跨页、标题跟随
- 中文显示:配置中文字体(fop 默认不含中文字体)
5. 中文配置示例
<!-- fop.xconf 配置字体 -->
<fonts>
<font kerning="yes">
<font-triplet name="STSong" style="normal" weight="normal"/>
<font-triplet name="STSong" style="normal" weight="bold"/>
</font>
</fonts>
<!-- FO 中引用 -->
<fo:block font-family="STSong">中文内容</fo:block>
XSLFO 流
XSLFO 流
1. 什么是流(Flow)
流(fo:flow)是页序列中的内容容器,内容按顺序从流中流向页面区域,像水流一样自动分页填充。
2. 基本结构
<fo:page-sequence master-reference="main">
<!-- 静态内容(页眉页脚,不流动) -->
<fo:static-content flow-name="xsl-region-before">
<fo:block>页眉文字</fo:block>
</fo:static-content>
<!-- 流内容(自动分页) -->
<fo:flow flow-name="xsl-region-body">
<fo:block>第一页内容...</fo:block>
<fo:block>自动流动到下一页</fo:block>
</fo:flow>
</fo:page-sequence>
3. 流动与分页
<fo:flow flow-name="xsl-region-body"> <!-- 内容超过页面高度时自动分页 --> <fo:block>内容1</fo:block> <fo:block break-before="page">强制新页</fo:block> <fo:block keep-with-next.within-page="always">与下一块保持同页</fo:block> </fo:flow>
4. 分页控制属性
break-before="page" <!-- 块前分页 --> break-after="page" <!-- 块后分页 --> keep-with-next="always" <!-- 与下一个保持同页 --> keep-together="always" <!-- 块内不分页 --> orphans="2" <!-- 页首最少行数 --> widows="2" <!-- 页尾最少行数 -->
5. 流内容综合示例
<fo:flow flow-name="xsl-region-body">
<fo:block font-size="18pt" font-weight="bold"
space-after="10pt" keep-with-next.within-page="always">
第一章 概述
</fo:block>
<fo:block text-indent="2em" text-align="justify">
这是正文段落。内容足够长时会自动分页,
段落不会在中间被截断(widows/orphans 控制)。
</fo:block>
<fo:block break-before="page">
这是新的一页开始的内容。
</fo:block>
</fo:flow>
XSLFO 页面
XSLFO 页面
1. 页面主控(layout-master-set)
<fo:layout-master-set>
<!-- 单页主控 -->
<fo:simple-page-master master-name="A4-page"
page-width="210mm" page-height="297mm"
margin-top="25mm" margin-bottom="25mm"
margin-left="20mm" margin-right="20mm">
<fo:region-body margin-top="15mm"/>
</fo:simple-page-master>
<!-- 双面主控(左页/右页不同) -->
<fo:page-sequence-master master-name="book">
<fo:single-page-master-binding master-reference="right"/>
<fo:repeatable-page-master-alternatives>
<fo:conditional-page-master-reference
odd-or-even="odd" master-reference="right"/>
<fo:conditional-page-master-reference
odd-or-even="even" master-reference="left"/>
</fo:repeatable-page-master-alternatives>
</fo:page-sequence-master>
</fo:layout-master-set>
2. 页面尺寸
# 常见尺寸 A4: 210mm × 297mm A5: 148mm × 210mm Letter: 8.5in × 11in Legal: 8.5in × 14in # 自定义 page-width="10cm" page-height="15cm"
3. 使用页面主控
<!-- 用 master-reference 引用 --> <fo:page-sequence master-reference="A4-page"> ... </fo:page-sequence>
4. 页号与引用
<!-- 当前页码 --> <fo:page-number/> <!-- 引用某元素的页码 --> <fo:block id="last-page">最后一页内容</fo:block> ... 第 <fo:page-number-citation ref-id="last-page"/> 页 <!-- 总页数(常见技巧:标记末元素) --> 共 <fo:page-number-citation ref-id="last"></fo:page-number-citation> 页
5. 页面属性速查
page-width / page-height 页面尺寸 margin-top/bottom/left/right 页面边距 master-name 主控名称 flow-name 内容流名称 reference-orientation 旋转(90/180/270) page-position 页面位置(first/last/rest)
XSLFO 块
XSLFO 块
1. 块元素(fo:block)
fo:block 是 XSL-FO 中最基本的布局元素,类似 HTML 的 div/p,生成一个独立的矩形区域。
2. 基础示例
<fo:flow flow-name="xsl-region-body">
<!-- 标题 -->
<fo:block font-size="20pt" font-weight="bold"
space-before="12pt" space-after="6pt">
大标题
</fo:block>
<!-- 普通段落 -->
<fo:block font-size="10.5pt" line-height="1.5"
text-align="justify" text-indent="2em">
段落文本...
</fo:block>
<!-- 带边框背景 -->
<fo:block border="1pt solid #ccc"
padding="6pt" background-color="#f9f9f9">
提示框内容
</fo:block>
<!-- 居中 -->
<fo:block text-align="center">居中内容</fo:block>
</fo:flow>
3. 常用属性
font-family 字体 font-size 字号 font-weight bold/normal font-style italic/normal color 文字颜色 background-color 背景色 text-align start/center/end/justify text-indent 首行缩进 line-height 行高 space-before 上间距 space-after 下间距 margin-* 外边距 padding-* 内边距 border-* 边框 keep-with-next 与下块同页 keep-together 块内不分页 break-before 前分页
4. 行内元素(fo:inline)
<fo:block> 普通文字,<fo:inline font-weight="bold" color="red">加粗红字</fo:inline>, 继续普通文字,<fo:inline font-style="italic">斜体</fo:inline>。 </fo:block>
5. 列表块
<fo:list-block space-after="12pt">
<fo:list-item>
<fo:list-item-label>
<fo:block>•</fo:block>
</fo:list-item-label>
<fo:list-item-body>
<fo:block>列表项一</fo:block>
</fo:list-item-body>
</fo:list-item>
</fo:list-block>
XSLFO 列表
XSLFO 列表
1. 列表结构
<fo:list-block>
<fo:list-item>
<fo:list-item-label end-indent="label-end()">
<fo:block>1.</fo:block>
</fo:list-item-label>
<fo:list-item-body start-indent="body-start()">
<fo:block>第一项内容</fo:block>
</fo:list-item-body>
</fo:list-item>
<fo:list-item>
<fo:list-item-label end-indent="label-end()">
<fo:block>2.</fo:block>
</fo:list-item-label>
<fo:list-item-body start-indent="body-start()">
<fo:block>第二项内容</fo:block>
</fo:list-item-body>
</fo:list-item>
</fo:list-block>
2. 列表属性
<fo:list-block
start-indent="10pt" <!-- 整体缩进 -->
provisional-label-separation="6pt" <!-- 标签与内容间距 -->
provisional-distance-between-starts="1.5em"> <!-- 标签宽度 -->
...
</fo:list-block>
3. 与 XSLT 配合生成列表
<xsl:for-each select="item">
<fo:list-item>
<fo:list-item-label end-indent="label-end()">
<fo:block><xsl:value-of select="position()"/>.</fo:block>
</fo:list-item-label>
<fo:list-item-body start-indent="body-start()">
<fo:block><xsl:value-of select="."/></fo:block>
</fo:list-item-body>
</fo:list-item>
</xsl:for-each>
4. 列表样式变体
<!-- 圆点列表 --> <fo:list-item-label> <fo:block>•</fo:block> </fo:list-item-label> <!-- 数字列表 --> <fo:list-item-label> <fo:block>1.</fo:block> </fo:list-item-label> <!-- 字母列表 --> <fo:list-item-label> <fo:block>a.</fo:block> </fo:list-item-label> <!-- 术语定义列表 --> <fo:list-item-label> <fo:block font-weight="bold">术语</fo:block> </fo:list-item-label> <fo:list-item-body> <fo:block>术语定义...</fo:block> </fo:list-item-body>
5. 列表跨页处理
<fo:list-item keep-together.within-page="always"> <!-- 单个列表项不跨页 --> </fo:list-item>
XSLFO 表格
XSLFO 表格
1. 表格结构
<fo:table table-layout="fixed" width="100%">
<!-- 列定义 -->
<fo:table-column column-width="25%"/>
<fo:table-column column-width="45%"/>
<fo:table-column column-width="30%"/>
<!-- 表头 -->
<fo:table-header>
<fo:table-row>
<fo:table-cell><fo:block font-weight="bold">姓名</fo:block></fo:table-cell>
<fo:table-cell><fo:block font-weight="bold">部门</fo:block></fo:table-cell>
<fo:table-cell><fo:block font-weight="bold">工资</fo:block></fo:table-cell>
</fo:table-row>
</fo:table-header>
<!-- 表体 -->
<fo:table-body>
<fo:table-row>
<fo:table-cell><fo:block>张三</fo:block></fo:table-cell>
<fo:table-cell><fo:block>技术部</fo:block></fo:table-cell>
<fo:table-cell><fo:block>12000</fo:block></fo:table-cell>
</fo:table-row>
</fo:table-body>
</fo:table>
2. 表格属性
<fo:table
width="100%" <!-- 宽度 -->
table-layout="fixed|auto" <!-- 布局 -->
border-collapse="collapse" <!-- 边框合并 -->
border="0.5pt solid #000"> <!-- 边框 -->
<fo:table-column column-width="2cm"/>
<fo:table-column column-width="*"/> <!-- 剩余宽度 -->
<fo:table-cell number-columns-spanned="2"> <!-- 跨列 -->
<fo:table-cell number-rows-spanned="2"> <!-- 跨行 -->
<fo:table-cell padding="4pt" background-color="#eee"> <!-- 样式 -->
3. 表头跨页重复
<fo:table-header> <!-- 表格跨页时,表头自动在每页重复 --> <fo:table-row>...</fo:table-row> </fo:table-header> <!-- 行不跨页 --> <fo:table-row keep-together.within-page="always">...</fo:table-row>
4. 从 XML 生成表格(XSLT)
<xsl:for-each select="employees/employee">
<fo:table-row>
<fo:table-cell>
<fo:block><xsl:value-of select="name"/></fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block><xsl:value-of select="salary"/></fo:block>
</fo:table-cell>
</fo:table-row>
</xsl:for-each>
XSLFO & XSLT
XSLFO & XSLT
1. 二者关系
XSLT 负责转换:把 XML 转换为 XSL-FO;XSL-FO 负责格式化:把转换结果排版为 PDF/打印文档。二者配合完成"数据到文档"的完整流程。
2. 转换流程
XML(数据) + XSLT(样式表)
↓ XSLT 处理器
FO 文档(格式化对象)
↓ FO 处理器(FOP)
PDF / 打印
3. 完整示例:XML → XSLT → FO
<!-- 数据:report.xml -->
<report>
<title>季度报告</title>
<section>
<heading>销售概况</heading>
<para>本季度销售额增长 15%。</para>
</section>
</report>
<!-- 样式:report.xsl -->
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:template match="/">
<fo:root>
<fo:layout-master-set>
<fo:simple-page-master master-name="A4">
<fo:region-body margin="2cm"/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="A4">
<fo:flow flow-name="xsl-region-body">
<fo:block font-size="22pt" font-weight="bold">
<xsl:value-of select="report/title"/>
</fo:block>
<xsl:apply-templates select="report/section"/>
</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:template>
<xsl:template match="section">
<fo:block font-size="14pt" font-weight="bold" space-before="12pt">
<xsl:value-of select="heading"/>
</fo:block>
<fo:block text-indent="2em">
<xsl:value-of select="para"/>
</fo:block>
</xsl:template>
</xsl:stylesheet>
4. 常用转换模式
# 直接输出 FO 元素 <xsl:element name="fo:block">... # 条件生成 <xsl:if test="@important='true'"> <fo:block font-weight="bold">重要内容</fo:block> </xsl:if> # 循环生成表格行 <xsl:for-each select="rows/row">...</xsl:for-each>
XSLFO 软件
XSLFO 软件
1. 编辑器与工具
- XMLSpy:Altova 出品,支持 XSLT/XSL-FO 编辑调试,集成 FO 预览
- Oxygen XML Editor:跨平台 XML 工具,内置 FOP 转换
- VS Code:XML 插件 + 命令行 FOP
- Stylus Studio:XML 开发套件
2. FO 处理器
| 软件 | 类型 | 特点 |
|---|---|---|
| Apache FOP | 开源 | 跨平台,Java,支持 PDF/PNG/PS/TIF |
| RenderX XEP | 商业 | 规范覆盖率高,性能好 |
| Antenna House | 商业 | 东亚字体、SVG 支持强 |
| Altsoft Xml2PDF | 商业 | 纯 .NET 实现 |
3. Apache FOP 详解
# 下载 https://xmlgraphics.apache.org/fop/ # 目录结构 fop/ ├── fop # 启动脚本 ├── fop.xconf # 配置文件 ├── conf/ ├── lib/ # 依赖 jar └── examples/
4. FOP 命令行常用
# FO 转 PDF fop -fo input.fo -pdf output.pdf # XML+XSL 转 PDF fop -xml input.xml -xsl style.xsl -pdf output.pdf # 其他格式 fop -fo input.fo -png output.png fop -fo input.fo -txt output.txt fop -fo input.fo -ps output.ps # 使用配置文件 fop -c fop.xconf -fo input.fo -pdf output.pdf # 详细日志 fop -fo input.fo -pdf output.pdf -d
5. 常见问题
- 中文字体乱码:fop.xconf 中注册中文字体(STSong/微软雅黑)
- 图片不显示:使用
fo:external-graphic并给绝对/相对路径 - 性能:大数据量分页转换,建议流式处理
XSL-FO 对象
XSL-FO 对象
1. 对象分类
XSL-FO 对象按用途分为几大类:
| 类别 | 对象 |
|---|---|
| 文档结构 | fo:root |
| 页面布局 | fo:layout-master-set、fo:simple-page-master、fo:page-sequence-master |
| 页面内容 | fo:page-sequence、fo:flow、fo:static-content |
| 块级 | fo:block、fo:block-container、fo:list-block、fo:table |
| 行内 | fo:inline、fo:inline-container、fo:character |
| 图形 | fo:external-graphic、fo:instream-foreign-object |
| 文本相关 | fo:page-number、fo:leader、fo:basic-link |
| 表格 | fo:table、fo:table-column、fo:table-header/body/footer、fo:table-row、fo:table-cell |
2. 常用对象速查
fo:root 文档根 fo:layout-master-set 页面主控集合 fo:simple-page-master 简单页面主控 fo:page-sequence 页序列 fo:flow 内容流 fo:static-content 静态内容(页眉页脚) fo:block 块(段落/标题) fo:inline 行内元素 fo:external-graphic 外部图片 fo:page-number 页码 fo:basic-link 超链接 fo:leader 引导线(目录点线) fo:table-* 表格系列
3. 图片对象
<fo:external-graphic src="url('images/logo.png')"
content-width="5cm" content-height="2cm"/>
4. 链接对象
<fo:basic-link external-destination="url('https://example.com')">
<fo:block color="blue" text-decoration="underline">访问官网</fo:block>
</fo:basic-link>
5. 目录引导线
<fo:block> 第一章 概述 <fo:leader leader-pattern="dots" leader-length.optimum="100%"/> 第 1 页 </fo:block>
XSL-FO 简介
XSL-FO 简介
1. 定义
XSL-FO(Extensible Stylesheet Language Formatting Objects)是 W3C 推荐的用于 XML 文档格式化的标准,将结构化数据排版为适合打印和分页的格式。
2. 关键特性
- 完全基于 XML,声明式描述排版
- 面向打印:支持分页、页眉页脚、页码
- 精确控制:字体、间距、边框、对齐、颜色
- 与 XSLT 天然配合,自动化文档生成
3. 适用场景
- 企业报表、发票、合同批量生成 PDF
- 书籍、手册排版出版
- 电子发票、单据打印
- 任何"XML 数据 → PDF"的自动化需求
4. 学习门槛
相比 CSS, XSL-FO 概念更多(主控、区域、流),但模式固定、属性体系完整,掌握核心对象后即可产出专业文档。
5. 快速回顾核心流程
1. 准备 XML 数据 2. 编写 XSLT 样式表生成 FO 3. 用 FOP 等处理器输出 PDF 4. 检查分页、字体、表格排版
现在开始学习XSL-FO!
现在开始学习 XSL-FO!
1. 准备工作
- 下载 Apache FOP:xmlgraphics.apache.org/fop
- 准备一个文本编辑器(推荐 VS Code)
- 准备示例 XML 数据
2. 第一步:创建最小 FO 文档
<?xml version="1.0" encoding="UTF-8"?>
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
<fo:simple-page-master master-name="page"
page-width="21cm" page-height="29.7cm">
<fo:region-body margin="2cm"/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="page">
<fo:flow flow-name="xsl-region-body">
<fo:block font-size="16pt" font-weight="bold">
我的第一份 XSL-FO 文档
</fo:block>
</fo:flow>
</fo:page-sequence>
</fo:root>
3. 第二步:转换
fop -fo hello.fo -pdf hello.pdf # 打开 hello.pdf 查看效果
4. 第三步:用 XSLT 驱动数据
# 准备 data.xml <items> <item>苹果</item> <item>香蕉</item> </items> # 在 XSLT 中循环生成 FO <xsl:for-each select="items/item"> <fo:block>• <xsl:value-of select="."/></fo:block> </xsl:for-each>
5. 练习建议
- 生成一份带页眉页脚和页码的报表
- 生成一个跨页的表格并验证表头重复
- 生成一份目录(引导线 + 页码引用)
- 加入图片与超链接
动手实践是掌握 XSL-FO 最快的方式,开始吧!
XSL-FO 对象参考手册
XSL-FO 对象参考手册
1. 文档与页面对象
| 对象 | 说明 |
|---|---|
| fo:root | 文档根元素 |
| fo:layout-master-set | 页面主控集合 |
| fo:simple-page-master | 单页主控,定义尺寸边距区域 |
| fo:page-sequence-master | 复合页面主控(奇偶页等) |
| fo:region-body/before/after/start/end | 页面区域 |
| fo:page-sequence | 页序列 |
| fo:flow | 内容流 |
| fo:static-content | 静态内容(页眉页脚) |
2. 块与行内对象
| 对象 | 说明 |
|---|---|
| fo:block | 块级元素(段落、标题、表格单元格内容) |
| fo:block-container | 块容器(可定位/旋转) |
| fo:inline | 行内元素 |
| fo:inline-container | 行内容器 |
| fo:character | 单个字符 |
| fo:leader | 引导线 |
| fo:page-number | 当前页码 |
| fo:page-number-citation | 引用页码 |
3. 表格对象
| 对象 | 说明 |
|---|---|
| fo:table | 表格 |
| fo:table-column | 列定义 |
| fo:table-header | 表头(跨页重复) |
| fo:table-body | 表体 |
| fo:table-footer | 表尾 |
| fo:table-row | 行 |
| fo:table-cell | 单元格 |
4. 列表与链接对象
| 对象 | 说明 |
|---|---|
| fo:list-block | 列表 |
| fo:list-item | 列表项 |
| fo:list-item-label | 列表标签 |
| fo:list-item-body | 列表内容 |
| fo:basic-link | 超链接 |
| fo:external-graphic | 外部图片 |
| fo:instream-foreign-object | 内嵌对象(SVG 等) |
5. 常用属性速查
# 字体 font-family / font-size / font-weight / font-style / color # 间距 margin-* / padding-* / space-before / space-after # 边框 border / border-color / border-style / border-width # 对齐 text-align / text-indent / line-height / vertical-align # 分页 break-before / break-after / keep-with-next / keep-together # 定位 position / top / left / width / height / z-index
完整属性定义参见 W3C XSL 规范。