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

使用XSL样式表将JSON转PDF时图片无法显示的问题求助

问题分析与解决办法

你遇到的问题核心是ITextRenderer无法解析相对路径的图片——虽然转换后的HTML在浏览器里能正常显示,但ITextRenderer渲染PDF时,需要明确知道资源的基准路径(Base URL),否则它找不到相对路径指向的图片文件。

主要原因

  • 基准URL未设置:你调用renderer.setDocument(resultDoc, "");时第二个参数为空,ITextRenderer无法确定./img/logo.png这个相对路径的起始位置,自然找不到图片。
  • 运行时资源路径变化:开发时图片在src/main/resource/img,但程序运行(尤其是打包后)时,这个目录的实际路径可能和开发环境不一致,导致相对路径失效。

解决办法

方法1:设置正确的基准URL(推荐)

通过类加载器获取资源目录的绝对URL,作为ITextRenderer的基准路径,让它能正确解析相对路径的图片。修改Java代码中renderer.setDocument的部分:

// 获取img目录的URL(从classpath中读取)
URL resourceBase = YourClassName.class.getResource("/img/");
if (resourceBase != null) {
    // 设置基准URL,指导ITextRenderer查找资源的起始位置
    renderer.setDocument(resultDoc, resourceBase.toExternalForm());
} else {
    throw new RuntimeException("无法找到img资源目录,请检查文件位置");
}

同时调整XSL中的img路径,去掉./,直接使用logo.png(因为基准URL已经指向/img/目录):

<td>
    <img>
        <xsl:attribute name="src">logo.png</xsl:attribute>
    </img>
</td>

方法2:嵌入Base64编码的图片(更可靠,适合打包场景)

如果程序需要打包成JAR/WAR,依赖外部文件路径容易出问题,这时可以将图片转换成Base64编码嵌入HTML,完全脱离外部文件依赖。

先在Java中读取图片并转Base64,再传递给XSL作为参数:

// 读取图片并转换为Base64编码
byte[] imageBytes = Files.readAllBytes(Paths.get(getClass().getResource("/img/logo.png").toURI()));
String base64Image = Base64.getEncoder().encodeToString(imageBytes);

// 将Base64字符串传入XSL作为参数
transformer.setParameter("logoBase64", base64Image);

然后在XSL中使用这个参数:

<td>
    <img src="data:image/png;base64,{$logoBase64}" />
</td>

方法3:使用绝对文件路径(仅适合开发调试)

开发阶段可以用绝对路径快速验证:

<td>
    <img>
        <xsl:attribute name="src">C:/your-project-path/src/main/resources/img/logo.png</xsl:attribute>
    </img>
</td>

注意:这种方法不适合生产环境,因为路径会随部署环境变化。

额外检查

  • 确认logo.png确实存在于运行时的资源目录中(打包后可检查JAR/WAR是否包含该文件)。
  • 确保flying-saucer-pdf(ITextRenderer所属库)和依赖的iText版本兼容,建议使用最新稳定版。

内容的提问来源于stack exchange,提问作者user8352964

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 10:02:01