JasperReport子报表基于sortedPositions直接字段分组失效问题
问题原因
这个问题是JasperReports的JRBeanCollectionDataSource字段取值规则导致的,核心逻辑很明确:
- 所有配置了
<fieldDescription>的字段,报表引擎会严格按照你写的OGNL路径从当前行的JavaBean里反射取值,取值逻辑稳定,返回的值一致性高,分组做equals判断时能正确识别相同值,所以你配置了fieldDescription的productDescription等嵌套对象字段分组完全正常。 - 没有配置
<fieldDescription>的直接字段(比如你现在的description、id、quantity、value),引擎会走默认的字段映射逻辑,这个逻辑在不同JasperReports版本、不同类加载环境、存在跨路径字段引用(比如你配置的period字段读invoice.period,但根JavaBean根本没有invoice属性)的情况下,会出现取值不稳定、值类型不匹配、甚至取到上下文其他同名参数的问题,导致分组判断时无法正确识别相同值,分组失效。
另外你当前配置里还有个隐藏问题:根JavaBean本身就有corridor字段,但你给corridor字段配置的fieldDescription实际读的是productConfiguration.invoicePositionList.get(0).corridor,等于覆盖了根字段的取值,如果你本来要分组的是根对象的corridor,这个配置本身就是错的。
解决方案
第一步:给所有根对象字段显式配置fieldDescription
不要依赖默认的字段名自动映射,给每个直接属于sortedPositions元素的字段都加上明确的取值路径,修改后的字段配置参考:
<field name="quantity" class="java.math.BigDecimal"> <fieldDescription><![CDATA[quantity]]></fieldDescription> </field> <field name="id" class="java.lang.Long"> <fieldDescription><![CDATA[id]]></fieldDescription> </field> <field name="value" class="java.math.BigDecimal"> <fieldDescription><![CDATA[value]]></fieldDescription> </field> <field name="description" class="java.lang.String"> <fieldDescription><![CDATA[description]]></fieldDescription> </field> <!-- 如果要使用根对象的corridor字段,替换掉原来的嵌套路径配置 --> <field name="corridor" class="java.lang.String"> <fieldDescription><![CDATA[corridor]]></fieldDescription> </field>
第二步:清理无效字段配置
删掉没有对应取值路径的无效字段,比如你当前配置的period字段写的路径是invoice.period,如果根JavaBean不存在getInvoice()方法,这个字段每次取值都会触发反射异常,干扰整个数据源的取值逻辑,不需要的话直接删除即可。
第三步:校验JavaBean规范
确保sortedPositions对应的实体类,所有字段都有符合JavaBean规范的public getter方法:比如description字段要对应public String getDescription()方法,返回值类型和子报表字段定义的class属性完全匹配,不要出现类型不匹配的情况。
做完以上调整后,直接字段的取值会和嵌套字段一样稳定,分组功能就能正常生效。
内容的提问来源于stack exchange,提问作者Markos Tzetzis
相关产品推荐
相关产品推荐

