Reputation: 71
If I have a Jasper report with two fields. For example:
<field name="counts" class="java.util.List"/>
<field name="names" class="java.util.List"/>
In the report is it possible to use the name field to "lookup" a value in the counts
field if the counts field looks like this:
[{"Bob":10},{"Bill":5},{"John":2}]
So in the report I iterate over the names using a subDataSet:
<subDataset name="nameDetails" uuid="6f0e513d-9659-4dea-8c88-0fa9522d6aef">
<field name="name" class="java.lang.String">
<fieldDescription><![CDATA[name]]></fieldDescription>
</field>
</subDataset>
<componentElement>
<reportElement x="0" y="40" width="200" height="60"/>
<jr:list printOrder="Vertical">
<datasetRun subDataset="nameDetails">
<dataSourceExpression><![CDATA[new net.sf.jasperreports.engine.data.JRMapCollectionDataSource($F{names})]]></dataSourceExpression>
</datasetRun>
<jr:listContents height="60" width="200">
<textField>
<reportElement x="0" y="0" width="200" height="20"/>
<textFieldExpression><![CDATA["Name: " + $F{name}]]></textFieldExpression>
</textField>
...
This prints out the name of each person in the names field, but additionally I want to use the "name" of each person to look-up the count for the person in the counts
field, but not sure if I can do this or how?
Upvotes: 3
Views: 4995
Reputation: 21710
Yes you can reference fields, in your case however you need first to pass also the other field to the subdataset, hence you can only reference data that is present in the actual subdataset.
One way is to pass the field counts
as a parameter.
<datasetParameter name="counts">
<datasetParameterExpression><![CDATA[$F{counts}]]></datasetParameterExpression>
</datasetParameter>
For example assuming the List have data in same position.
List<String> names = Arrays.asList(new String[] { "Bob", "Bill", "John" });
List<Integer> counts = Arrays.asList(new Integer[] { 10, 5, 2 });
You could use the built in parameter $V{REPORT_COUNT}
to retrive data from the other List, $P{counts}.get(($V{REPORT_COUNT}.intValue()-1))
jrxml
<?xml version="1.0" encoding="UTF-8"?>
<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="firstReport" pageWidth="595" pageHeight="842" whenNoDataType="BlankPage" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="597c0716-df6b-42ec-a7c8-863eb1b7174a">
<subDataset name="nameDetails" uuid="63078d78-2076-4a72-8728-ee6ca3ded99f">
<parameter name="counts" class="java.util.List"/>
<field name="_THIS" class="java.lang.String"/>
</subDataset>
<field name="counts" class="java.util.List"/>
<field name="names" class="java.util.List"/>
<detail>
<band height="50">
<componentElement>
<reportElement x="0" y="0" width="550" height="30" uuid="180fb785-64b3-4f04-81f6-7076444d871d"/>
<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" printOrder="Vertical">
<datasetRun subDataset="nameDetails" uuid="8d40297b-e33b-4681-9533-d6f1ab63c6f2">
<datasetParameter name="counts">
<datasetParameterExpression><![CDATA[$F{counts}]]></datasetParameterExpression>
</datasetParameter>
<dataSourceExpression><![CDATA[new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($F{names})]]></dataSourceExpression>
</datasetRun>
<jr:listContents height="30" width="550">
<textField>
<reportElement x="0" y="0" width="550" height="30" uuid="48e09c52-3b6a-40cf-b572-2abccfcd83cc"/>
<textElement verticalAlignment="Middle">
<font size="14"/>
</textElement>
<textFieldExpression><![CDATA[$F{_THIS} + ":" + $P{counts}.get(($V{REPORT_COUNT}.intValue()-1))]]></textFieldExpression>
</textField>
</jr:listContents>
</jr:list>
</componentElement>
</band>
</detail>
</jasperReport>
Result
Note: If you have control on data arriving, however I would strongly suggest you pass the data in a single object (List), since this type of referencing is error prone, in this case if the size of the Lists are different, the report generation will fail
Upvotes: 3