XSL-FO 页面体系最全实战总结(2025 年仍天天被用)
XSL-FO 里「页面」完全由三大层结构决定,记住这张图你就通杀 99% 的排版需求:
fo:layout-master-set ← 定义所有页面模板(像模具)
├─ fo:simple-page-master ← 最常用:单面模板(A4、Letter)
├─ fo:page-sequence-master ← 高级:奇偶页、封面+正文、章节模板自动切换
└─ fo:repeatable-page-master-alternatives ← 条件模板
fo:page-sequence ← 真正生成页面时使用哪个模具
master-reference="xxx" ← 指向上面的模板
1. 99% 项目够用的 4 种页面模式(直接复制)
| 模式 | 代码片段(直接粘进去就能用) | 典型场景 |
|---|---|---|
| ① 普通单面(发票、报表) | <fo:simple-page-master master-name="A4" page-width="210mm" page-height="297mm" margin="20mm"> | 增值税发票、对账单、合同 |
| ② 封面页 + 正文页(不同页眉页脚) | 两个 page-sequence 分别引用不同 master-name | 报告、投标书、说明书 |
| ③ 图书双面(奇偶页镜像) | 用 page-sequence-master + odd/even 自动切换 | 书籍、期刊、手册 |
| ④ 每章重新从第 1 页开始 | 每个章节一个 page-sequence,设置 initial-page-number=”1″ force-page-count=”even” | 技术文档、财务报表合集 |
2. 完整实战模板(2025 年最常用 4 套,直接复制)
模板① 普通单面(发票、报表首选)
<fo:layout-master-set>
<fo:simple-page-master master-name="normal" page-width="210mm" page-height="297mm"
margin-top="20mm" margin-bottom="20mm" margin-left="15mm" margin-right="15mm">
<fo:region-body margin-top="15mm" margin-bottom="15mm"/>
<fo:region-before extent="12mm"/>
<fo:region-after extent="10mm"/>
</fo:simple-page-master>
</fo:layout-master-set>
模板② 封面页无页眉页脚 + 正文页有页眉页脚
<fo:layout-master-set>
<!-- 封面模板 -->
<fo:simple-page-master master-name="cover" page-width="210mm" page-height="297mm" margin="20mm">
<fo:region-body/>
<!-- 故意不定义 before/after -->
</fo:simple-page-master>
<!-- 正文模板 -->
<fo:simple-page-master master-name="content" page-width="210mm" page-height="297mm" margin="20mm">
<fo:region-body margin-top="20mm" margin-bottom="20mm"/>
<fo:region-before extent="15mm"/>
<fo:region-after extent="12mm"/>
</fo:simple-page-master>
</fo:layout-master-set>
<!-- 使用时 -->
<fo:page-sequence master-reference="cover"> ……封面内容…… </fo:page-sequence>
<fo:page-sequence master-reference="content"> ……正文内容…… </fo:page-sequence>
模板③ 图书奇偶页镜像(最经典双面排版)
<fo:layout-master-set>
<fo:page-sequence-master master-name="book">
<fo:repeatable-page-master-alternatives>
<fo:conditional-page-master-reference master-reference="odd-page" odd-or-even="odd"/>
<fo:conditional-page-master-reference master-reference="even-page" odd-or-even="even"/>
<fo:conditional-page-master-reference master-reference="odd-page" page-position="first"/> <!-- 第一页强制用奇数页 -->
</fo:repeatable-page-master-alternatives>
</fo:page-sequence-master>
<!-- 奇数页(右页) -->
<fo:simple-page-master master-name="odd-page" page-width="210mm" page-height="297mm"
margin-top="20mm" margin-bottom="20mm" margin-left="25mm" margin-right="15mm">
<fo:region-body margin-top="15mm" margin-bottom="15mm"/>
<fo:region-before extent="12mm" display-align="after"/>
<fo:region-after extent="10mm"/>
</fo:simple-page-master>
<!-- 偶数页(左页) -->
<fo:simple-page-master master-name="even-page" page-width="210mm" page-height="297mm"
margin-top="20mm" margin-bottom="20mm" margin-left="15mm" margin-right="25mm">
<fo:region-body margin-top="15mm" margin-bottom="15mm"/>
<fo:region-before extent="12mm" display-align="after"/>
<fo:region-after extent="10mm"/>
</fo:simple-page-master>
</fo:layout-master-set>
<!-- 使用超级简单 -->
<fo:page-sequence master-reference="book">
……整本书内容只用一个 page-sequence 就行……
</fo:page-sequence>
模板④ 每章强制新开奇数页、重新从 1 开始编号
<!-- 在每个章节的 page-sequence 加上这两句 -->
<fo:page-sequence master-reference="book"
initial-page-number="1"
force-page-count="even"> <!-- 强制本章结束在偶数页,下一章自然从奇数页开始 -->
……章节内容……
</fo:page-sequence>
3. 页面控制终极技巧表(血泪总结)
| 需求 | 关键属性或写法 |
|---|---|
| 本页强制新起一页 | <fo:block break-before="page"/> |
| 本块不能被分页拆开 | keep-together.within-page="always" |
| 表格跨页时自动重复表头 | 把表头写在 <fo:table-header> 里 |
| 最后一页强制为空白页 | force-page-count="even" 或 "end-on-even" |
| 控制总页码为偶数(印刷要求) | 在最后一个 page-sequence 加 force-page-count="even" |
| 第一页页码从 1 开始(而不是继承) | initial-page-number="1" |
| 罗马数字页码 + 阿拉伯数字切换 | 前言用 roman,章节用 arabic(两个 page-sequence) |
一句话总结
简单项目:一个 simple-page-master + 一个 page-sequence 就够了
复杂项目:page-sequence-master + odd/even + 多个 page-sequence 组合
需要我直接发你一套完整可运行的「增值税发票」「银行对账单」「双面图书」三种页面模板吗?30 秒就能出 PDF,说一声就发。