XSL-FO 流

XSL-FO「流」(flow & static-content)最完整实战讲解

(2025 年仍在银行、发票、图书排版里天天被用到的核心机制)

XSL-FO 里所有内容必须放在「流」里,分为两大类:

类型元素名称放哪里?每页是否重复?典型内容
流动内容(Flow)<fo:flow>只能流向 region-body不重复,一次性排完正文、表格、图片、段落
固定内容(Static)<fo:static-content>流向 region-before/after/start/end每页都重复页眉、页脚、边注、背景水印

记住一句话:
正文用 flow,页眉页脚用 static-content,缺一不可!

1. 标准完整结构(直接复制的母版)

<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
  <fo:layout-master-set>
    <fo:simple-page-master master-name="A4" page-height="297mm" page-width="210mm"
                           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="A4">

    <!-- 固定内容:页眉(每页都出现) -->
    <fo:static-content flow-name="xsl-region-before">
      <fo:block font-size="10pt" text-align="center" border-bottom="0.5pt solid #999">
        ××公司 2025 年度增值税专用发票
      </fo:block>
    </fo:static-content>

    <!-- 固定内容:页脚(每页都出现) -->
    <fo:static-content flow-name="xsl-region-after">
      <fo:block font-size="9pt" text-align="center" color="#666">
        第 <fo:page-number/> 页 共 <fo:page-number-citation-last ref-id="LAST"/> 页
      </fo:block>
    </fo:static-content>

    <!-- 流动内容:正文(只出现一次,从上往下排) -->
    <fo:flow flow-name="xsl-region-body">
      <fo:block font-size="18pt" font-weight="bold" text-align="center" space-after="20pt">
        增值税专用发票
      </fo:block>

      <!-- 你的所有表格、段落、图片都放在这里 -->
      <fo:block id="LAST">   <!-- 标记最后一页,供页脚引用 -->
        ……发票明细表格、金额大写、收款人、复核人……
      </fo:block>
    </fo:flow>

  </fo:page-sequence>
</fo:root>

2. 常见流组合(99% 项目都属于下面这几种)

场景需要哪些流?说明
普通报表、发票1 个 flow + 2 个 static-content最常见
图书、长报告(奇偶页不同)1 个 flow + 4 个 static-content(奇偶各一套)用 page-sequence-master 切换
封面页不要页眉页脚第1个 page-sequence 只有 flow
第2个开始加 static-content
两组 page-sequence
每章单独重新页码每个章节一个 page-sequence,各自带 static-contentinitial-page-number=”1″
背景水印(“机密”“作废”)用 region-before 放 absolute-position 的 block固定内容里也可以做水印

3. 实战技巧(血泪经验)

需求正确做法
页码显示“第 2 页 共 10 页”在最后一个 block 上加 id=”LAST”,然后页脚用 <fo:page-number-citation-last ref-id="LAST"/>
第一页不显示页眉页脚用两个 page-sequence:第一个只有 flow,第二个加 static-content
正文内容太多,自动分页完全自动!flow 会自动流向 region-body,排满一页就自动新开一页
想在页脚放大表格(审批签字表)仍然用 static-content + fo:table + absolute-position 定位
奇数页页眉居左,偶数页居右用 fo:page-sequence-master + conditional-page-master-reference 做奇偶模板

4. 最小可运行例子(30 秒出 PDF)

<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
  <fo:layout-master-set>
    <fo:simple-page-master master-name="p" page-height="297mm" page-width="210mm" margin="20mm">
      <fo:region-body/>
      <fo:region-before extent="10mm"/>
      <fo:region-after extent="10mm"/>
    </fo:simple-page-master>
  </fo:layout-master-set>

  <fo:page-sequence master-reference="p">
    <fo:static-content flow-name="xsl-region-before">
      <fo:block text-align="center">我的测试文档 - 页眉</fo:block>
    </fo:static-content>
    <fo:static-content flow-name="xsl-region-after">
      <fo:block text-align="center">第 <fo:page-number/> 页</fo:block>
    </fo:static-content>
    <fo:flow flow-name="xsl-region-body">
      <fo:block font-size="16pt" space-after="10mm">Hello XSL-FO 流机制!</fo:block>
      <!-- 重复 200 次就会自动分页 -->
      <fo:block>这是一段测试文字。</fo:block>
      <!-- ... 复制很多行 ... -->
    </fo:flow>
  </fo:page-sequence>
</fo:root>

一句话总结:
一个 page-sequence 里只能有 1 个 <fo:flow>(正文) + 0~多个 <fo:static-content>(页眉页脚),flow 负责内容,static-content 负责每页重复的东西

需要我给你「发票」「对账单」「图书双面」三种经典流模板吗?说一声就发。

文章已创建 2838

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部