You need to enable JavaScript to run this app. Java使用core renderer、iText依赖实现HTML转PDF时Base64图片不显示
优惠活动
大模型
产品
解决方案
定价
更多

Java使用core renderer、iText依赖实现HTML转PDF时Base64图片不显示

HTML转PDF时内嵌Base64图片无法渲染的根因与修复

问题核心成因

  • 你当前使用的老版本core renderer(即Flying Saucer渲染引擎)默认的资源加载逻辑,原生不支持解析data:协议开头的Base64内嵌图片。它的内置资源加载器仅能识别http、https、本地file路径这类常规图片源,遇到你HTML里<img src="data:image/png;base64,xxx">格式的资源时,会直接判定资源加载失败,跳过图片渲染,最终出现文字展示正常、内嵌图片全部丢失的现象。
  • 你当前的依赖组合本身存在版本冲突:同时引入itext-2.0.8和itextpdf-5.5.13.1两个不兼容的itext大版本,类加载冲突会进一步干扰渲染器的资源加载流程,放大图片渲染异常的概率。

具体修复步骤

  • 第一步:实现支持Base64协议的自定义资源加载器
    继承渲染器内置的基础资源加载类NaiveUserAgent,重写图片资源获取方法,专门针对data:开头的Base64源做解码处理,核心实现代码如下:
    import org.xhtmlrenderer.swing.NaiveUserAgent;
    import org.xhtmlrenderer.swing.Java2DImage;
    import org.xhtmlrenderer.swing.ImageResource;
    import javax.imageio.ImageIO;
    import java.io.ByteArrayInputStream;
    import java.util.Base64;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    public class Base64SupportedUserAgent extends NaiveUserAgent {
        // 匹配data协议格式的正则表达式
        private static final Pattern DATA_URI_MATCHER = Pattern.compile("data:([a-zA-Z]+/[a-zA-Z+.-]+);base64,(.+)");
    
        @Override
        public ImageResource getImageResource(String uriStr) {
            // 优先识别并处理Base64内嵌的图片资源
            Matcher dataUriMatcher = DATA_URI_MATCHER.matcher(uriStr);
            if (dataUriMatcher.find()) {
                try {
                    String base64ImgContent = dataUriMatcher.group(2);
                    byte[] imgByteArr = Base64.getDecoder().decode(base64ImgContent);
                    var loadedImg = ImageIO.read(new ByteArrayInputStream(imgByteArr));
                    return new ImageResource(uriStr, new Java2DImage(loadedImg));
                } catch (Exception e) {
                    // 解码异常时走原有逻辑抛出标准错误
                    return super.getImageResource(uriStr);
                }
            }
            // 非Base64的常规图片源走原有加载逻辑
            return super.getImageResource(uriStr);
        }
    }
    
  • 第二步:在原有PDF生成逻辑中替换默认的资源加载器
    在初始化ITextRenderer的代码段,替换成上面写好的支持Base64的加载器,原有字体配置、PDF输出逻辑保持不变,调整后的核心代码片段:
    ITextRenderer renderer = new ITextRenderer();
    // 替换默认资源加载器,开启Base64图片支持
    renderer.getSharedContext().setUserAgentCallback(new Base64SupportedUserAgent());
    // 原有字体解析逻辑保留
    ITextFontResolver resolver = renderer.getFontResolver();
    resolver.addFont("C:\\Users\\DELL\\AppData\\Local\\Microsoft\\Windows\\Fonts\\ANGSA.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
    
  • 第三步:清理依赖版本冲突
    移除不兼容的重复itext依赖:如果使用的是core-renderer R8版本(即你当前用的老版本core renderer),仅保留配套适配的itext-2.0.8依赖,删掉itextpdf-5.5.13.1的引入,避免类冲突导致的渲染异常。如果后续升级到9.x版本的Flying Saucer渲染器,引擎本身已经原生支持Base64内嵌图片,不需要额外写自定义加载器。
  • 额外样式兼容排查
    你示例HTML里的img标签样式写法style = "width = 10px; height = 10px;",不符合标准CSS语法规范,老版本渲染器的CSS解析器无法正确识别带空格的属性写法,会导致图片即使加载成功,也因为尺寸解析失败被渲染成0宽度0高度,看不到效果。要改成标准CSS写法:style="width:10px;height:10px;"。

内容的提问来源于stack exchange,提问作者vinoth .N

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.29 00:54:03