Jasper Report表格多级属性过滤及字段取值问题排查
解决Jasper Report中XML字段读取与行过滤问题
我来帮你搞定这两个核心问题——字段值无法读取和过滤指定行的需求,咱们一步步来梳理:
1. 修复value_create和value_create1字段的读取问题
你的字段描述里的XPath路径犯了一个常见错误:在子数据集driver_details中,查询已经定位到/data/c_data节点,所以字段的XPath应该用相对路径,而不是重复写完整的根路径。另外value_create1直接引用字段名是无效的,得用正确的路径或者复用已有字段的逻辑:
修正后的子数据集字段定义:
<subDataset name="driver_details" uuid="123c4f48-1cc9-4bd6-8350-f9e9ebe20e74"> <queryString language="xPath"> <![CDATA[/data/c_data]]> </queryString> <field name="quote_driver_full_name" class="java.lang.String"> <fieldDescription><![CDATA[quote_driver_full_name]]></fieldDescription> </field> <!-- 移除冗余的quote_driver_full_name1,直接用原字段即可 --> <field name="value_create" class="java.lang.String"> <fieldDescription><![CDATA[create_state/value]]></fieldDescription> </field> <!-- 如果确实需要value_create1,用和value_create相同的相对路径 --> <field name="value_create1" class="java.lang.String"> <fieldDescription><![CDATA[create_state/value]]></fieldDescription> </field> </subDataset>
解释:子数据集的查询已经把上下文限定在每个c_data节点上,所以只需要写create_state/value就能直接拿到当前节点下的value值,不用再从头写data/c_data。
2. 过滤掉value=Yes的行
要实现行过滤,推荐两种高效方式:
方式一:数据源层面直接过滤(最推荐)
修改子数据集的queryString,只选择create_state/value != 'Yes'的节点,从根源上排除不需要的行:
<queryString language="xPath"> <![CDATA[/data/c_data[create_state/value != 'Yes']]]> </queryString>
这种方式性能最好,因为报表不需要处理多余的数据。
方式二:报表单元格添加打印条件
如果不想修改数据源查询,可以在textField的printWhenExpression里设置显示条件,只打印符合要求的行:
<textField> <reportElement x="0" y="0" width="490" height="20" uuid="2f8004da-a095-4eff-928b-ec955cad7622"> <printWhenExpression><![CDATA[!$F{value_create}.equals("Yes")]]></printWhenExpression> </reportElement> <textFieldExpression><![CDATA[$F{quote_driver_full_name} + ":" + $F{value_create} + ":" + $F{value_create1}]]></textFieldExpression> </textField>
注意:这种方式只是隐藏了不符合条件的行,但数据源里仍然会包含这些数据,所以优先选方式一。
3. 完整修正后的关键代码片段
把上面的修改整合后,你的子数据集和表格部分应该是这样的:
<style name="noBorder"/> <subDataset name="driver_details" uuid="123c4f48-1cc9-4bd6-8350-f9e9ebe20e74"> <queryString language="xPath"> <![CDATA[/data/c_data[create_state/value != 'Yes']]]> </queryString> <field name="quote_driver_full_name" class="java.lang.String"> <fieldDescription><![CDATA[quote_driver_full_name]]></fieldDescription> </field> <field name="value_create" class="java.lang.String"> <fieldDescription><![CDATA[create_state/value]]></fieldDescription> </field> <field name="value_create1" class="java.lang.String"> <fieldDescription><![CDATA[create_state/value]]></fieldDescription> </field> </subDataset> <detail> <band height="670" splitType="Stretch"> <frame> <reportElement style="table" positionType="Float" x="3" y="49" width="546" height="441" uuid="4bf9e6ee-0faa-458c-9d98-96ee2936be2a"/> <componentElement> <reportElement key="table 6" x="3" y="13" width="497" height="50" uuid="462397c6-bb2d-4a70-a568-0d34b8ef9bde"/> <jr:table xmlns:jr="http://jasperreports.sourceforge.net/jasperreports/components" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports/components http://jasperreports.sourceforge.net/xsd/components.xsd"> <datasetRun subDataset="driver_details" uuid="a856c3e2-4cac-4df0-b0b3-83d9c4d3be5a"> <dataSourceExpression><![CDATA[((net.sf.jasperreports.engine.data.JRXmlDataSource)$P{REPORT_DATA_SOURCE}).subDataSource("/data/c_data")]]></dataSourceExpression> </datasetRun> <jr:column width="490" uuid="fbc10a2f-9507-453e-bf9e-714df6349e71"> <jr:columnHeader height="30" rowSpan="1"> <staticText> <reportElement x="0" y="0" width="490" height="30" uuid="760bf14a-a63e-452f-b8d0-863ba993d174"/> <text><![CDATA[Named Drivers]]></text> </staticText> </jr:columnHeader> <jr:detailCell style="noBorder" height="20" rowSpan="1"> <textField> <reportElement x="0" y="0" width="490" height="20" uuid="2f8004da-a095-4eff-928b-ec955cad7622"/> <textFieldExpression><![CDATA[$F{quote_driver_full_name} + ":" + $F{value_create} + ":" + $F{value_create1}]]></textFieldExpression> </textField> </jr:detailCell> </jr:column> </jr:table> </componentElement> </frame> </band> </detail>
这样修改后,你就能正确读取value_create和value_create1的字段值,同时报表只会显示value=No的行(也就是SD2那一行)。
内容的提问来源于stack exchange,提问作者Rashmi Ranjan Sahu
相关产品推荐
相关产品推荐

