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

使用Java实现HTML转内存PDF时ITextRenderer+Jsoup抛出SAX解析异常如何解决

问题根因

ITextRenderer(即Flying Saucer PDF渲染组件)仅支持解析语法严格符合XML规范的XHTML内容,无法直接处理松散语法的普通HTML,你当前的代码存在核心问题触发SAX解析异常:

  • 手动将Jsoup输出语法设置为Syntax.html,输出内容存在标签未闭合、属性未加引号等不符合XML规范的写法
  • 未给HTML根元素声明XHTML必需的命名空间,解析器无法识别文档结构
  • 部分场景下输出内容开头会携带多余空白、BOM头,和报错信息中「根元素前的标记格式不合法」的描述完全匹配
修复代码

不需要更换HTML转PDF类库,调整Jsoup的输出配置,生成标准合规的XHTML再传入渲染器即可,修正后的实现如下:

import org.jsoup.nodes.Document;
import java.io.ByteArrayOutputStream;
import java.nio.charset.StandardCharsets;
import org.xhtmlrenderer.pdf.ITextRenderer;

// 解析原始HTML模板
Document document = Jsoup.parse(template, "UTF-8");
// 配置Jsoup输出为XHTML(XML语法)格式
document.outputSettings()
        .syntax(Document.OutputSettings.Syntax.xml)
        .charset(StandardCharsets.UTF_8)
        .outline(true)
        .indentAmount(2);
// 给根标签添加XHTML必须的命名空间,避免样式渲染异常
document.selectFirst("html").attr("xmlns", "http://www.w3.org/1999/xhtml");

ByteArrayOutputStream binaryOutput = new ByteArrayOutputStream();
ITextRenderer renderer = new ITextRenderer();
renderer.setDocumentFromString(document.html());
renderer.layout();
renderer.createPDF(binaryOutput);
// binaryOutput中即为内存中生成的PDF文件字节,可直接用于后续存储、返回响应等操作
避坑说明
  • 不要在传入渲染器的内容开头手动添加XML声明头(如<?xml version="1.0" encoding="UTF-8"?>),部分版本的ITextRenderer解析该头部时会直接触发位置1的格式错误
  • 若模板使用了HTML5新增标签(如<section>、<article>),请使用9.1.22及以上版本的Flying Saucer依赖,老版本对HTML5标签兼容性极差,会出现解析失败、样式错乱问题
  • 切换到XML输出语法后,Jsoup会自动补全所有未闭合的标签,不需要手动修改原始HTML模板的写法
  • 该方案仅对CSS2.1及部分简单CSS3属性支持较好,若需要渲染复杂的现代页面(含大量CSS3、JS动态内容),建议选择基于无头浏览器的渲染方案实现。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 12:27:23