Apache FOP 2.11 常用 CLI 命令与工具详解

逐项实测 fop 命令行全部输入输出模式、XML+XSL 管道与 -param、PDF 加密与 PDF/A-1b、批量渲染与内存压测,含 -out list NPE 等 10 个实测 FAQ

Apache FOPFOPApache运维2026/10/14

Apache FOP 2.11 常用 CLI 命令与工具详解

一、命令行概览

fop 是单入口命令行工具,本文环境:Ubuntu 22.04.5 / OpenJDK 11.0.32.1 / Apache FOP 2.11(安装于 /opt/fop,全局软链 /usr/local/bin/fop)。fop -h 输出的用法总纲:

USAGE
fop [options] [-fo|-xml] infile [-xsl file] [-awt|-pdf|-mif|-rtf|-tiff|-png|-pcl|-ps|-txt|-at [mime]|-print] <outfile>

命令由三段构成:输入模式(-fo / -xml / -atin / -ifin / -imagein / 位置参数)、可选的 -xsl 与 -param、输出模式(-pdf / -ps / ... / -out)。另有一组脚本级选项(--help/-h、--noconfig、--execdebug)在 FOP 选项之前由启动脚本处理。

所有实测命令均在 /work 目录下执行,配置文件 /work/conf/fop-cjk5.xconf 注册了文泉驿正黑与 Droid Sans Fallback 两个 CJK 字体(注册方法见配置篇第三章)。

二、输入模式

2.1 直接渲染 XSL-FO:-fo 与位置参数

cd /opt/fop/fop
./fop examples/fo/basic/simple.fo /work/out/simple.pdf
./fop -fo examples/fo/basic/simple.fo -pdf /work/out/simple.pdf

两种写法等价(-h 的 Examples 段原文:fop -fo foo.fo -pdf foo.pdf (does the same as the previous line))。无扩展名歧义时推荐显式 -fo/-pdf,脚本里不易踩坑。

2.2 stdin 与 stdout 管道

输入输出都支持 -(stdin/stdout):

cat /work/out/news.fo | ./fop -c /work/conf/fop-cjk5.xconf -fo - -pdf - > /work/out/pipe.pdf

实测输出:

-rw-r--r-- 1 root root 12842 Oct 14 14:06 /work/out/pipe.pdf

日志走 stderr,管道重定向 stdout 即可拿到干净的 PDF 二进制。

2.3 XML + XSLT 转换渲染:-xml 与 -xsl

最常见的生产模式——XML 数据 + 样式表直接出 PDF:

export LANG=C.UTF-8
./fop -c /work/conf/fop-cjk5.xconf \
      -xml /work/src/news.xml -xsl /work/src/news.xsl \
      -param title-prefix "季度报告:" \
      -pdf /work/out/news.pdf

实测输出(stderr):

INFO: Rendered page #1.

产物 13,606 字节,pdftotext 可提取到 季度报告:FOP 转换管道演示,说明 -param 传参生效。

2.4 -param 传递样式表参数

-param name value <value> to use for parameter <name> in xslt stylesheet
        (repeat '-param name value' for each parameter)

每个 -param 传一个参数,多个参数重复书写。XSL 侧用 <xsl:param name="title-prefix"/> 接收。注意 -param 的值是字符串,含空格时整体加引号。

2.5 -foout:只转换不渲染

排查样式表问题的利器——把 XML+XSL 的中间 XSL-FO 结果存盘:

./fop -c /work/conf/fop-cjk5.xconf -xml /work/src/news.xml -xsl /work/src/news.xsl \
      -param title-prefix "季度报告:" -foout /work/out/news.fo

实测输出:

-rw-r--r-- 1 root root 910 Oct 14 14:05 /work/out/news.fo

-foout 仅在 -xml + -xsl 组合下可用,产物是标准 XSL-FO 文件,可直接喂给 -fo 继续渲染,把「样式表错误」与「渲染错误」解耦排查。

2.6 -if / -ifin:两阶段渲染(中间格式)

-if 输出布局完成后的中间格式 XML(intermediate format),-ifin 从中间格式继续渲染最终格式。适合「布局计算贵、多格式输出」的批产场景:

./fop -c /work/conf/fop-cjk5.xconf /work/out/news.fo -if /work/out/news.if.xml
./fop -ifin /work/out/news.if.xml -pdf /work/out/news-ifin.pdf

实测输出:

INFO: Rendered page #1.
-rw-r--r-- 1 root root 5463 Oct 14 14:05 /work/out/news-ifin.pdf

-at(area tree XML)与 -at [mime]/-if [mime] 带可选 mime 时会在输出 XML 中记录目标格式信息,-s 可让 area tree 只保留到块级区域,减小文件。-atin 从 area tree 输入。

2.7 -imagein 与 -catalog

-imagein 把图像文件直接作为输入渲染成目标格式;-catalog 启用 XML catalog 解析器解析 DOCTYPE 外部实体(离线环境处理带 DTD 的 XML 时有用)。

三、输出模式

3.1 支持格式总表(实测)

参数格式实测产物大小备注
-pdfPDF13,606 B(1 页 A4 中文)主力格式
-psPostScript11,563 B打印
-pclPCL9,173 BHP 打印机
-rtfRTF1,571 B可编辑文档,仅支持 FO 子集
-txt纯文本374 B丢排版只留文本流
-pngPNG14,312 B(72dpi)逐页输出 news1.png/…;-dpi 300 时 98,728 B
-tiffTIFF2,010,936 B默认无压缩,配置 CCITT T.6 后 12,214 B
-afpAFP—大型机打印,需按配置篇配 AFP 字体
-mifMIF—FrameMaker 交换格式
-at / -if中间 XML3,689 B / 1,577 B两阶段渲染
-print直接送打印机—无头服务器不可用
-awt屏幕预览—需要 X 环境

PNG/TIFF 是多页输出:一页一个文件,自动加序号后缀(news1.png、news2.png…)。

3.2 -out:按 MIME 指定输出

-out mime outfile input will be rendered using the given MIME type
        (Tip: "-out list" prints the list of supported MIME types and exits)

理论上 fop foo.fo -out application/pdf out.pdf 与 -pdf 等价。实测 2.11 的 -out list 有 bug,直接抛空指针:

./fop -out list

实测输出:

SEVERE: Exception
java.lang.NullPointerException
        at org.apache.fop.cli.CommandLineOptions.parseCustomOutputOption(CommandLineOptions.java:707)

写脚本时避免依赖 -out,直接用 -pdf/-ps 等具名参数。

3.3 PDF 版本与档案规范:-pdfprofile / -pdfa1b

./fop -c /work/conf/fop-cjk5.xconf /work/out/news.fo -pdfa1b /work/out/news-a1b.pdf

实测输出(stderr 含字重替换告警):

WARNING: Font "WQYZenHei,normal,700" not found. Substituting with "WQYZenHei,normal,400".
INFO: Rendered page #1.
pdfinfo /work/out/news-a1b.pdf | grep -iE "pdf version|tagged"

实测输出:

Tagged:          no
PDF version:     1.4

-pdfa1b 是 -pdf outfile -pdfprofile PDF/A-1b 的简写;-a 开启无障碍特性(Tagged PDF)。注意 PDF/A 要求全部字体嵌入,混用未注册字体会产生替换告警,存档前应用 pdffonts 核查。

PDF/X 系列别碰:实测 -pdfprofile "PDF/X-3:2003" 失败:

WARNING: Note: PDF/X-3:2003 support is work-in-progress and not fully implemented, yet!
SEVERE: Exception
org.apache.fop.pdf.PDFConformanceException: PDF/X-3:2003 requires that the DestOutputProfile be an Output Device Profile. sRGB does not match that requirement.

需要 CMYK ICC 输出意图配置才能满足 PDF/X,2.11 官方也明示 work-in-progress,生产存档选 PDF/A-1b。

3.4 PDF 加密与权限

8 个权限开关 + 2 个口令:

参数含义
-o [password]owner 口令(权限管理者)
-u [password]user 口令(打开文档)
-noprint禁打印
-nocopy禁复制
-noedit禁编辑
-noannotations禁批注
-nofillinforms禁填表单
-noaccesscontent禁提取文本/图形(无障碍读取)
-noassembledoc禁拆装页面
-noprinthq禁高质量打印

实测加密渲染:

./fop -c /work/conf/fop-cjk5.xconf /work/out/news.fo \
      -o owner123 -u user123 -noprint -nocopy -pdf /work/out/news-enc.pdf

验证(poppler-utils):

pdfinfo /work/out/news-enc.pdf

实测输出:

Command Line Error: Incorrect password

带 user 口令可正常提取文本:

pdftotext -upw user123 /work/out/news-enc.pdf - | head -2

实测输出:

季度报告:FOP 转换管道演示
日期:2026-10-14

四、校验、日志与退出码

4.1 严格校验与 -r

FOP 默认严格校验 XSL-FO 元素顺序。构造一个 layout-master-set 缺失顺序的坏文件实测:

SEVERE: javax.xml.transform.TransformerException: file:/work/src/bad.fo:4:6:
For "fo:root", "fo:layout-master-set" must be declared before "fo:page-sequence"! (See position 4:6)
SEVERE: Exception
org.apache.fop.apps.FOPException: ... org.apache.fop.fo.ValidationException: ...

产物不生成(退出码非 0)。加 -r(relaxed validation)也无法跳过这类元素顺序错误——-r 只放宽部分属性级检查。报错行号格式 file:4:6 是「文件:行:列」,定位很直接。

4.2 日志分级

全部日志走 stderr,java.util.logging 格式:

级别实测示例含义
INFOINFO: Rendered page #1. / INFO: This is a TrueType collection file with 3 fonts页面进度、字体集合清单
WARNINGWARNING: Glyph "文" (0x6587) not available in font "Times-Roman". / WARNING: Font "WQYZenHei,normal,700" not found. Substituting...缺字、triplet 替换、连字符替换
SEVERESEVERE: Failed to read font file ...致命错误,渲染中止

批量脚本里通常 2>/dev/null 丢弃 INFO,或 2>render.log 留档告警。

4.3 退出码

成功为 0;任何 SEVERE(转换异常、字体加载失败、校验失败)为非 0。批量渲染脚本按退出码判断成败即可,无需解析输出。

五、性能与批量渲染

5.1 JVM 启动开销

实测单次 fop 命令的固定开销约 1.1 秒(JVM 启动 + 类加载 + 字体解析),极小文档的总时长基本等于这个常数。

5.2 批量渲染脚本

#!/bin/bash
set -u
CONF=/work/conf/fop-cjk5.xconf
mkdir -p /work/batch/out
for f in /work/batch/*.fo; do
  n=$(basename "$f" .fo)
  if fop -c "$CONF" "$f" -pdf "/work/batch/out/$n.pdf" 2>/dev/null; then
    echo "OK  $n"
  else
    echo "FAIL $n"
  fi
done

实测 3 个文件:

OK  a
OK  b
OK  c

real    0m3.443s

平均 1.1 秒/文件,瓶颈在 JVM 启动。文件量大时的两条优化路径:其一,用 2.6 的两阶段渲染把布局计算与多格式输出分离;其二,改用 FOP 的 Java 嵌入 API(examples/embedding/ 有官方示例)在单 JVM 内循环渲染,省掉每文件的启动成本。

5.3 内存控制实测

生成 300 页 A4 纯文本文档(每页一个标题块 + 一段正文)压测:

命令耗时峰值 RSS产物
fop big.fo -pdf big.pdf1.95s235,796 KB161,335 B
fop -conserve big.fo -pdf ...1.90s234,624 KB161,335 B
FOP_OPTS="-Xmx64m" fop ...1.85s193,068 KB161,335 B

简单文本页的 area tree 很小,64MB 堆即可完成;-conserve(序列化 area tree 到磁盘)在这种负载下收益不明显,其真正目标是含大图片/巨型表格、area tree 放不进内存的文档。日志尾部 INFO: Rendered page #300. 可用于确认完整渲染。

5.4 位图 dpi 控制

fop -c "$CONF" -dpi 300 /work/out/news.fo -png /work/out/news300.png

实测:72 dpi PNG 14,312 字节 → 300 dpi 98,728 字节。-dpi 实际改写 target-resolution,只影响位图与 SVG 光栅化,对 PDF 矢量输出无意义。

六、字体缓存与配置文件管理

命令作用实测
-cache 路径指定字体缓存位置无家目录 CI 必备
-flush清空字体缓存缓存文件 /root/.fop/fop-fonts.cache(2,105 字节)
-c cfg.xml加载用户配置多个渲染器配置集中在同一文件
-x转储解析后的配置排查配置合并结果
-l lang用户消息语言2.11 仅支持 en/de 等少数语言,国内环境保持默认

七、脚本机制与集成

--execdebug 打印启动脚本最终 exec 的命令行(完整 -classpath 串 + 主类 org.apache.fop.cli.Main),是排查「jar 找不到 / JVM 参数没生效」的官方手段:

FOP_OPTS="-Xmx64m" fop --execdebug -version 2>&1 | grep -o '\-Xmx64m'

实测输出:

-Xmx64m

启动脚本会依次加载 /etc/fop.conf、$HOME/.fop/fop.conf、$HOME/.foprc(--noconfig 抑制),适合按用户注入 JVM 参数。无头服务器上禁用 -awt/-print;cron/systemd timer 环境记得 export LANG=C.UTF-8 并用绝对路径的 -c。

八、常见问题

8.1 fop -out list 抛 NullPointerException

2.11 的已知 CLI bug(CommandLineOptions.parseCustomOutputOption)。改用具名输出参数(3.2)。

8.2 -pdfprofile PDF/X-3:2003 报 sRGB does not match

PDF/X 需要 CMYK ICC 输出意图,2.11 未完整支持,改用 -pdfa1b(3.3)。

8.3 命令行 -param 传中文变问号

POSIX locale 的 argv 解码问题,export LANG=C.UTF-8(安装篇 6.4)。文件内容不受影响,只有命令行参数受影响。

8.4 报 Name does not exist in the TrueType collection

TTC 缺 sub-font 或子字体名错(内部名带 Bold/Regular 后缀),见配置篇 3.3。

8.5 报 'loca' table not found

CFF 轮廓字体(fonts-noto-cjk)不受支持,换 TrueType 轮廓字体(配置篇 3.4)。

8.6 加了 -r 还是校验失败

-r 只放宽属性检查,元素顺序错误(如 layout-master-set 必须在 page-sequence 之前)依旧致命(4.1)。

8.7 stdout 重定向的 PDF 打不开

把 stderr 一起重定向了。日志走 stderr,务必 1>out.pdf 2>log 分开,或确认没有在管道里混入 INFO 行。

8.8 大文件渲染 OOM

FOP_OPTS="-Xmx1g" 加堆 + -conserve;仍不足则用 -if 两阶段拆分(5.3)。

8.9 PNG 只出了一张或多页没序号

PNG/TIFF 一页一文件,自动以 news1.png/news2.png 编号;检查文件名通配时不要把序号写死。

8.10 渲染结果与昨天的字体不一致

字体缓存陈旧,-flush 后重试;CI 环境把 -cache 指到固定路径保证可重复(六)。

九、参考链接

资源地址
Running(CLI)官方文档https://xmlgraphics.apache.org/fop/2.11/running.html
Ant 任务与嵌入 APIhttps://xmlgraphics.apache.org/fop/2.11/embedding.html
Intermediate format 说明https://xmlgraphics.apache.org/fop/2.11/intermediate.html
PDF 加密/规范说明https://xmlgraphics.apache.org/fop/2.11/pdfencryption.html
官方 CLI 示例发行包内 examples/embedding/