freefall
freefall

Reputation: 617

How to iterate over JSON array to create repeating report in jasperreports

I have a JSON data with a following structure

[{
"a1":"b1",
"a2":"b2",
"details1":[{"a1":"b1"}],
"details2":[{"a2":"b2"}],
},
{
"a1":"b1",
"a2":"b2",
"details1":[{"a1":"b1"}],
"details2":[{"a2":"b2"}],
},
{
"a1":"b1",
"a2":"b2",
"details1":[{"a1":"b1"}],
"details2":[{"a2":"b2"}],
}]

I have created separate reports for details1 and details2 arrays. Also I have create a report for one element of the main table refferring to details1 and details2 reports as a subreports.

The problem is the main report is printing only the a1 and a2 from the first element and then prints all elements from all details1 and details2 tables from all elements.

My goal is to create a report that will print a1,a2, details1, details2 from first element of the main table, then the second one and so on. How can I achive that?

In other words, how can I iterate the same report template over the JSON array?

Upvotes: 2

Views: 9631

Answers (1)

Narcis
Narcis

Reputation: 2511

You don't have to create subreports in order to reach the nested arrays. A simpler solution is to make use of subDatasets.

In your case you need to create subDatasets for each details key in your JSON source:

<subDataset name="details1" uuid="4563e834-a9e5-43b5-9f0a-824948c73c73">
  <field name="A1" class="java.lang.String">
    <fieldDescription><![CDATA[a1]]></fieldDescription>
  </field>
</subDataset>
<subDataset name="details2" uuid="f703cb76-2a4a-44f1-9a42-227e180038d2">
  <field name="A2" class="java.lang.String">
    <fieldDescription><![CDATA[a2]]></fieldDescription>
  </field>
</subDataset>

Your main query has to be empty in order to iterate over each object in the main JSON source:

<queryString language="json">
  <![CDATA[]]>
</queryString>

You then need to use a structure that knows how to handle a subDataset like a table or a list. I'm choosing a list here since it easier to work with. For the first subDataset you would then have:

<componentElement>
  <reportElement x="90" y="40" width="333" height="20" uuid="c3237c70-6b2e-43e3-aa21-5092d8b91afc"/>
  <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="details1" uuid="f5fdc6a3-736f-43ce-b549-cd7332d19eb8">
      <dataSourceExpression><![CDATA[((net.sf.jasperreports.engine.data.JsonDataSource)$P{REPORT_DATA_SOURCE}).subDataSource("details1")]]></dataSourceExpression>
    </datasetRun>
    <jr:listContents height="20" width="333">
      <textField>
        <reportElement x="10" y="0" width="130" height="20" uuid="07e3ff2a-3832-4b06-9275-cb1ee8e51cfe"/>
        <textFieldExpression><![CDATA[$F{A1}]]></textFieldExpression>
      </textField>
    </jr:listContents>
  </jr:list>
</componentElement>

For the second subDataset the list component is identical.

Here is a simple JRXML with the complete solution:

<?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="Report" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="81afe112-ee1b-4443-8d1c-cb6d9ab95dd8">
  <property name="com.jaspersoft.studio.data.defaultdataadapter" value="JsonArrayDataAdapter.xml"/>
  <subDataset name="details1" uuid="4563e834-a9e5-43b5-9f0a-824948c73c73">
    <field name="A1" class="java.lang.String">
      <fieldDescription><![CDATA[a1]]></fieldDescription>
    </field>
  </subDataset>
  <subDataset name="details2" uuid="f703cb76-2a4a-44f1-9a42-227e180038d2">
    <field name="A2" class="java.lang.String">
      <fieldDescription><![CDATA[a2]]></fieldDescription>
    </field>
  </subDataset>
  <queryString language="json">
    <![CDATA[]]>
  </queryString>
  <field name="A1" class="java.lang.String">
    <fieldDescription><![CDATA[a1]]></fieldDescription>
  </field>
  <field name="A2" class="java.lang.String">
    <fieldDescription><![CDATA[a2]]></fieldDescription>
  </field>
  <detail>
    <band height="99" splitType="Stretch">
      <textField>
        <reportElement x="72" y="16" width="100" height="24" uuid="698866c8-7d26-4bc7-8727-b4a56d239a53"/>
        <textFieldExpression><![CDATA[$F{A1}]]></textFieldExpression>
      </textField>
      <textField>
        <reportElement x="190" y="16" width="100" height="24" uuid="e775c6c0-4058-4bc4-8c7a-d4d381fd6e66"/>
        <textFieldExpression><![CDATA[$F{A2}]]></textFieldExpression>
      </textField>
      <componentElement>
        <reportElement x="90" y="40" width="333" height="20" uuid="c3237c70-6b2e-43e3-aa21-5092d8b91afc"/>
        <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="details1" uuid="f5fdc6a3-736f-43ce-b549-cd7332d19eb8">
            <dataSourceExpression><![CDATA[((net.sf.jasperreports.engine.data.JsonDataSource)$P{REPORT_DATA_SOURCE}).subDataSource("details1")]]></dataSourceExpression>
          </datasetRun>
          <jr:listContents height="20" width="333">
            <textField>
              <reportElement x="10" y="0" width="130" height="20" uuid="07e3ff2a-3832-4b06-9275-cb1ee8e51cfe"/>
              <textFieldExpression><![CDATA[$F{A1}]]></textFieldExpression>
            </textField>
          </jr:listContents>
        </jr:list>
      </componentElement>
      <componentElement>
        <reportElement x="90" y="60" width="333" height="20" uuid="38f3ac11-ad3e-464c-813a-46132f23783f"/>
        <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="details2" uuid="833a13c3-e9b8-4f56-9f8f-279d32d403e8">
            <dataSourceExpression><![CDATA[((net.sf.jasperreports.engine.data.JsonDataSource)$P{REPORT_DATA_SOURCE}).subDataSource("details2")]]></dataSourceExpression>
          </datasetRun>
          <jr:listContents height="20" width="333">
            <textField>
              <reportElement x="10" y="0" width="130" height="20" uuid="3d9fb513-bfc9-4d95-a3da-16b95cf15e7c"/>
              <textFieldExpression><![CDATA[$F{A2}]]></textFieldExpression>
            </textField>
          </jr:listContents>
        </jr:list>
      </componentElement>
    </band>
  </detail>
</jasperReport>

Upvotes: 8

Related Questions