I'm having issues accessing the array from my JSON data source. I'm using jasperreports 4.5.1.
My contact.json file:
{ "Person": { "FirstName": "John", "LastName": "Smith", "Contacts": [ { "Type":
"Cell", "Number": "555-555-5555" }, { "Type": "Home", "Number": "666-666-6666" }
] }
}
My contact.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="contact" language="groovy" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20">
<property name="ireport.zoom" value="2.0"/>
<property name="ireport.x" value="0"/>
<property name="ireport.y" value="0"/>
<subDataset name="Contactdataset">
<queryString language="json">
<![CDATA[]]>
</queryString>
<field name="Type" class="java.lang.String">
<property name="net.sf.jasperreports.json.field.expression" value="Type"/>
</field>
<field name="Number" class="java.lang.String">
<property name="net.sf.jasperreports.json.field.expression" value="Number"/>
</field>
</subDataset>
<queryString language="json">
<![CDATA[]]>
</queryString>
<field name="FirstName" class="java.lang.String">
<property name="net.sf.jasperreports.json.field.expression" value="Person.FirstName"/>
</field>
<field name="LastName" class="java.lang.String">
<property name="net.sf.jasperreports.json.field.expression" value="Person.LastName"/>
</field>
<detail>
<band height="300" splitType="Stretch">
<staticText>
<reportElement x="0" y="0" width="80" height="30"/>
<textElement/>
<text><![CDATA[First Name:]]></text>
</staticText>
<staticText>
<reportElement x="0" y="30" width="80" height="30"/>
<textElement/>
<text><![CDATA[Last Name:]]></text>
</staticText>
<textField>
<reportElement x="80" y="0" width="200" height="30"/>
<textElement/>
<textFieldExpression><![CDATA[$F{FirstName}]]></textFieldExpression>
</textField>
<textField>
<reportElement x="80" y="30" width="200" height="30"/>
<textElement/>
<textFieldExpression><![CDATA[$F{LastName}]]></textFieldExpression>
</textField>
<componentElement>
<reportElement x="130" y="166" width="150" height="23"/>
<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="Contactdataset">
<dataSourceExpression><![CDATA[((net.sf.jasperreports.engine.data.JsonDataSource)$P{REPORT_DATA_SOURCE}).subDataSource("Person.Contacts")]]></dataSourceExpression>
</datasetRun>
<jr:listContents height="23" width="150">
<textField>
<reportElement x="27" y="0" width="100" height="17"/>
<textElement/>
<textFieldExpression><![CDATA[$F{Type}]]></textFieldExpression>
</textField>
</jr:listContents>
</jr:list>
</componentElement>
<staticText>
<reportElement x="157" y="150" width="100" height="16"/>
<textElement/>
<text><![CDATA[Type]]></text>
</staticText>
</band>
</detail>
I also tried passing Contactdataset as :
<queryString language="json">
<![CDATA[Person.Contacts]]>
</queryString>
and passed that in the datasourceexpression like:
<dataSourceExpression><![CDATA[((net.sf.jasperreports.engine.data.JsonDataSource)$P{REPORT_DATA_SOURCE}).subDataSource("Contactdataset")]]></dataSourceExpression>
What I am doing wrong? I'm getting the following error:
net.sf.jasperreports.engine.fill.JRExpressionEvalException: Error evaluating expression :
Source text :
((net.sf.jasperreports.engine.data.JsonDataSource)$P{REPORT_DATA_SOURCE}).subDataSource("Person.Contacts")
In JasperReports 4.5.1 there was no subDataSource() method for the JsonDataSource. It was introduced in JasperReports 5.0.4.
As mentioned by #Narcis, the subDataSource() method for the JsonDataSource was introduced in JasperReports 5.0.4. and with this fact, you cannot use it in jasperreports 4.5.1. You should then try creating Main report and a Subreport. Add the field FirstName & LastName in the detail band of Main report and create a Subreport to iterate over the Contacts data. Add this Subreport on the detail band of Main report, select SubReport Poperties: "Use a datasource expression" and set below value for the datasource expression:
new net.sf.jasperreports.engine.data.JsonDataSource(new ByteArrayInputStream($F{Contacts}.toString().getBytes()),"")
In your Subreport, add Type & Number field and it would print the nested array accordingly, for every node of the main array.
Related
I am using jaspersoft studio 6.6.0 for my report, and i have json as a datasource for my report, in my report there is a field to display next port name based on condition of current port, but i am not able to display that, my json is as like this
"routingLocs": [
{
"callOrder": 1,
"locCode": "ZWTHJ",
"isCurrentLoc": "N"
},
{
"callOrder": 2,
"locCode": "TRYAR",
"isCurrentLoc": "Y"
},
{
"callOrder": 3,
"locCode": "AUABP",
"isCurrentLoc": "N"
},
{
"callOrder": 4,
"locCode": "RAJPI",
"isCurrentLoc": "N"
}
]
now i have to display locCode of object which is next to object that has isCurrentLoc = "Y", for this i have created one field with expression as
<![CDATA[routingLocs..locCode(^.isCurrentLoc == "Y")]]>
This expression is printing "TRYAR" instead of "AUABP"
My field definition in JRXML to display the value is
<field name="nextPort" class="java.lang.String">
<property name="net.sf.jasperreports.jsonql.field.expression">
<![CDATA[routingLocs..locCode(^.isCurrentLoc == "Y")]]>
</property>
<fieldDescription><![CDATA[nextPort]]></fieldDescription>
</field>
please help me to fix this expression
Thanks in advance for any kind of support
You cannot land on a sibling element with a jsonql query, but you can filter the JSON in a separate subDataset to achieve what you want.
Provided there is some order in your JSON data, like the ascending order of the callOrder, you can start creating your main dataset with your filtering query, something like:
<queryString language="jsonql">
<![CDATA[routingLocs.*(isCurrentLoc == "Y")]]>
</queryString>
Then create a subDataset that accepts a MAIN_CALL_ORDER parameter and that will use the same JSON data that your main does:
<subDataset name="nextPortDataset" uuid="a8b8a64f-4c6b-4c28-91db-e10f28cef52c">
<property name="net.sf.jasperreports.data.adapter" value="./DataAdapter.xml"/>
<parameter name="MAIN_CALL_ORDER" class="java.lang.Integer"/>
<queryString language="jsonql">
<![CDATA[routingLocs.*(callOrder > $P{MAIN_CALL_ORDER})[0]]]>
</queryString>
<field name="locCode" class="java.lang.String">
<property name="net.sf.jasperreports.json.field.expression" value="locCode"/>
<fieldDescription><![CDATA[locCode]]></fieldDescription>
</field>
</subDataset>
Here, the query will produce the first item that has the callOrder greater than the one sent from the main dataset.
Then this dataset should be linked to a list that will be passed the parameter like so:
<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="nextPortDataset" uuid="55c7173b-0b04-4d4f-bd80-48cfe1ef620c">
<datasetParameter name="MAIN_CALL_ORDER">
<datasetParameterExpression><![CDATA[$F{mainCallOrder}]]></datasetParameterExpression>
</datasetParameter>
</datasetRun>
<jr:listContents height="30" width="460">
<textField>
<reportElement x="230" y="0" width="115" height="30" uuid="213ab052-9cdc-419a-8d3d-45db3bf6ef90"/>
<textFieldExpression><![CDATA[$F{locCode}]]></textFieldExpression>
</textField>
</jr:listContents>
</jr:list>
A basic working JRXML would look like this:
<?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="e9573346-c7d0-4b7a-a838-d2ff5b7b9512">
<property name="net.sf.jasperreports.data.adapter" value="./DataAdapter.xml"/>
<subDataset name="nextPortDataset" uuid="a8b8a64f-4c6b-4c28-91db-e10f28cef52c">
<property name="net.sf.jasperreports.data.adapter" value="./DataAdapter.xml"/>
<parameter name="MAIN_CALL_ORDER" class="java.lang.Integer"/>
<queryString language="jsonql">
<![CDATA[routingLocs.*(callOrder > $P{MAIN_CALL_ORDER})[0]]]>
</queryString>
<field name="callOrder" class="java.lang.Integer">
<property name="net.sf.jasperreports.json.field.expression" value="callOrder"/>
<fieldDescription><![CDATA[callOrder]]></fieldDescription>
</field>
<field name="locCode" class="java.lang.String">
<property name="net.sf.jasperreports.json.field.expression" value="locCode"/>
<fieldDescription><![CDATA[locCode]]></fieldDescription>
</field>
<field name="isCurrentLoc" class="java.lang.String">
<property name="net.sf.jasperreports.json.field.expression" value="isCurrentLoc"/>
<fieldDescription><![CDATA[isCurrentLoc]]></fieldDescription>
</field>
</subDataset>
<queryString language="jsonql">
<![CDATA[routingLocs.*(isCurrentLoc == "Y")]]>
</queryString>
<field name="mainCallOrder" class="java.lang.Integer">
<property name="net.sf.jasperreports.jsonql.field.expression" value="callOrder"/>
<fieldDescription><![CDATA[mainCallOrder]]></fieldDescription>
</field>
<field name="mainLocCode" class="java.lang.String">
<property name="net.sf.jasperreports.jsonql.field.expression" value="locCode"/>
<fieldDescription><![CDATA[mainLocCode]]></fieldDescription>
</field>
<field name="mainIsCurrentLoc" class="java.lang.String">
<property name="net.sf.jasperreports.jsonql.field.expression" value="isCurrentLoc"/>
<fieldDescription><![CDATA[mainIsCurrentLoc]]></fieldDescription>
</field>
<background>
<band splitType="Stretch"/>
</background>
<title>
<band height="79" splitType="Stretch"/>
</title>
<pageHeader>
<band height="35" splitType="Stretch"/>
</pageHeader>
<columnHeader>
<band height="32" splitType="Stretch">
<staticText>
<reportElement x="115" y="0" width="115" height="30" uuid="4ec73015-1c44-441c-a80e-bff448923a29">
<property name="com.jaspersoft.studio.spreadsheet.connectionID" value="bff05bbe-0c73-4e55-adec-461fd0f2ebff"/>
</reportElement>
<text><![CDATA[callOrder]]></text>
</staticText>
<staticText>
<reportElement x="230" y="0" width="115" height="30" uuid="018825e6-aa24-4a11-85a4-760fa6cf913c">
<property name="com.jaspersoft.studio.spreadsheet.connectionID" value="cc7977d7-a541-4d3b-81d8-97be3451e130"/>
<property name="com.jaspersoft.studio.unit.width" value="px"/>
</reportElement>
<text><![CDATA[locCode]]></text>
</staticText>
<staticText>
<reportElement x="345" y="0" width="115" height="30" uuid="16e13486-0a34-4c65-b512-00a4678c65f7">
<property name="com.jaspersoft.studio.spreadsheet.connectionID" value="82e0773c-3e7d-4372-a44c-93a4bfcfd6b0"/>
</reportElement>
<text><![CDATA[isCurrentLoc]]></text>
</staticText>
<staticText>
<reportElement x="0" y="2" width="60" height="30" uuid="ad4e4685-2696-472c-a3b6-4a9961aeb6dc">
<property name="com.jaspersoft.studio.spreadsheet.connectionID" value="bff05bbe-0c73-4e55-adec-461fd0f2ebff"/>
</reportElement>
<text><![CDATA[Main Dataset]]></text>
</staticText>
</band>
</columnHeader>
<detail>
<band height="110" splitType="Stretch">
<textField>
<reportElement x="115" y="0" width="115" height="30" uuid="3bffc0f6-fb80-443a-b06d-ebbe2b669388">
<property name="com.jaspersoft.studio.spreadsheet.connectionID" value="bff05bbe-0c73-4e55-adec-461fd0f2ebff"/>
</reportElement>
<textFieldExpression><![CDATA[$F{mainCallOrder}]]></textFieldExpression>
</textField>
<textField>
<reportElement x="230" y="0" width="115" height="30" uuid="1267f406-8492-4dd1-859a-a37f24ac545a">
<property name="com.jaspersoft.studio.spreadsheet.connectionID" value="cc7977d7-a541-4d3b-81d8-97be3451e130"/>
</reportElement>
<textFieldExpression><![CDATA[$F{mainLocCode}]]></textFieldExpression>
</textField>
<textField>
<reportElement x="345" y="0" width="115" height="30" uuid="522f3a23-a2b4-443d-9ca5-9abbd54a07df">
<property name="com.jaspersoft.studio.spreadsheet.connectionID" value="82e0773c-3e7d-4372-a44c-93a4bfcfd6b0"/>
</reportElement>
<textFieldExpression><![CDATA[$F{mainIsCurrentLoc}]]></textFieldExpression>
</textField>
<componentElement>
<reportElement x="0" y="80" width="560" height="30" uuid="859af22b-90ec-41fb-acf0-36d4acf2b90a"/>
<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="nextPortDataset" uuid="55c7173b-0b04-4d4f-bd80-48cfe1ef620c">
<datasetParameter name="MAIN_CALL_ORDER">
<datasetParameterExpression><![CDATA[$F{mainCallOrder}]]></datasetParameterExpression>
</datasetParameter>
</datasetRun>
<jr:listContents height="30" width="560">
<staticText>
<reportElement x="0" y="0" width="100" height="30" uuid="6db9b791-aaac-45e9-af0f-34546254b9e9"/>
<text><![CDATA[Filtering List]]></text>
</staticText>
<textField>
<reportElement x="115" y="0" width="115" height="30" uuid="ee03e48b-38dd-4814-ad7d-2549810c0991">
<property name="com.jaspersoft.studio.unit.x" value="px"/>
</reportElement>
<textFieldExpression><![CDATA[$F{callOrder}]]></textFieldExpression>
</textField>
<textField>
<reportElement x="230" y="0" width="115" height="30" uuid="213ab052-9cdc-419a-8d3d-45db3bf6ef90"/>
<textFieldExpression><![CDATA[$F{locCode}]]></textFieldExpression>
</textField>
<textField>
<reportElement x="345" y="0" width="115" height="30" uuid="a8ea32ea-150f-4d1f-8945-18c2b287c157"/>
<textFieldExpression><![CDATA[$F{isCurrentLoc}]]></textFieldExpression>
</textField>
</jr:listContents>
</jr:list>
</componentElement>
</band>
</detail>
</jasperReport>
and produce the following output:
This sample needs a file-based data adapter that is linked to both main dataset and subDataset with this property:
<property name="net.sf.jasperreports.data.adapter" value="./DataAdapter.xml"/>
If you don't have a file-based data adapter, you could create one and export it to file from the Repository Explorer inside Jaspersoft Studio.
Let's assume we have this JSON:
{
"header" : "some header",
"strings": [
"foo",
"bar",
"baz"
]
}
And we want to display it in jasper report - header as a textfield, and the array in a list.
This is the report, which has access the array, but does not display all the elements of it - only first of them appears.
<?xml version="1.0" encoding="UTF-8"?>
<!-- Created with Jaspersoft Studio version 6.17.0.final using JasperReports Library version 6.17.0-6d93193241dd8cc42629e188b94f9e0bc5722efd -->
<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="sample" pageWidth="595" pageHeight="100" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" isIgnorePagination="true" uuid="6c570f43-054a-44a9-a9b1-ba4cf2cdcf86">
<property name="com.jaspersoft.studio.data.defaultdataadapter" value="json-sample"/>
<subDataset name="ListDataSet" uuid="fb812d2a-cb63-473c-b7d3-149977476dd0">
<field name="val" class="java.lang.String">
<property name="net.sf.jasperreports.jsonql.field.expression" value="strings.*"/>
</field>
</subDataset>
<queryString language="jsonql">
<![CDATA[]]>
</queryString>
<field name="header" class="java.lang.String">
<property name="net.sf.jasperreports.jsonql.field.expression" value="header"/>
<fieldDescription><![CDATA[header]]></fieldDescription>
</field>
<field name="strings" class="java.lang.String">
<property name="net.sf.jasperreports.jsonql.field.expression" value="strings"/>
<fieldDescription><![CDATA[strings]]></fieldDescription>
</field>
<background>
<band splitType="Stretch"/>
</background>
<pageHeader>
<band height="30" splitType="Stretch">
<textField>
<reportElement x="0" y="0" width="100" height="30" uuid="d98a55eb-ebbd-4cdd-8fa2-ae052b124aaa"/>
<textFieldExpression><![CDATA[$F{header}]]></textFieldExpression>
</textField>
</band>
</pageHeader>
<detail>
<band height="30" splitType="Stretch">
<componentElement>
<reportElement x="0" y="0" width="450" height="30" uuid="887dc258-2eac-4492-ae69-f9b2ffd1faee">
<property name="com.jaspersoft.studio.unit.CONTENTS.width" value="px"/>
</reportElement>
<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="Horizontal">
<datasetRun subDataset="ListDataSet" uuid="1316cfd7-fe59-440f-a155-501914c00056">
<dataSourceExpression><![CDATA[((net.sf.jasperreports.engine.data.JsonQLDataSource)($P{REPORT_DATA_SOURCE})).subDataSource()]]></dataSourceExpression>
</datasetRun>
<jr:listContents height="30" width="100">
<textField>
<reportElement x="0" y="0" width="90" height="30" uuid="4ee2d6b3-c681-433f-a170-4bb31697de58"/>
<textFieldExpression><![CDATA[$F{val}]]></textFieldExpression>
</textField>
</jr:listContents>
</jr:list>
</componentElement>
</band>
</detail>
</jasperReport>
This is how the result looks like:
What is wrong with the report?
Your fields could be updated a little:
$F{header} => java.lang.String
$F{strings} => java.util.List - this makes it possible to use this field as the datasource for a subcomponent.
Then when you pass in the Datasource, just pass in the list:
new JRBeanCollectionDatasource($F{strings})
or new JRBeanArrayDatasource($F{strings})
For you List data set I would just:
$F{_THIS} => java.lang.String - I'm not sure if val works well, but I know for sure that _THIS works (both 5.2 and 6.3)
I'll try to post the JRXML if you need it.
I got the following json
{
"data": [
{
"name": "apple",
"sorts": [
{ "name": "green", "number": "6", "comment": "green apples are nice" },
{ "name": "yellow", "number": "1" },
{ "name": "red", "number": "2" }
]
},
{
"name": "banana",
"sorts": [
]
},
{
"name": "pear",
"sorts": [
{ "name": "green", "number": "6", "comment": "green pears are sour" },
{ "name": "purple", "number": "0", "comment": "so far we haven't seen purple pears" }
]
}
]
}
This is result I want:
I created this with 2 nested list and passing the name to the nested list.
This works well, but now I want to color the odd list items. That would be the Yellow Apples and Green Pears. I found some example on how to do that on a simple list, but I have a nested list so that won't work.
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="Blank_A4" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20">
<subDataset name="DatasetFruits">
<queryString language="JSON">
<![CDATA[data]]>
</queryString>
<field name="name" class="java.lang.String">
<property name="net.sf.jasperreports.json.field.expression" value="name"/>
<fieldDescription><![CDATA[name]]></fieldDescription>
</field>
<field name="sorts" class="java.lang.String">
<property name="net.sf.jasperreports.json.field.expression" value="sorts"/>
<fieldDescription><![CDATA[sorts]]></fieldDescription>
</field>
</subDataset>
<subDataset name="DatasetFruitsSort">
<parameter name="FRUIT_NAME" class="java.lang.String"/>
<queryString language="JSON">
<![CDATA[data.sorts]]>
</queryString>
<field name="name" class="java.lang.String">
<property name="net.sf.jasperreports.json.field.expression" value="name"/>
<fieldDescription><![CDATA[name]]></fieldDescription>
</field>
<field name="number" class="java.lang.Integer">
<property name="net.sf.jasperreports.json.field.expression" value="number"/>
<fieldDescription><![CDATA[number]]></fieldDescription>
</field>
<field name="comment" class="java.lang.String">
<property name="net.sf.jasperreports.json.field.expression" value="comment"/>
<fieldDescription><![CDATA[comment]]></fieldDescription>
</field>
</subDataset>
<detail>
<band height="125" splitType="Stretch">
<componentElement>
<reportElement x="-20" y="43" width="595" height="30"/>
<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">
<datasetRun subDataset="DatasetFruits">
<dataSourceExpression><![CDATA[((net.sf.jasperreports.engine.data.JsonDataSource)$P{REPORT_DATA_SOURCE}).subDataSource("data")]]></dataSourceExpression>
</datasetRun>
<jr:listContents height="30" width="595">
<componentElement>
<reportElement x="0" y="0" width="595" height="30" isRemoveLineWhenBlank="true">
<printWhenExpression><![CDATA[!$F{sorts}.equals("[]")]]></printWhenExpression>
</reportElement>
<jr:list>
<datasetRun subDataset="DatasetFruitsSort">
<datasetParameter name="FRUIT_NAME">
<datasetParameterExpression><![CDATA[$F{name}]]></datasetParameterExpression>
</datasetParameter>
<dataSourceExpression><![CDATA[((net.sf.jasperreports.engine.data.JsonDataSource)$P{REPORT_DATA_SOURCE}).subDataSource("sorts")]]></dataSourceExpression>
</datasetRun>
<jr:listContents height="30" width="595">
<textField>
<reportElement x="0" y="0" width="100" height="30"/>
<textFieldExpression><![CDATA[$P{FRUIT_NAME}]]></textFieldExpression>
</textField>
<textField>
<reportElement x="180" y="0" width="100" height="30"/>
<textFieldExpression><![CDATA[$F{number}]]></textFieldExpression>
</textField>
<textField isBlankWhenNull="true">
<reportElement x="400" y="0" width="190" height="30"/>
<textFieldExpression><![CDATA[$F{comment}]]></textFieldExpression>
</textField>
</jr:listContents>
</jr:list>
</componentElement>
</jr:listContents>
</jr:list>
</componentElement>
</band>
</detail>
</jasperReport>
If you're using JasperReports 6.3.1 or newer, the simplest solution is to switch to JSONQL and use a single list instead of nested lists. You can read about JSONQL data sources here.
With JSONQL you can have a single list that iterates over all data.sorts.* nodes and get the fruit name via a field that goes up the tree. Then with a single list you can have a simple conditional style to color odd rows.
The whole thing would look something like this:
<?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="Blank_A4" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="af456afc-4615-4564-8841-81929ce2447f">
<property name="com.jaspersoft.studio.data.defaultdataadapter" value="Adapter"/>
<style name="listRow">
<conditionalStyle>
<conditionExpression><![CDATA[$V{REPORT_COUNT} % 2 == 0]]></conditionExpression>
<style mode="Opaque" backcolor="#FFFF00"/>
</conditionalStyle>
</style>
<subDataset name="DatasetFruitsSortAll" uuid="5961129e-70f0-4d98-8d4e-524f2bbb28f9">
<property name="com.jaspersoft.studio.data.defaultdataadapter" value="Adapter"/>
<queryString language="JSONQL">
<![CDATA[data.sorts]]>
</queryString>
<field name="fruitName" class="java.lang.String">
<property name="net.sf.jasperreports.jsonql.field.expression" value="^^.name"/>
<fieldDescription><![CDATA[fruitName]]></fieldDescription>
</field>
<field name="name" class="java.lang.String">
<property name="net.sf.jasperreports.json.field.expression" value="name"/>
<fieldDescription><![CDATA[name]]></fieldDescription>
</field>
<field name="number" class="java.lang.Integer">
<property name="net.sf.jasperreports.json.field.expression" value="number"/>
<fieldDescription><![CDATA[number]]></fieldDescription>
</field>
<field name="comment" class="java.lang.String">
<property name="net.sf.jasperreports.json.field.expression" value="comment"/>
<fieldDescription><![CDATA[comment]]></fieldDescription>
</field>
</subDataset>
<queryString language="JSONQL">
<![CDATA[]]>
</queryString>
<detail>
<band height="125" splitType="Stretch">
<componentElement>
<reportElement x="0" y="0" width="595" height="30" isRemoveLineWhenBlank="true" uuid="c4206620-ee0d-4e50-9336-1e1be2723c6f"/>
<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="DatasetFruitsSortAll" uuid="b9df9d8f-7ada-47eb-84e6-4870547e7bd9">
<dataSourceExpression><![CDATA[((net.sf.jasperreports.engine.data.JsonQLDataSource)$P{REPORT_DATA_SOURCE}).subDataSource("data.sorts.*")]]></dataSourceExpression>
</datasetRun>
<jr:listContents height="30" width="595">
<frame>
<reportElement style="listRow" x="0" y="0" width="590" height="30" uuid="3b3fba3d-e4c5-499c-a752-b6caa847a448"/>
<textField>
<reportElement x="0" y="0" width="100" height="30" uuid="bd3ac2b2-1803-4e0f-afa8-a0bdcc54e6fb"/>
<textFieldExpression><![CDATA[$F{fruitName}]]></textFieldExpression>
</textField>
<textField>
<reportElement x="180" y="0" width="100" height="30" uuid="be871dcb-61a0-49bd-b565-af8aa27bc7f4"/>
<textFieldExpression><![CDATA[$F{number}]]></textFieldExpression>
</textField>
<textField isBlankWhenNull="true">
<reportElement x="400" y="0" width="190" height="30" uuid="bea6dae7-bca2-4c0a-a0b5-443a859c20ac"/>
<textFieldExpression><![CDATA[$F{comment}]]></textFieldExpression>
</textField>
</frame>
</jr:listContents>
</jr:list>
</componentElement>
</band>
</detail>
</jasperReport>
If for some reason JSONQL or a single list do not suit you, you can color odd rows with nested lists by having a running row number in the nested list. To do that you'd need to pass the value forth and back to/from the nested subdataset via a parameter and a return value.
This is how the whole report would look like. The nesting subdataset has a variable called subRowCount which keeps the row count of the previous nested subdataset runs. The variable is passed to the nesteed subdataset via a parameter; the subdataset adds it to the current row number and uses the result in the conditional style. Then the final row count is returned back into the subRowCount variable.
<?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="Blank_A4" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="af456afc-4615-4564-8841-81929ce2447f">
<property name="com.jaspersoft.studio.data.defaultdataadapter" value="Adapter"/>
<style name="listRow">
<conditionalStyle>
<conditionExpression><![CDATA[$V{runningRowCount} % 2 == 0]]></conditionExpression>
<style mode="Opaque" backcolor="#FFFF00"/>
</conditionalStyle>
</style>
<subDataset name="DatasetFruits" uuid="5824cf79-a97e-4cf1-954b-cc0c327c8405">
<property name="com.jaspersoft.studio.data.defaultdataadapter" value="Adapter"/>
<queryString language="JSON">
<![CDATA[data]]>
</queryString>
<field name="name" class="java.lang.String">
<property name="net.sf.jasperreports.json.field.expression" value="name"/>
<fieldDescription><![CDATA[name]]></fieldDescription>
</field>
<field name="sorts" class="java.lang.String">
<property name="net.sf.jasperreports.json.field.expression" value="sorts"/>
<fieldDescription><![CDATA[sorts]]></fieldDescription>
</field>
<variable name="subRowCount" class="java.lang.Integer" calculation="System">
<initialValueExpression><![CDATA[0]]></initialValueExpression>
</variable>
</subDataset>
<subDataset name="DatasetFruitsSort" uuid="5961129e-70f0-4d98-8d4e-524f2bbb28f9">
<property name="com.jaspersoft.studio.data.defaultdataadapter" value="Adapter"/>
<parameter name="FRUIT_NAME" class="java.lang.String"/>
<parameter name="prevRowCount" class="java.lang.Integer"/>
<queryString language="JSON">
<![CDATA[data.sorts]]>
</queryString>
<field name="name" class="java.lang.String">
<property name="net.sf.jasperreports.json.field.expression" value="name"/>
<fieldDescription><![CDATA[name]]></fieldDescription>
</field>
<field name="number" class="java.lang.Integer">
<property name="net.sf.jasperreports.json.field.expression" value="number"/>
<fieldDescription><![CDATA[number]]></fieldDescription>
</field>
<field name="comment" class="java.lang.String">
<property name="net.sf.jasperreports.json.field.expression" value="comment"/>
<fieldDescription><![CDATA[comment]]></fieldDescription>
</field>
<variable name="runningRowCount" class="java.lang.Integer">
<variableExpression><![CDATA[$P{prevRowCount} + $V{REPORT_COUNT}]]></variableExpression>
</variable>
</subDataset>
<queryString language="json">
<![CDATA[]]>
</queryString>
<detail>
<band height="125" splitType="Stretch">
<componentElement>
<reportElement x="-20" y="43" width="595" height="30" uuid="da841d21-e910-4ce3-b415-1c68cade0981"/>
<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="DatasetFruits" uuid="4baf7682-130d-4b12-a973-8ab6084373de">
<dataSourceExpression><![CDATA[((net.sf.jasperreports.engine.data.JsonDataSource)$P{REPORT_DATA_SOURCE}).subDataSource("data")]]></dataSourceExpression>
</datasetRun>
<jr:listContents height="30" width="595">
<componentElement>
<reportElement x="0" y="0" width="595" height="30" isRemoveLineWhenBlank="true" uuid="c4206620-ee0d-4e50-9336-1e1be2723c6f">
<printWhenExpression><![CDATA[!$F{sorts}.equals("[]")]]></printWhenExpression>
</reportElement>
<jr:list printOrder="Vertical">
<datasetRun subDataset="DatasetFruitsSort" uuid="b9df9d8f-7ada-47eb-84e6-4870547e7bd9">
<datasetParameter name="FRUIT_NAME">
<datasetParameterExpression><![CDATA[$F{name}]]></datasetParameterExpression>
</datasetParameter>
<datasetParameter name="prevRowCount">
<datasetParameterExpression><![CDATA[$V{subRowCount}]]></datasetParameterExpression>
</datasetParameter>
<dataSourceExpression><![CDATA[((net.sf.jasperreports.engine.data.JsonDataSource)$P{REPORT_DATA_SOURCE}).subDataSource("sorts")]]></dataSourceExpression>
<returnValue fromVariable="runningRowCount" toVariable="subRowCount"/>
</datasetRun>
<jr:listContents height="30" width="595">
<frame>
<reportElement style="listRow" x="0" y="0" width="590" height="30" uuid="3b3fba3d-e4c5-499c-a752-b6caa847a448"/>
<textField>
<reportElement x="0" y="0" width="100" height="30" uuid="bd3ac2b2-1803-4e0f-afa8-a0bdcc54e6fb"/>
<textFieldExpression><![CDATA[$P{FRUIT_NAME}]]></textFieldExpression>
</textField>
<textField>
<reportElement x="180" y="0" width="100" height="30" uuid="be871dcb-61a0-49bd-b565-af8aa27bc7f4"/>
<textFieldExpression><![CDATA[$F{number}]]></textFieldExpression>
</textField>
<textField isBlankWhenNull="true">
<reportElement x="400" y="0" width="190" height="30" uuid="bea6dae7-bca2-4c0a-a0b5-443a859c20ac"/>
<textFieldExpression><![CDATA[$F{comment}]]></textFieldExpression>
</textField>
</frame>
</jr:listContents>
</jr:list>
</componentElement>
</jr:listContents>
</jr:list>
</componentElement>
</band>
</detail>
</jasperReport>
JasperReports generate null to table cell if this value is not defined in table scope, but defined globally.
At the top of the report I have defined variables:
<subDataset name="Dataset1" uuid="c145c0b0-641e-4a32-8e07-265189715ef9">
<property name="com.jaspersoft.studio.data.defaultdataadapter" value="data\JSONDdapterNew.xml"/>
<queryString language="json">
<![CDATA[]]>
</queryString>
<field name="groupName" class="java.lang.String">
<fieldDescription><![CDATA[groupName]]></fieldDescription>
</field>
<field name="elementName" class="java.lang.String">
<fieldDescription><![CDATA[elementName]]></fieldDescription>
</field>
<field name="elementValue" class="java.lang.String">
<fieldDescription><![CDATA[elementValue]]></fieldDescription>
</field>
</subDataset>
Then I pass they to the Jasper table (markup simplified without dropping sense):
<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="Dataset1" uuid="db1f69ee-c0db-4ece-aacb-a181465bdc79">
<dataSourceExpression><![CDATA[((net.sf.jasperreports.engine.data.JsonDataSource)$P{REPORT_DATA_SOURCE}).subDataSource("elements")]]></dataSourceExpression>
</datasetRun>
<jr:column width="220" uuid="09e23518-5d7f-45d9-9a22-c4b537f0d83f">
<jr:detailCell style="Table 2_TD" height="18">
<textField isStretchWithOverflow="true">
<reportElement stretchType="RelativeToBandHeight" x="0" y="0" width="220" height="18" uuid="4d0b54e7-584e-4cc9-86f2-59d72b600f1b"/>
<textElement verticalAlignment="Middle">
<font size="9"/>
<paragraph leftIndent="5"/>
</textElement>
<textFieldExpression><![CDATA[$F{groupName}]]></textFieldExpression>
</textField>
</jr:detailCell>
</jr:column>
<jr:column width="220" uuid="09e23518-5d7f-45d9-9a22-c4b537f0d83f">
<jr:detailCell style="Table 2_TD" height="18">
<textField isStretchWithOverflow="true">
<reportElement stretchType="RelativeToBandHeight" x="0" y="0" width="220" height="18" uuid="4d0b54e7-584e-4cc9-86f2-59d72b600f1b"/>
<textElement verticalAlignment="Middle">
<font size="9"/>
<paragraph leftIndent="5"/>
</textElement>
<textFieldExpression><![CDATA[$F{elementName}]]></textFieldExpression>
</textField>
</jr:detailCell>
</jr:column>
<jr:column width="220" uuid="09e23518-5d7f-45d9-9a22-c4b537f0d83f">
<jr:detailCell style="Table 2_TD" height="18">
<property name="com.jaspersoft.studio.unit.width" value="px"/>
<textField isStretchWithOverflow="true">
<reportElement stretchType="RelativeToBandHeight" x="0" y="0" width="220" height="18" uuid="4d0b54e7-584e-4cc9-86f2-59d72b600f1b"/>
<textElement verticalAlignment="Middle">
<font size="9"/>
<paragraph leftIndent="5"/>
</textElement>
<textFieldExpression><![CDATA[$F{elementValue}]]></textFieldExpression>
</textField>
</jr:detailCell>
</jr:column>
</jr:table>
Example for input json:
[
{
"groupName" : "Group1",
"elements" : [
{
"elementName" : "el11",
"elementValue" : "evl1"
},
{
"elementName" : "el12",
"elementValue" : "evl2"
}
]
},
{
"groupName" : "Group2",
"elements" : [
{
"elementName" : "el21",
"elementValue" : "ev21"
},
{
"elementName" : "el22",
"elementValue" : "ev22"
}
]
}
]
As result I see values for elementName and elementValue, but for groupName I see null. I want to see something like that:
Group1 | el11 | ev11 |
Group1 | el12 | ev12 |
Group2 | el21 | ev21 |
Group2 | el22 | ev22 |
If you really must use a table element and you have it in the Detail band, you could pass the groupName as a parameter to the table dataset:
First, you would add the groupName field to the main dataset:
<queryString language="json">
<![CDATA[]]>
</queryString>
<field name="groupName" class="java.lang.String">
<fieldDescription><![CDATA[groupName]]></fieldDescription>
</field>
The subDataset would become:
<subDataset name="Dataset1" uuid="c145c0b0-641e-4a32-8e07-265189715ef9">
<property name="com.jaspersoft.studio.data.defaultdataadapter" value="data\JSONDdapterNew.xml"/>
<queryString language="json">
<![CDATA[]]>
</queryString>
<parameter name="groupNameParam" class="java.lang.String"/>
<field name="elementName" class="java.lang.String">
<fieldDescription><![CDATA[elementName]]></fieldDescription>
</field>
<field name="elementValue" class="java.lang.String">
<fieldDescription><![CDATA[elementValue]]></fieldDescription>
</field>
</subDataset>
The table datasetRun would become:
<datasetRun subDataset="Dataset1" uuid="db1f69ee-c0db-4ece-aacb-a181465bdc79">
<datasetParameter name="groupNameParam">
<datasetParameterExpression><![CDATA[$F{groupName}]]></datasetParameterExpression>
</datasetParameter>
<dataSourceExpression><![CDATA[((net.sf.jasperreports.engine.data.JsonDataSource)$P{REPORT_DATA_SOURCE}).subDataSource("elements")]]></dataSourceExpression>
</datasetRun>
And then your textFieldExpression would go from $F{groupName} to $P{groupNameParam}.
The easier solution, that does not rely on a table element, would involve switching to the newer JSONQL(stable in Jaspersoft Studio since v6.4.0) language that allows traversals up the JSON tree:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Created with Jaspersoft Studio version 6.9.0.final using JasperReports Library version 6.9.0-cb8f9004be492ccc537180b49c026951f4220bf3 -->
<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_v3" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="5c8f0a97-e66c-4103-8305-10e7cefe9ca2">
<queryString language="jsonql">
<![CDATA[elements.*]]>
</queryString>
<field name="groupName" class="java.lang.String">
<property name="net.sf.jasperreports.jsonql.field.expression" value="^^.groupName"/>
<fieldDescription><![CDATA[Group Name]]></fieldDescription>
</field>
<field name="elementName" class="java.lang.String">
<property name="net.sf.jasperreports.jsonql.field.expression" value="elementName"/>
<fieldDescription><![CDATA[Element Name]]></fieldDescription>
</field>
<field name="elementValue" class="java.lang.String">
<property name="net.sf.jasperreports.jsonql.field.expression" value="elementValue"/>
<fieldDescription><![CDATA[Element Value]]></fieldDescription>
</field>
<columnHeader>
<band height="30" splitType="Stretch">
<staticText>
<reportElement x="0" y="0" width="185" height="30" uuid="ef173e64-d7d6-4afd-abba-9ad32bf204b6">
<property name="com.jaspersoft.studio.spreadsheet.connectionID" value="b7c69e0c-11ed-4881-93c1-dd83cefb5d4c"/>
</reportElement>
<text><![CDATA[Group Name]]></text>
</staticText>
<staticText>
<reportElement x="185" y="0" width="185" height="30" uuid="cd0d90cb-2ced-4f52-becb-7e171c0e7824">
<property name="com.jaspersoft.studio.spreadsheet.connectionID" value="cef61be1-0d90-4575-8b39-00b300c52204"/>
</reportElement>
<text><![CDATA[Element Name]]></text>
</staticText>
<staticText>
<reportElement x="370" y="0" width="185" height="30" uuid="7bee32cf-b618-489d-bb81-014d410ba074">
<property name="com.jaspersoft.studio.spreadsheet.connectionID" value="9a5a388b-f4ea-48dd-9b4f-82a7c58b2c22"/>
</reportElement>
<text><![CDATA[Element Value]]></text>
</staticText>
</band>
</columnHeader>
<detail>
<band height="30" splitType="Stretch">
<textField>
<reportElement x="0" y="0" width="185" height="30" uuid="6866d5da-c4a4-4ae3-af9f-19d29e3d28dc">
<property name="com.jaspersoft.studio.spreadsheet.connectionID" value="b7c69e0c-11ed-4881-93c1-dd83cefb5d4c"/>
</reportElement>
<textFieldExpression><![CDATA[$F{groupName}]]></textFieldExpression>
</textField>
<textField>
<reportElement x="185" y="0" width="185" height="30" uuid="87262f8a-1548-44a3-887e-e916aa551eab">
<property name="com.jaspersoft.studio.spreadsheet.connectionID" value="cef61be1-0d90-4575-8b39-00b300c52204"/>
</reportElement>
<textFieldExpression><![CDATA[$F{elementName}]]></textFieldExpression>
</textField>
<textField>
<reportElement x="370" y="0" width="185" height="30" uuid="7bf9a789-1f10-4986-abd7-aa7c57bd1b9c">
<property name="com.jaspersoft.studio.spreadsheet.connectionID" value="9a5a388b-f4ea-48dd-9b4f-82a7c58b2c22"/>
</reportElement>
<textFieldExpression><![CDATA[$F{elementValue}]]></textFieldExpression>
</textField>
</band>
</detail>
</jasperReport>
This is similar to previous questions, but it has me stumped. I'm using Studio 6.5.1 CE version. So I have json data in a file that starts
{
"users": {
"itemCount": 30,
"items": [{
"id": 1,
"username": "user1",
...
My main json query is blank, with a single field defined: itemCount with expression "users.itemCount".
I have a Details band table and "UserDataset" with jsonql query "users.items". There are fields "id" with expression "id", "username" with expression "username", etc. Data preview shows the fields accurately.
When running the report I do see the single itemCount field populated. The problem is the table is missing. Apparently I cannot successfully tie the Datasource to the table. I have tried all sorts of expressions, and I thought something like this should work:
<datasetRun...>
...
<dataSourceExpression><![CDATA[((net.sf.jasperreports.engine.data.JsonDataSource)$P{REPORT_CONNECTION}).subDataSource("users.items")]]></dataSourceExpression>
</datasetRun>
However, I can never get the table populated. What am I doing wrong? (I have similar report formats with jdbc sources and I have no problem with those tables.)
I can't find any combination of query/expression that works, so I am appending the jrxml file with style info stripped out for viewing.
<?xml version="1.0" encoding="UTF-8"?>
<!-- Created with Jaspersoft Studio version 6.5.1.final using JasperReports Library version 6.5.1 -->
<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="Users" pageWidth="792" pageHeight="612" orientation="Landscape" columnWidth="752" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" isIgnorePagination="true" uuid="61928541-d006-4374-9164-985c6c4116c9">
<property name="com.jaspersoft.studio.data.defaultdataadapter" value="Users.json"/>
<subDataset name="UserDataset" uuid="effd13cd-71de-4771-b706-d68b1042b564">
<property name="com.jaspersoft.studio.data.defaultdataadapter" value="Users.json"/>
<queryString language="jsonql">
<![CDATA[users.items]]>
</queryString>
<field name="id" class="java.lang.Integer">
<property name="net.sf.jasperreports.jsonql.field.expression" value="id"/>
<fieldDescription><![CDATA[id]]></fieldDescription>
</field>
<field name="username" class="java.lang.String">
<property name="net.sf.jasperreports.jsonql.field.expression" value="username"/>
<fieldDescription><![CDATA[username]]></fieldDescription>
</field>
</subDataset>
<queryString language="jsonql">
<![CDATA[]]>
</queryString>
<field name="itemCount" class="java.lang.Integer">
<property name="net.sf.jasperreports.jsonql.field.expression" value="users.itemCount"/>
<fieldDescription><![CDATA[itemCount]]></fieldDescription>
</field>
<detail>
<band height="116" splitType="Stretch">
<componentElement>
<reportElement x="-9" y="50" width="770" height="62" uuid="7d7f19b0-9800-43ab-86a4-45846dae7775">
<property name="com.jaspersoft.studio.layout" value="com.jaspersoft.studio.editor.layout.VerticalRowLayout"/>
<property name="com.jaspersoft.studio.table.style.table_header" value="Table_TH"/>
<property name="com.jaspersoft.studio.table.style.column_header" value="Table_CH"/>
<property name="com.jaspersoft.studio.table.style.detail" value="Table_TD"/>
</reportElement>
<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="UserDataset" uuid="fdfe69e2-eeac-4287-9e41-4c39610a79be">
<datasetParameter name="JSON_INPUT_STREAM">
<datasetParameterExpression><![CDATA[$P{JSON_INPUT_STREAM}]]></datasetParameterExpression>
</datasetParameter>
<datasetParameter name="net.sf.jasperreports.json.source">
<datasetParameterExpression><![CDATA[$P{net.sf.jasperreports.json.source}]]></datasetParameterExpression>
</datasetParameter>
<datasetParameter name="net.sf.jasperreports.json.sources">
<datasetParameterExpression><![CDATA[$P{net.sf.jasperreports.json.sources}]]></datasetParameterExpression>
</datasetParameter>
<datasetParameter name="net.sf.jasperreports.json.date.pattern">
<datasetParameterExpression><![CDATA[$P{net.sf.jasperreports.json.date.pattern}]]></datasetParameterExpression>
</datasetParameter>
<datasetParameter name="net.sf.jasperreports.json.number.pattern">
<datasetParameterExpression><![CDATA[$P{net.sf.jasperreports.json.number.pattern}]]></datasetParameterExpression>
</datasetParameter>
<datasetParameter name="JSON_LOCALE">
<datasetParameterExpression><![CDATA[$P{JSON_LOCALE}]]></datasetParameterExpression>
</datasetParameter>
<datasetParameter name="net.sf.jasperreports.json.locale.code">
<datasetParameterExpression><![CDATA[$P{net.sf.jasperreports.json.locale.code}]]></datasetParameterExpression>
</datasetParameter>
<datasetParameter name="JSON_TIME_ZONE">
<datasetParameterExpression><![CDATA[$P{JSON_TIME_ZONE}]]></datasetParameterExpression>
</datasetParameter>
<datasetParameter name="net.sf.jasperreports.json.timezone.id">
<datasetParameterExpression><![CDATA[$P{net.sf.jasperreports.json.timezone.id}]]></datasetParameterExpression>
</datasetParameter>
<dataSourceExpression><![CDATA[((net.sf.jasperreports.engine.data.JsonDataSource)$P{REPORT_CONNECTION}).subDataSource("users.items")]]></dataSourceExpression>
</datasetRun>
<jr:column width="30" uuid="65fed6e9-ae42-4e04-b0b4-e2c8ef4a1b27">
<property name="com.jaspersoft.studio.components.table.model.column.name" value="Column1"/>
<jr:columnHeader style="Table_CH" height="30" rowSpan="1">
<staticText>
<reportElement x="0" y="0" width="30" height="30" uuid="becae13f-4af9-4884-9b38-ab19347e9455"/>
<text><![CDATA[USER_ID]]></text>
</staticText>
</jr:columnHeader>
<jr:detailCell style="Table_TD" height="30">
<textField>
<reportElement x="0" y="0" width="30" height="30" uuid="8c6b26dc-c436-4e68-acd5-89c33e09dac6"/>
<textFieldExpression><![CDATA[$F{id}]]></textFieldExpression>
</textField>
</jr:detailCell>
</jr:column>
<jr:column width="90" uuid="224b44e6-a9c2-4407-891d-623c7d6b33dc">
<property name="com.jaspersoft.studio.components.table.model.column.name" value="Column2"/>
<jr:columnHeader style="Table_CH" height="30" rowSpan="1">
<staticText>
<reportElement x="0" y="0" width="90" height="30" uuid="3c961dd1-f991-4cde-9d22-224d4f3ae86c"/>
<text><![CDATA[USERNAME]]></text>
</staticText>
</jr:columnHeader>
<jr:detailCell style="Table_TD" height="30">
<textField>
<reportElement x="0" y="0" width="90" height="30" uuid="3acbeee1-e7a4-4f45-b54c-b10c69bf7a95"/>
<textFieldExpression><![CDATA[$F{username}]]></textFieldExpression>
</textField>
</jr:detailCell>
</jr:column>
</jr:table>
</componentElement>
<textField>
<reportElement x="0" y="10" width="100" height="30" uuid="683b48a8-3f4d-4a3a-9ab5-df8255699b8b"/>
<textFieldExpression><![CDATA[$F{itemCount}]]></textFieldExpression>
</textField>
</band>
</detail>
<pageFooter>
<band height="39" splitType="Stretch">
<textField>
<reportElement x="326" y="6" width="100" height="30" uuid="94b2cbaa-c1f0-4934-a304-a0c4c84486a0"/>
<textFieldExpression><![CDATA["Page" +$V{PAGE_NUMBER}]]></textFieldExpression>
</textField>
</band>
</pageFooter>
</jasperReport>
Your subDataset should have no query, like this:
<subDataset name="UserDataset" uuid="effd13cd-71de-4771-b706-d68b1042b564">
<field name="id" class="java.lang.Integer">
<property name="net.sf.jasperreports.jsonql.field.expression" value="id"/>
<fieldDescription><![CDATA[id]]></fieldDescription>
</field>
<field name="username" class="java.lang.String">
<property name="net.sf.jasperreports.jsonql.field.expression" value="username"/>
<fieldDescription><![CDATA[username]]></fieldDescription>
</field>
</subDataset>
And your table's datasetRun should only use the correct expression, like this, with nothing else in it (you were casting the REPORT_CONNECTION to JsonDataSource):
<datasetRun subDataset="UserDataset" uuid="fdfe69e2-eeac-4287-9e41-4c39610a79be">
<dataSourceExpression><![CDATA[((net.sf.jasperreports.engine.data.JsonQLDataSource)$P{REPORT_DATA_SOURCE}).subDataSource("users.items")]]></dataSourceExpression>
</datasetRun>