itext不直接解析xml,需先转换为java对象或xhtml;xmlworkerhelper.parsexhtml()仅支持严格xhtml格式,原始xml会抛documentexception或nullpointerexception。

XML解析失败:iText不直接读XML,得先转成Java对象或HTML
iText本身不提供XmlToPdf这种开箱即用的函数。你扔一个report.xml进去,它会直接报DocumentException或NullPointerException——因为它根本不知道XML结构代表什么。常见错误是误以为调用XmlWorkerHelper.parseXHtml()就能喂原始XML,其实它只认格式严格的XHTML(比如<p>...</p>),不是任意XML。
实际做法分两路:
- 如果XML是自定义结构(如
<invoice><item><name>A</name></item></invoice>),先用JAXB或DOMParser解析成Java对象,再用iText API逐个写入PdfDocument - 如果XML能转成XHTML(比如用XSLT或手动映射),再交给
XmlWorkerHelper.parseXHtml()渲染——但注意iText 7里XmlWorker已独立为itext7-xmlworker模块,必须显式引入
iText 7中XmlWorkerHelper.parseXHtml()报ClassNotFound
这是典型依赖缺失。iText 7把XML解析抽成了单独模块,itext7-xmlworker不包含在核心包里,且和iText 7主版本强绑定。比如用itext7.2.5却配了xmlworker.7.1.0,运行时就会找不到com.itextpdf.tool.xml.XMLWorkerHelper。
正确做法:
立即学习“Java免费学习笔记(深入)”;
PowerDesigner使用教程,内容有界面与操作基本概念、数据项目与实体、定义实体间的联系与角色、定义和使用域及继承、将CDM对象转换成PDM对象、生成报表等
- Maven里必须同时声明匹配的版本:
itext7.kernel、itext7.layout、itext7.xmlworker三者小版本号一致(如全用7.2.5) -
XmlWorkerHelper初始化不能直接new,得用XmlWorkerHelper.getInstance() - 传入的XHTML字符串里不能有
<script></script>或CSS里的position: absolute——XmlWorker对CSS支持有限,遇到就静默跳过或崩溃
中文乱码/字体缺失:PDF里显示方块或空格
iText默认不嵌入中文字体,parseXHtml()遇到中文直接用Helvetica,而Helvetica没中文字符集,结果就是方块。这不是编码问题(UTF-8读XML没问题),是字体资源没绑定。
解决路径很明确:
- 准备一个支持中文的TrueType字体文件(如
simhei.ttf或NotoSansCJKsc-Regular.otf) - 创建
ConverterProperties时,用setBaseUri()指向字体所在目录,并调用setFontProvider()注册字体 - 关键点:XHTML里得用
style="font-family: 'SimHei';"显式指定,不能只靠CSS全局设置——XmlWorker对@font-face支持不完整
动态表格生成慢、内存溢出
用XmlWorker渲染含几百行<table>的XHTML时,容易OOM或卡死。根本原因是XmlWorker内部会把整个DOM树加载进内存,再逐节点转换,没有流式处理机制。
<p>替代方案更可靠:</p>
<ul>
<li>放弃XmlWorker,改用<code>Table类手动生成:解析XML后循环调用table.addCell(new Cell().add(new Paragraph(text)))
PdfPage,调用document.add(table)后立刻table.flush()释放引用new Font()——复用同一个Font实例,否则GC压力陡增真正麻烦的是混合场景:既要XML灵活定义字段,又要PDF精准控制分页和字体。这时候得在解析层做预处理,把XML转成带样式标记的中间结构,而不是硬塞给XmlWorker扛。









