XSL-FO是什么 如何用它生成PDF

XSL-FO是W3C制定的XML排版语言,用于将结构化数据精确渲染为PDF等可打印格式;它需经XSLT转换XML为FO文件,再由FO处理器(如Apache FOP)解析布局指令生成PDF,核心依赖XML数据源、XSLT转换器和FO处理器三步协作。

XSL-FO(Extensible Stylesheet Language Formatting Objects)是一种基于XML的排版语言,由W3C制定,专门用于将结构化数据精确渲染为可打印格式,最常用的是生成PDF。它不直接处理原始XML,而是作为XSLT转换的“中间格式”:先用XSLT把XML转成FO文件(.fo),再交由FO处理器(如Apache FOP)渲染成PDF。

核心组成和工作流程

XSL-FO本身不是独立工具,而是一套声明式标记规范,依赖三步协作完成PDF生成:

  • XML数据源:提供原始内容,比如订单、发票或文档元数据,结构清晰、无样式
  • XSLT转换器:把XML按业务逻辑“翻译”成FO文件,例如把变成带页眉、表格、字体设置的
  • FO处理器:接收FO文件,解析布局指令(页边距、分栏、字体、换页控制等),输出PDF。主流选择是Apache FOP(免费开源)、Antenna House(商业,支持高级CSS混合)

快速上手一个可运行的FO文件

不需要XSLT也能试水——直接写一个最小可行FO文件(如hello.fo),用FOP命令行一键转PDF:

  • 确保已安装JDK和Apache FOP(解压后路径设为FOP_HOME
  • 创建hello.fo,内容包含必需结构:(定义A4纸张与边距)、(含正文流)
  • 关键样式可直接写在里,例如font-family="SimSun"(中文必须显式指定字体)
  • 执行命令:fop -fo hello.fo -pdf hello.pdf

中文显示和防乱码要点

生成中文PDF失败,90%出在字体环节:

  • XML/XSL/FO文件本身必须保存为UTF-8编码,且首行声明encoding="UTF-8"
  • FOP默认不带中文字体,需手动配置:fop.xconf中添加字体目录(如fonts/),并放入simsun.ttc或msyh.ttf等真实字体文件
  • FO代码中必须显式调用注册过的字体名,例如你好,不能只写sans-serif
  • 测试时先输出单个汉字,确认是否正常——避免等到整张发票排完才发现全是方框

典型应用场景和优势

它适合对排版精度要求高、内容结构固定的批量文档:

  • 电子发票、合同、对账单:表格列宽固定、金额右对齐、税额自动计算后嵌入FO
  • 政企公文输出:严格遵循红头文件格式(标题居中、仿宋_GB2312三号、段落间距28磅)
  • 多语言出版物:通过writing-mode="tb-rl"支持竖排中文,或切换lang="ja"调用日文字体
  • 相比HTML+CSS转PDF,XSL-FO对分页控制更强(如keep-with-next="always"防止标题孤行)