使用FOP将HTML转PDF:如何在运行时向XSLT变量传递动态值?
如何在FOP转换HTML到PDF时向XSLT传递动态变量
Hey there! 我来帮你搞定这个问题——在FOP运行时给XSLT传动态值其实是个很常见的需求,分几个清晰的步骤就能实现,下面我分场景给你详细说明:
第一步:在XSLT中定义可接收的参数
首先你需要在你的XSLT样式文件里,提前声明好要接收的动态参数,放在<xsl:stylesheet>标签内部、所有模板之外的顶层位置:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 定义带默认值的参数,如果没传值就用默认值 --> <xsl:param name="dynamicDocumentTitle" select="'Generated PDF'" /> <!-- 定义无默认值的参数,不传的话就是空值 --> <xsl:param name="currentUserName" /> <!-- 你的模板逻辑,比如使用这些参数 --> <xsl:template match="/"> <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> <fo:layout-master-set> <fo:simple-page-master master-name="page" page-width="A4" page-height="29.7cm"> <fo:region-body margin="2cm" /> </fo:simple-page-master> </fo:layout-master-set> <fo:page-sequence master-reference="page"> <fo:flow flow-name="xsl-region-body"> <!-- 引用动态参数 --> <fo:block font-size="24pt" font-weight="bold" margin-bottom="1cm"> <xsl:value-of select="$dynamicDocumentTitle" /> </fo:block> <fo:block font-size="12pt"> Generated by: <xsl:value-of select="$currentUserName" /> </fo:block> <!-- 其他HTML转换后的内容 --> </fo:flow> </fo:page-sequence> </fo:root> </xsl:template> </xsl:stylesheet>
第二步:通过Java API传递参数(适合编程场景)
如果你的项目是用Java开发的,直接用FOP的Java API来传递参数非常灵活:
import org.apache.fop.apps.*; import javax.xml.transform.*; import javax.xml.transform.stream.*; import java.io.*; public class FopHtmlToPdf { public static void main(String[] args) throws Exception { // 初始化FOP工厂 FopFactory fopFactory = FopFactory.newInstance(new File(".").toURI()); FOUserAgent foUserAgent = fopFactory.newFOUserAgent(); // 加载XSLT样式表,并设置动态参数 TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer( new StreamSource(new File("your-stylesheet.xsl")) ); // 传递参数:键名要和XSLT里的param name完全一致(大小写敏感) transformer.setParameter("dynamicDocumentTitle", "Q3 2024 Sales Report"); transformer.setParameter("currentUserName", "Maulik Kakadiya"); // 准备输出PDF的流 OutputStream pdfOut = new BufferedOutputStream( new FileOutputStream(new File("output.pdf")) ); Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, pdfOut); // 把HTML作为转换输入源 Source htmlSource = new StreamSource(new File("input.html")); Result foResult = new SAXResult(fop.getDefaultHandler()); // 执行转换:HTML -> XSLT(注入动态值)-> FO -> FOP -> PDF transformer.transform(htmlSource, foResult); // 关闭资源 pdfOut.close(); } }
这里的核心是transformer.setParameter()方法,只要参数名和XSLT里的<xsl:param>名称完全匹配,就能把动态值传递进去。
第三步:通过命令行传递参数(适合脚本/手动运行场景)
如果你习惯用命令行调用FOP,直接用-param参数就能传递动态值,多个参数重复使用-param即可:
fop -xml input.html -xsl your-stylesheet.xsl -pdf output.pdf \ -param dynamicDocumentTitle "Q3 2024 Sales Report" \ -param currentUserName "Maulik Kakadiya"
注意事项
- 参数名大小写敏感,必须和XSLT里的
<xsl:param>的name属性完全一致 - 如果参数值包含空格或特殊字符,记得用引号把值括起来
- 复杂类型的参数(比如XML节点集)建议用Java API传递,命令行只适合简单的字符串/数值类型
内容的提问来源于stack exchange,提问作者Maulik Kakadiya
相关产品推荐
相关产品推荐

