XSL-FO全称为Extensible Stylesheet Language Formatting Objects,是W3C制定的用于描述XML文档格式化输出的标准语言,它和XSLT同属于XSL规范的一部分,主要作用是定义内容在输出介质上的呈现方式,最常见的应用场景就是将XML数据转换为PDF文档。

XSL-FO的核心概念
XSL-FO的文档本身是符合XML规范的,它的核心是通过一系列格式化对象(Formatting Objects)来描述页面的结构和内容的样式,常见的核心对象包括:
fo:root:XSL-FO文档的根元素,所有其他格式化对象都需要放在这个元素内部fo:layout-master-set:定义页面模板的集合,可以设置页面的尺寸、边距、页眉页脚区域等fo:simple-page-master:单个页面模板,用来定义某一类页面的布局规则fo:flow:存放实际要输出的内容,内容会按照模板的规则自动分页排列fo:block:块级元素,类似HTML中的<div>,用来定义段落、标题等块级内容,可以设置字体、颜色、边距等样式fo:inline:行内元素,用来对块内的部分文本设置特殊样式,类似HTML中的<span>
使用XSL-FO生成PDF的准备工作
要完成XSL-FO到PDF的转换,我们需要准备两个核心内容,以及对应的转换工具:
1. 准备XML数据文件
XML文件是我们要输出的原始数据,结构可以根据业务需求自定义,比如下面是一个简单的员工信息XML:
<?xml version="1.0" encoding="UTF-8"?>
<employees>
<employee>
<id>1001</id>
<name>张三</name>
<department>技术部</department>
<salary>15000</salary>
</employee>
<employee>
<id>1002</id>
<name>李四</name>
<department>产品部</department>
<salary>12000</salary>
</employee>
</employees>
2. 编写XSL-FO样式文件
XSL-FO文件用来定义PDF的页面布局和内容的呈现样式,我们需要把XML数据和XSL-FO结合,通常可以通过XSLT先将XML转换为XSL-FO,也可以直接编写固定的XSL-FO文件。下面是一个简单的XSL-FO示例,定义了A4纸大小的页面,以及员工信息的展示样式:
<?xml version="1.0" encoding="UTF-8"?>
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
<!-- 定义A4页面的模板 -->
<fo:simple-page-master master-name="A4-page" page-height="29.7cm" page-width="21cm" margin="2cm">
<fo:region-body margin="1cm"/>
</fo:simple-page-master>
</fo:layout-master-set>
<!-- 页面序列,使用上面定义的A4模板 -->
<fo:page-sequence master-reference="A4-page">
<fo:flow flow-name="xsl-region-body">
<!-- 标题块 -->
<fo:block font-size="20pt" font-weight="bold" text-align="center" margin-bottom="20pt">
员工信息表
</fo:block>
<!-- 员工信息块,实际使用中可以通过XSLT循环读取XML数据 -->
<fo:block font-size="12pt" margin-bottom="10pt">
员工ID:1001
</fo:block>
<fo:block font-size="12pt" margin-bottom="10pt">
姓名:张三
</fo:block>
<fo:block font-size="12pt" margin-bottom="10pt">
部门:技术部
</fo:block>
<fo:block font-size="12pt" margin-bottom="10pt">
薪资:15000元
</fo:block>
</fo:flow>
</fo:page-sequence>
</fo:root>
3. 选择转换工具
目前最常用的XSL-FO转PDF的工具是Apache FOP,它是Apache基金会开源的XSL-FO处理器,支持将XSL-FO文档转换为PDF、PS等多种格式,兼容性好且使用简单。我们可以从Apache官网下载FOP的发行包,解压后就可以使用命令行或者Java API调用它完成转换。
完整转换流程演示
下面以Apache FOP为例,演示从XSL-FO生成PDF的完整步骤:
步骤1:安装Apache FOP
下载FOP的二进制包后解压到本地目录,比如解压到/opt/fop路径下,解压后的目录中会包含fop脚本(Linux/Mac)或者fop.bat脚本(Windows),以及依赖的jar包。
步骤2:使用命令行转换
如果已经有现成的XSL-FO文件(比如上面的示例保存为employee.fo),可以直接通过命令行执行转换:
# Linux/Mac系统执行 /opt/fop/fop -fo employee.fo -pdf employee.pdf # Windows系统执行 C:fopfop.bat -fo employee.fo -pdf employee.pdf
执行完成后,当前目录就会生成employee.pdf文件,打开后可以看到按照XSL-FO定义的样式排版的员工信息。
步骤3:结合XSLT动态生成XSL-FO
实际业务中XML数据通常是动态的,我们可以先编写XSLT文件,将XML转换为XSL-FO,再通过FOP转换。下面是一个简单的XSLT示例,将员工XML转换为XSL-FO:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:output method="xml" encoding="UTF-8"/>
<xsl:template match="/">
<fo:root>
<fo:layout-master-set>
<fo:simple-page-master master-name="A4-page" page-height="29.7cm" page-width="21cm" margin="2cm">
<fo:region-body margin="1cm"/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="A4-page">
<fo:flow flow-name="xsl-region-body">
<fo:block font-size="20pt" font-weight="bold" text-align="center" margin-bottom="20pt">
员工信息表
</fo:block>
<xsl:for-each select="employees/employee">
<fo:block font-size="12pt" margin-bottom="10pt">
员工ID:<xsl:value-of select="id"/>
</fo:block>
<fo:block font-size="12pt" margin-bottom="10pt">
姓名:<xsl:value-of select="name"/>
</fo:block>
<fo:block font-size="12pt" margin-bottom="10pt">
部门:<xsl:value-of select="department"/>
</fo:block>
<fo:block font-size="12pt" margin-bottom="20pt">
薪资:<xsl:value-of select="salary"/>元
</fo:block>
</xsl:for-each>
</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:template>
</xsl:stylesheet>
保存为employee.xsl后,可以通过FOP一次性完成XML到PDF的转换:
# 直接通过XSLT转换XML并生成PDF /opt/fop/fop -xml employee.xml -xsl employee.xsl -pdf employee.pdf
使用注意事项
- XSL-FO的语法要求非常严格,必须符合XML的规范,所有标签都需要正确闭合,属性值需要用引号包裹,否则转换时会报错
- 中文字体支持需要额外配置,Apache FOP默认不支持中文字体,需要在FOP的配置文件中指定中文字体文件路径,否则中文会显示为乱码或者空白
- 复杂的排版需求比如表格、图片、页眉页脚等都可以通过对应的XSL-FO对象实现,但是语法相对繁琐,需要参考官方规范逐步调试
- 如果业务场景只是简单的PDF生成,也可以考虑其他更轻量的方案,XSL-FO更适合需要严格遵循排版规范、基于XML结构化数据的PDF生成场景
XSL-FOPDF生成XML转换Apache_FOP修改时间:2026-07-14 20:42:46