jasperreports需用jrxmldatasource包装xml数据源,要求xml有唯一根节点且记录为直接子节点,支持xpath定位字段、命名空间及sax流式解析,pdf中文需配置字体,大文件须启用流模式防oom。

XML数据源怎么配给JasperReports
JasperReports 本身不直接解析任意 XML 文件,必须先用 JRXmlDataSource 包装。它要求 XML 符合特定结构:根节点下是重复的记录节点(比如 <orders><order>...</order><order>...</order></orders>),否则会报 net.sf.jasperreports.engine.JRException: Could not load XML data 或静默跳过数据。
- 确保 XML 有且仅有一个顶层容器节点,所有数据行是它的直接子节点(不能嵌套两层才到记录)
- 用
new JRXmlDataSource(xmlInputStream, "/root/record")显式指定 XPath 路径,别依赖默认行为 - 如果 XML 含命名空间,
JRXmlDataSource默认不处理,要么预处理去掉 namespace,要么改用JRXmlDataSource(InputStream, String, boolean)构造函数并传true启用 namespace 支持(JasperReports ≥ 6.12)
报表模板里怎么引用XML字段
字段名不是 XML 标签名,而是 XPath 表达式相对记录节点的路径。比如每条 <order></order> 下有 <customer><name>Alice</name></customer>,那字段表达式得写 customer/name,不是 name 或 /order/customer/name。
- 字段类型在模板中声明为
java.lang.String即可,JasperReports 会自动转换文本内容 - 遇到属性值(如
<item id="101"></item>),用@id引用,注意@符号不能漏 - 子节点含多个同名项(如多个
<tag></tag>)时,tags/tag只取第一个;要全量需用$F{tags/tag}.size()配合 list 组件,但得提前确认字段类型是java.util.List
导出PDF时中文乱码或字体缺失
XML 数据里的中文能正常读取,但 PDF 导出后显示方块或空格,问题几乎都在字体配置,和 XML 解析无关。
- 必须在 jrxml 模板里每个文本字段设置
pdfFontName和pdfEncoding,例如pdfFontName="STSong-Light" pdfEncoding="UniGB-UCS2-H" - 使用 iText 5 时,中文字体文件(如
simhei.ttf)要通过JRFontExtensionsRegistry注册,或把字体打包进 classpath 并在jasperreports_extension.properties中声明 - 若用 JasperReports Server,字体配置在服务端,本地开发测试用的字体路径对服务器无效,容易误判为代码问题
内存溢出或生成超慢的常见原因
大 XML(>10MB)直接喂给 JRXmlDataSource 会全部加载进内存构建 DOM 树,不是流式解析。即使数据只用一次,也极易 OOM。
- 超过 5 万条记录建议改用
JRXmlDataSource的流式构造函数:new JRXmlDataSource(xmlInputStream, "/root/record", true)(第三个参数启用 SAX 模式) - 避免在模板表达式里写复杂 XPath,如
../../../parent/name,每次渲染都重新遍历,性能断崖式下降 - 不要在
textField的expression中调用System.getProperty()或其他 IO 操作——XML 数据源本身无状态,但表达式会在每行重复执行
真正卡住的地方往往不在“怎么转”,而在 XML 结构是否适配 JRXmlDataSource 的 XPath 定位逻辑,以及字体和内存这两关没提前压测过真实数据量。










