Question

I have jrxml file that based on csv datasource. Only one column contains json string in that csv file.

Consider following sample,

    ID  NAME    TAG_AND_VALUES
    1   test1   { "caseID" : "1200", "CaseNumber"  : 12 }
    2   test2   { "caseID" : "1201" }
    3   test3   { "caseID" : "1202", "CaseNumber"  : 14 }
    4   test4   { "caseID" : "1203", "CaseNumber"  : 15 }
    5   test5   { "CaseNumber"  : 16, "caseID" : "1204",  }
    6   test6   { "caseID" : "1205", }
   

Please note that CaseID is always there, but cannot guarantee the order of TAG_AND_VALUES, because it is possible to add or grow TAG_AND_VALUES dynamically.

I want to read the value of each caseID from each TAG_AND_VALUES.

Was it helpful?

Solution

You can do something with the JSON data source built into JasperReports. See below JRXML fragments that use a list component with a subdataset to read the values from the JSON string:

<subDataset name="TagAndValues">
    <field name="caseID" class="java.lang.String"/>
    <field name="CaseNumber" class="java.lang.String"/>
</subDataset>
....
        <componentElement>
            <reportElement x="200" y="0" width="200" height="20" uuid="a6cc346e-d517-431e-8860-d81cc4e1145f"/>
            <c:list xmlns:c="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="TagAndValues" uuid="b8180534-701e-4f9a-ad5f-785d1a5fb74b">
                    <dataSourceExpression>new net.sf.jasperreports.engine.data.JsonDataSource(new java.io.ByteArrayInputStream($F{TAG_AND_VALUES}.getBytes()))</dataSourceExpression>
                </datasetRun>
                <c:listContents height="20">
                    <frame>
                        <reportElement x="0" y="0" width="200" height="20" uuid="28b3ebcb-1bd3-422d-9468-54216206315d"/>
                        <textField>
                            <reportElement x="0" y="0" width="100" height="20" uuid="2fba17f5-4547-4f51-a12f-815c7f0589ca"/>
                            <textFieldExpression><![CDATA[$F{caseID}]]></textFieldExpression>
                        </textField>
                        <textField>
                            <reportElement x="100" y="0" width="100" height="20" uuid="2fba17f5-4547-4f51-a12f-815c7f0589ca"/>
                            <textFieldExpression><![CDATA[$F{CaseNumber}]]></textFieldExpression>
                        </textField>
                    </frame>
                </c:listContents>
            </c:list>
        </componentElement>

There are two issues with this approach:

  1. JSON doesn't allow trailing commas. If you don't control the source of the data, some processing of the JSON text to remove trailing commas would be required.
  2. Declaring the CaseNumber field as number/integer won't work, there's a problem in JR with the records that don't have CaseNumber. Keeping the field as string is a workaround, it can be manually parsed as number if required.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top