XSL-FO 区域(Region)最全实用总结
(2025 年仍在每天被银行、保险、发票系统大量使用的核心知识)
XSL-FO 把每一页分为最多 5 个固定区域,像一个五宫格:
┌────────────────────┐
│ region-before │ ← 页眉
│ (xsl-region-before)│
┌────────────────┼────────────────────┼────────────────┐
│ │ │ │
│ region-start │ region-body │ region-end │ ← 左中右三栏(很少用)
│ (左栏/侧边栏) │ (正文主要区域) │ (右栏/侧边栏) │
└────────────────┼────────────────────┼────────────────┘
│ region-after │ ← 页脚
│ (xsl-region-after) │
└────────────────────┘
1. 五个区域的正式名称和对应 flow-name
| 区域名称 | 标准 flow-name(必须写成对出现) | 中文俗称 | 典型用途 |
|---|---|---|---|
| region-before | xsl-region-before | 页眉 | 标题、章节名、logo、机密水印 |
| region-after | xsl-region-after | 页脚 | 页码、共X页、公司信息、审批表 |
| region-start | xsl-region-start | 左侧边栏 | 书籍的眉批、边注、奇数页装订边 |
| region-end | xsl-region-end | 右侧边栏 | 偶数页装订边、注释 |
| region-body | xsl-region-body | 正文区 | 放正文、表格、图片等所有流动内容 |
注意:99% 的项目只用 before + body + after 三个就够了。
2. 经典 A4 页面区域定义(最常用模板,直接复制)
<fo:layout-master-set>
<fo:simple-page-master master-name="A4" page-width="210mm" page-height="297mm"
margin-top="20mm" margin-bottom="25mm"
margin-left="20mm" margin-right="20mm">
<!-- 正文区(会自动根据页眉页脚缩小) -->
<fo:region-body
margin-top="15mm"
margin-bottom="15mm"
background-color="#fdfdfd"/>
<!-- 页眉 -->
<fo:region-before
extent="12mm" <!-- 页眉高度 -->
precedence="true"
display-align="before"/>
<!-- 页脚 -->
<fo:region-after
extent="10mm" <!-- 页脚高度 -->
precedence="true"
display-align="after"/>
<!-- 如果你真的需要左右侧栏(极少用) -->
<!--
<fo:region-start extent="15mm"/>
<fo:region-end extent="15mm"/>
/>
-->
</fo:simple-page-master>
</fo:layout-master-set>
3. 内容如何放进对应区域?
<fo:page-sequence master-reference="A4">
<!-- 页眉内容(每页重复) -->
<fo:static-content flow-name="xsl-region-before">
<fo:block font-size="10pt" text-align="center" border-bottom="0.5pt solid #ccc" padding-bottom="3mm">
2025年度增值税专用发票
</fo:block>
</fo:static-content>
<!-- 页脚内容(每页重复) -->
<fo:static-content flow-name="xsl-region-after">
<fo:block font-size="9pt" text-align="center">
第 <fo:page-number/> 页 共 <fo:page-number-citation-last ref-id="lastpage"/> 页
</fo:block>
</fo:static-content>
<!-- 正文内容(只会放进 body) -->
<fo:flow flow-name="xsl-region-body">
<fo:block id="lastpage"> <!-- 给最后一页标记,供页脚引用 -->
……你的发票正文、表格、签名区……
</fo:block>
</fo:flow>
</fo:page-sequence>
4. 实战技巧(踩坑合集)
| 需求 | 正确做法 |
|---|---|
| 页眉左中右三部分 | 用 fo:table 或 fo:block-container 做三列布局 |
| 第一页页眉不同(封面页不要页眉) | 用两个 page-sequence + 不同 master-name |
| 奇偶页页眉页脚镜像 | 用 fo:page-sequence-master + odd/even 子模板 |
| 正文区背景图/水印 | 在 fo:region-body 上放 background-image |
| 页脚要放审批表(横线+签名) | 用 fo:table 画线,absolute-position 定位也很常用 |
| 防止正文内容跑到页眉页脚里 | 给 region-body 加大 margin-top/bottom 或者减小 extent |
5. 奇偶页不同区域布局(常见于书刊)
<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:repeatable-page-master-alternatives>
</fo:page-sequence-master>
一句话总结:
region-body 放正文,region-before/after 放页眉页脚,99% 的业务只用这三个区域就够了。掌握上面这段代码,你已经干掉了国内 95% 的 XSL-FO 项目里关于区域的所有需求。
需要我直接给你一套「增值税发票」「对账单」「图书排版」三种经典区域模板吗?说一声就发。