You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

JasperReports 4.5.1使用JSON数据源遇JRExpressionEvalException及数组访问问题

解决JasperReports 4.5.1中JSON数组访问异常问题

问题分析

你碰到的JRExpressionEvalException,核心原因是JSON数据源未正确定位到数组节点,或者字段表达式的JSON路径写法不符合JasperReports 4.5.1的解析规则。这个版本对JSON数据源的解析依赖明确的节点指向,尤其是数组类型的数据,必须单独指定路径才能正常遍历访问。

分步解决方案

1. 配置JSON数据源的查询路径

首先要给报表设置JSON_QUERY参数,明确告诉JasperReports要解析的数组节点位置:

  • 在jrxml中添加参数定义:
<parameter name="JSON_QUERY" class="java.lang.String">
    <defaultValueExpression><![CDATA["Person.Contacts"]]></defaultValueExpression>
</parameter>
  • 接着在报表的dataSourceExpression中引用这个参数,直接定位到数组:
<dataSourceExpression><![CDATA[new net.sf.jasperreports.engine.data.JsonDataSource(new java.io.FileInputStream("contact.json"), $P{JSON_QUERY})]]></dataSourceExpression>

2. 正确编写数组元素的字段表达式

当数据源指向Contacts数组后,就可以直接用字段名访问数组内的属性:

  • 先定义对应字段:
<field name="Type" class="java.lang.String"/>
<field name="Number" class="java.lang.String"/>
  • 在报表文本框中引用字段时,直接使用$F{Type}$F{Number}即可:
<textField>
    <reportElement x="10" y="10" width="100" height="20"/>
    <textFieldExpression><![CDATA[$F{Type}]]></textFieldExpression>
</textField>
<textField>
    <reportElement x="120" y="10" width="150" height="20"/>
    <textFieldExpression><![CDATA[$F{Number}]]></textFieldExpression>
</textField>

3. 用List组件同时展示主数据和数组(主报表+子组件方式)

如果需要在主报表里同时显示Person的基本信息和Contacts数组,推荐使用List组件:

  1. 主报表数据源先指向Person节点:
<dataSourceExpression><![CDATA[new net.sf.jasperreports.engine.data.JsonDataSource(new java.io.FileInputStream("contact.json"), "Person")]]></dataSourceExpression>
  1. 定义Person的基础字段:
<field name="FirstName" class="java.lang.String"/>
<field name="LastName" class="java.lang.String"/>
  1. 添加List组件,将其数据源设置为Contacts数组:
<componentElement>
    <reportElement x="10" y="50" width="300" height="100"/>
    <jr:list xmlns:jr="http://jasperreports.sourceforge.net/jasperreports/components" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports/components http://jasperreports.sourceforge.net/xsd/components.xsd">
        <datasetRun>
            <dataSourceExpression><![CDATA[new net.sf.jasperreports.engine.data.JsonDataSource(((net.sf.jasperreports.engine.data.JsonDataSource)$P{REPORT_DATA_SOURCE}).getCurrentNode().get("Contacts"))]]></dataSourceExpression>
        </datasetRun>
        <jr:listContents height="20" width="300">
            <textField>
                <reportElement x="10" y="0" width="100" height="20"/>
                <textFieldExpression><![CDATA[$F{Type}]]></textFieldExpression>
            </textField>
            <textField>
                <reportElement x="120" y="0" width="150" height="20"/>
                <textFieldExpression><![CDATA[$F{Number}]]></textFieldExpression>
            </textField>
        </jr:listContents>
    </jr:list>
</componentElement>

注意事项

  • JasperReports 4.5.1的JSON数据源不支持复杂JSONPath语法,尽量用简单的层级路径(如Parent.Child.Array)。
  • 确保JSON文件路径正确,避免因文件找不到引发间接异常。
  • 检查字段名和JSON中的键是否完全一致(区分大小写),这是容易忽略的细节。

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

火山引擎 最新活动