You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 07:41:37