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
相关产品推荐
相关产品推荐

