We have input json to jrxml as
{
"ID": "5c2c7662f256a1452b0ed8b2",
"MarketData": {
"markets": [ { "id": "1001", "name": "val1" }, { "id": "1002", "name": "Val2" }, { "id": "1003", "name": "val3" } ],
"products": [
{"id": "1001", "proname": "shoe"},
{"id": "1002", "name": "bag"},
{"id": "1003", "name": "cap"}
],
"location":"ABC"
}
}
We have json that contains list of values of markets, products .
We need to show values from this json as
Location : ABC
Markets : val1,Val2,val3
Products Sold: shoes,bag,cap
Using this solution provided here i am able to display Markets as comma separated values Jasper converting list of values of json to comma separated values using jsonQL
Same technique if i use subdataset and display i get output as
Location : ABC
Markets : val1
val1,val2
val1,val2,val3
Products : shoes
shoes,bag
shoes,bag,cap
i declared the main data set as
<queryString language="jsonql">
<![CDATA[]]>
</queryString>
<field name="location" class="java.lang.String">
<property name="net.sf.jasperreports.jsonql.field.expression" value="location"/>
<fieldDescription><![CDATA[location]]></fieldDescription>
</field>
then subdataset as markets as
<subDataset name="marketList" uuid="01e76955-f29e-4d52-991b-aa0149bfdb37">
<field name="name" class="java.lang.String">
<property name="net.sf.jasperreports.jsonql.field.expression" value="name"/>
</field>
<variable name="allname" class="java.lang.String">
<variableExpression><![CDATA[$V{allname} != null ? $V{allname} + ", " + $F{name} : $F{name}]]></variableExpression>
</variable>
</subDataset>
referenced these fields in jrxml as
<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="marketList" uuid="565f0c3a-76b6-4527-b0d2-d306c5f4e20c">
<dataSourceExpression><![CDATA[((net.sf.jasperreports.engine.data.JsonQLDataSource)$P{REPORT_DATA_SOURCE}).subDataSource("$.MarketData.markets")]]></dataSourceExpression>
</datasetRun>
<jr:listContents height="16" width="103">
<textField>
<reportElement x="0" y="0" width="100" height="16" uuid="7f2eaa2a-20b5-4598-bbf1-758f61dc3fc8"/>
<textFieldExpression><![CDATA[$V{allname}]]></textFieldExpression>
</textField>
</jr:listContents>
</jr:list>
this gives output as
Markets : val1
val1,val2
val1,val2,val3
however expected output is
Location : ABC
Markets : val1,val2,val3
Products :shoes,bag,cap
How to show subdataset that has list of values as comma separated values .
Thanks
Anjana
In your list's textField you could set the evaluation time to something like Page or Report and display it only for the first record, something like so:
<jr:listContents height="0" width="180">
<frame>
<reportElement x="0" y="0" width="100" height="0" uuid="3c9872d0-ef6c-4643-9cf9-e78bc6996d3e">
<property name="ShowOutOfBoundContent" value="true"/>
<printWhenExpression><![CDATA[$V{REPORT_COUNT} == 1]]></printWhenExpression>
</reportElement>
<textField evaluationTime="Report">
<reportElement x="0" y="0" width="100" height="16" uuid="f5a23577-4e57-4542-81a4-06ed679be920"/>
<textFieldExpression><![CDATA[$V{allname}]]></textFieldExpression>
</textField>
</frame>
</jr:listContents>
The textField is wrapped in a 0 height frame to avoid unnecessary white space generation inside the list.
Related
I have the following JSON:
{
"data": [
{
"name": "apple",
"sorts": [
{ "name": "green", "number": "6", "comment": "green apples are nice", "suppliers": [{"name": "Supplier1"},{"name": "Supplier2"}] },
{ "name": "yellow", "number": "1", "suppliers": [] },
{ "name": "red", "number": "2", "suppliers": [{"name": "supplier1"}] }
]
},
{
"name": "banana",
"sorts": [
]
},
{
"name": "pear",
"sorts": [
{ "name": "green", "number": "6", "comment": "green pears are sour", "suppliers": [{"name": "supplier4"}] },
{ "name": "purple", "number": "0", "comment": "so far we haven't seen purple pears", "suppliers": [{"name": "supplier1"},{"name": "supplier4"}] }
]
}
]
}
And this is my JRXML:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Created with Jaspersoft Studio version 6.13.0.final using JasperReports Library version 6.13.0-46ada4d1be8f3c5985fd0b6146f3ed44caed6f05 -->
<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>
<subDataset name="DatasetSuppliers" uuid="4af8f526-8e16-4e58-8c2e-0a7dcf7998ba">
<property name="com.jaspersoft.studio.data.defaultdataadapter" value="Adapter"/>
<queryString language="JSON">
<![CDATA[data.sorts.suppliers]]>
</queryString>
<field name="name" class="java.lang.String">
<property name="net.sf.jasperreports.json.field.expression" value="name"/>
<fieldDescription><![CDATA[name]]></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="130" y="0" width="100" height="30" uuid="be871dcb-61a0-49bd-b565-af8aa27bc7f4"/>
<textFieldExpression><![CDATA[$F{number}]]></textFieldExpression>
</textField>
<textField isBlankWhenNull="true">
<reportElement x="230" y="0" width="190" height="30" uuid="bea6dae7-bca2-4c0a-a0b5-443a859c20ac"/>
<textFieldExpression><![CDATA[$F{comment}]]></textFieldExpression>
</textField>
<componentElement>
<reportElement x="490" y="0" width="100" height="30" uuid="af5e5156-cdae-45eb-b423-dbdbebad8879"/>
<jr:list>
<datasetRun subDataset="DatasetSuppliers" uuid="d3430f43-a76c-47d8-b592-c6dae7fbf083">
<dataSourceExpression><![CDATA[((net.sf.jasperreports.engine.data.JsonQLDataSource)$P{REPORT_DATA_SOURCE}).subDataSource("suppliers")]]></dataSourceExpression>
</datasetRun>
<jr:listContents height="30" width="100">
<textField>
<reportElement x="0" y="0" width="100" height="30" uuid="8f7ab53c-b3c2-4d4d-8266-3f04efed81d7"/>
<textFieldExpression><![CDATA[$F{name}]]></textFieldExpression>
</textField>
</jr:listContents>
</jr:list>
</componentElement>
</frame>
</jr:listContents>
</jr:list>
</componentElement>
</band>
</detail>
</jasperReport>
That gives the following result:
Now I want to sort the list on fruitnames. I added <sortField name="fruitName"/> to the subDataset. Unfortunately I get the following error:
net.sf.jasperreports.engine.JRException: net.sf.jasperreports.engine.JRRuntimeException: net.sf.jasperreports.engine.fill.JRExpressionEvalException: Error evaluating expression for source text: ((net.sf.jasperreports.engine.data.JsonQLDataSource)$P{REPORT_DATA_SOURCE}).subDataSource("suppliers")
at com.jaspersoft.studio.editor.preview.view.control.ReportController.fillReport(ReportController.java:551)
at com.jaspersoft.studio.editor.preview.view.control.ReportController.access$18(ReportController.java:526)
at com.jaspersoft.studio.editor.preview.view.control.ReportController$1.run(ReportController.java:444)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:63)
Caused by: net.sf.jasperreports.engine.JRRuntimeException: net.sf.jasperreports.engine.fill.JRExpressionEvalException: Error evaluating expression for source text: ((net.sf.jasperreports.engine.data.JsonQLDataSource)$P{REPORT_DATA_SOURCE}).subDataSource("suppliers")
at net.sf.jasperreports.components.list.VerticalFillList.prepare(VerticalFillList.java:150)
at net.sf.jasperreports.engine.fill.JRFillComponentElement.prepare(JRFillComponentElement.java:152)
at net.sf.jasperreports.engine.fill.JRFillElementContainer.prepareElements(JRFillElementContainer.java:542)
at net.sf.jasperreports.engine.fill.JRFillBand.fill(JRFillBand.java:453)
at net.sf.jasperreports.engine.fill.JRFillBand.fill(JRFillBand.java:428)
at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillColumnBand(JRVerticalFiller.java:2602)
at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillDetail(JRVerticalFiller.java:825)
at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillReportStart(JRVerticalFiller.java:266)
at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillReport(JRVerticalFiller.java:110)
at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:621)
at net.sf.jasperreports.engine.fill.BaseFillHandle$ReportFill.run(BaseFillHandle.java:135)
at java.lang.Thread.run(Thread.java:748)
Caused by: net.sf.jasperreports.engine.fill.JRExpressionEvalException: Error evaluating expression for source text: ((net.sf.jasperreports.engine.data.JsonQLDataSource)$P{REPORT_DATA_SOURCE}).subDataSource("suppliers")
at net.sf.jasperreports.engine.fill.JREvaluator.handleEvaluationException(JREvaluator.java:294)
at net.sf.jasperreports.engine.fill.JREvaluator.evaluate(JREvaluator.java:328)
at net.sf.jasperreports.engine.fill.JRCalculator.evaluate(JRCalculator.java:673)
at net.sf.jasperreports.engine.fill.JRCalculator.evaluate(JRCalculator.java:641)
at net.sf.jasperreports.engine.fill.JRFillDataset.evaluateExpression(JRFillDataset.java:2028)
at net.sf.jasperreports.components.list.FillDatasetRun.evaluateDatasetExpression(FillDatasetRun.java:237)
at net.sf.jasperreports.components.list.BaseFillList$1.evaluate(BaseFillList.java:91)
at net.sf.jasperreports.components.list.FillDatasetRun.evaluate(FillDatasetRun.java:131)
at net.sf.jasperreports.components.list.BaseFillList.evaluate(BaseFillList.java:115)
at net.sf.jasperreports.engine.fill.JRFillComponentElement.evaluate(JRFillComponentElement.java:110)
at net.sf.jasperreports.engine.fill.JRFillElementContainer.evaluate(JRFillElementContainer.java:383)
at net.sf.jasperreports.engine.fill.JRFillFrame.evaluate(JRFillFrame.java:172)
at net.sf.jasperreports.engine.fill.JRFillElementContainer.evaluate(JRFillElementContainer.java:383)
at net.sf.jasperreports.components.list.FillListContents.evaluateContents(FillListContents.java:85)
at net.sf.jasperreports.components.list.VerticalFillList.prepare(VerticalFillList.java:110)
... 11 more
Caused by: java.lang.ClassCastException: net.sf.jasperreports.engine.fill.SortedDataSource cannot be cast to net.sf.jasperreports.engine.data.JsonQLDataSource
at Blank_A4_DatasetFruitsSortAll_1598446444233_560474.evaluate(Blank_A4_DatasetFruitsSortAll_1598446444233_560474:86)
at net.sf.jasperreports.engine.fill.JREvaluator.evaluate(JREvaluator.java:313)
... 24 more
What am I doing wrong?
Defining a sort field will result in an in memory data source being used for the report, which means that $P{REPORT_DATA_SOURCE} is no longer the original JsonQLDataSource object.
Because of that, the data source expression ((net.sf.jasperreports.engine.data.JsonQLDataSource)$P{REPORT_DATA_SOURCE}).subDataSource("suppliers") fails.
The solution is to use the SUB_DATA_SOURCE builtin function instead of JsonQLDataSource.subDataSource. The expression will look like this:
<dataSourceExpression><![CDATA[SUB_DATA_SOURCE("suppliers")]]></dataSourceExpression>
You will need JasperReports 6.13.0 or newer for this, and a jasperreports-functions jar in your application (you can get it via Maven).
We are trying to build a JasperReport for an estimate via JSON. The header and lines (multiple) are fine. However, there is one more node in the JSON file which requires to be looped in the detail table. We are not able to achieve it using subdataset. Currently, we are using JSONQL to iterate the lines.
We are unable to loop the taxes node via subdataset.
Below is the sample JSON input:
{
"taxes": [
{
"tax_slab_name": "VAT Exempt",
"tax_amount": "AED 20.00"
},
{
"tax_slab_name": "VAT 0%",
"tax_amount": "AED 30.00"
},
{
"tax_slab_name": "VAT 5 %",
"tax_amount": "AED 50.00"
}
],
"header": [
{
"estimate_no": "EST-000054",
"bill_to_address": "111 Stamm Cliffs Suite 285, Heaney Ville, Jebel Ali, Dubai, United Arab Emirates (UAE)",
"ship_to_address": "66015 شارع بلال السهلي, ممر ميسر مدني, Jebel Ali, Dubai, United Arab Emirates (UAE)",
"estimate_date": "2020-05-08",
"expiry_date": "2020-05-23",
"sub_total": 14000,
"discount": 0,
"tax_amt": 450,
"total": 14450,
"conditions": "All charges are in United States Dollar (USD) unless otherwise stated. E. and O.E.",
"status": "SAVED",
"contact_name": "Kerluke, Bartell and Dickinson (مجموعة الداوود وأولاده)"
}
],
"lines": [
{
"item_name": "Enterprise Product Development - Java/JSF/PF",
"tax_slab": 1,
"uom": "box",
"quantity": 1,
"rate": 1000,
"amount": 1000
},
{
"item_name": "Server Setup",
"tax_slab": 2,
"uom": "cm",
"quantity": 2,
"rate": 2000,
"amount": 4000
},
{
"item_name": "Backup and DR Service",
"tax_slab": 2,
"uom": "cm",
"quantity": 2,
"rate": 2000,
"amount": 4000
}
]
}
Datasource Type: JSONQL
JasperReport Version: 6.12.2 (latest)
Never mind. Got it working with sub-data-set.
<subDataset name="TaxSDS" uuid="1701ce05-88ab-4435-85c5-3ad38e0b941b">
<queryString language="jsonql">
<![CDATA[..taxes]]>
</queryString>
<field name="tax_slab_name" class="java.lang.String">
<property name="net.sf.jasperreports.jsonql.field.expression" value="tax_slab_name"/>
<fieldDescription><![CDATA[Tax Slabs]]></fieldDescription>
</field>
<field name="tax_slab_amt" class="java.lang.String">
<property name="net.sf.jasperreports.jsonql.field.expression" value="tax_amount"/>
<fieldDescription><![CDATA[Tax Amount]]></fieldDescription>
</field>
</subDataset>
<subDataset name="LinesSDS" uuid="1701ce05-88ab-4435-85c5-3ad38e0b941b">
<queryString language="jsonql">
<![CDATA[..lines]]>
</queryString>
<field name="item_name" class="java.lang.String">
<property name="net.sf.jasperreports.jsonql.field.expression" value="item_name"/>
<fieldDescription><![CDATA[Item]]></fieldDescription>
</field>
<field name="uom" class="java.lang.String">
<property name="net.sf.jasperreports.jsonql.field.expression" value="uom"/>
<fieldDescription><![CDATA[UOM]]></fieldDescription>
</field>
</subDataset>
<queryString language="jsonql">
<![CDATA[]]>
</queryString>
<field name="invoiceNo" class="java.lang.String">
<property name="net.sf.jasperreports.jsonql.field.expression" value="header.estimate_no"/>
<fieldDescription><![CDATA[Estimate No]]></fieldDescription>
</field>
my json is as follows
"values": [
{
"purchase": {
"name":"bags"
},
"weekSpend": [
{
"weekStartDate": 20181105,
"spend":100
},
{
"weekStartDate": 20181112,
"spend":200
}
]
},
{
"purchase": {
"name":"shoes"
},
"weekSpend": [
{
"weekStartDate": 20181105,
"spend":100
},
{
"weekStartDate": 20181112,
"spend":200
}
]
},
]
I want to displayed the grid where rows are
productname and (columns by weekstartdate)
I followed the technique provided in How to show column at Crosstab even the data is absent
However the productname are listed in row but the column are showing only first column.
my data set is as follows
<queryString language="jsonql">
<![CDATA[]]>
</queryString>
<field name="productName" class="java.lang.String">
<property name="net.sf.jasperreports.jsonql.field.expression" value="product.name"/>
<fieldDescription><![CDATA[product.name]]></fieldDescription>
</field>
<field name="weekStartDate" class="java.lang.String[]">
<property name="net.sf.jasperreports.jsonql.field.expression" value="weekSpend.weekStartDate"/>
</field>
<group name="activityDateGroup">
<groupExpression><![CDATA[$F{weekStartDate}]]></groupExpression>
</group>
my crossdata datasource is as follows
<crosstabDataset isDataPreSorted="true">
<dataset>
<datasetRun subDataset="crossTabDataSet" uuid="e7b27508-8a48-4785-a48e-c646249df9a9">
<dataSourceExpression><![CDATA[((net.sf.jasperreports.engine.data.JsonQLDataSource)$P{REPORT_DATA_SOURCE}).subDataSource("..values(#size > 0).*")]]></dataSourceExpression>
</datasetRun>
</dataset>
</crosstabDataset>
and bucketexpression is on weekstartdate.
With these using JsonQL still only the first column is displayed
How do i get list of column based on weekstardate from iterating from rootnode.
i am using jasper studio 6.5.
Thanks
Anjana.
There is an invalid field mapping: weekStartDate to java.lang.String[], that is not supported in JSONQL.
Instead you could have this subDataset expression:
<datasetRun subDataset="crossTabDataSet" uuid="e7b27508-8a48-4785-a48e-c646249df9a9">
<dataSourceExpression><![CDATA[((net.sf.jasperreports.engine.data.JsonQLDataSource)$P{REPORT_DATA_SOURCE}).subDataSource("..values(#size > 0)..weekSpend.*")]]></dataSourceExpression>
</datasetRun>
with these field mappings:
<field name="productName" class="java.lang.String">
<property name="net.sf.jasperreports.jsonql.field.expression" value="^{2}.purchase.name"/>
</field>
<field name="weekStartDate" class="java.lang.Integer">
<property name="net.sf.jasperreports.jsonql.field.expression" value="weekStartDate"/>
</field>
I have a json as below
"markets": [ { "id": "1001", "name": "val1" }, { "id": "1002", "name": "Val2" }, { "id": "1003", "name": "val3" } ]
I am trying to display as following in jasper jrxml text fields
val1, Val2, val3.
i defined my field expression as follow
<field name="market" class="java.lang.String">
<property name="net.sf.jasperreports.jsonql.field.expression" value="markets*.name"/>
<textField isStretchWithOverflow="true">
<reportElement x="80" y="40" width="100" height="16" uuid="903a6728-3a7a-4d1a-9b70-cd8da7a11c7f"/>
<textElement>
<font size="9"/>
</textElement>
<textFieldExpression><![CDATA[$F{market}]]></textFieldExpression>
</textField>
However only one value is displayed i.e. val1.
how to display list of values.
Thanks
Anjana.
The two jsons i need to concatenate to convert it into a single valid json are :
{
"first": true,
"second": {
"name": "manoj",
"age": "45"
},
"third": {
"fourth": [{
"class": "test12",
"salary": "123456"
},
{
"class": "test23",
"salary": "15678"
}
],
"fifth": "hello"
}
}
and
[{
"item1": "123456",
"item2": "5678"
},
{
"item1": "8976",
"item2": "abcd"
}]
Is it possible to concatenate these two without using any jquery. I need something related to wso2 esb code. I tried using enrich and other mediators but no luck so far.
You can concat the jsons using WSO2 ESB Payload Factory mediator as follows,
<api xmlns="http://ws.apache.org/ns/synapse" name="ConcatAPI" context="/concat">
<resource methods="GET">
<inSequence>
<call>
<endpoint>
<http method="GET" uri-template="http://www.mocky.io/v2/56b2d88c13000057518945d4"/>
</endpoint>
</call>
<enrich>
<source type="body" clone="true"/>
<target type="property" property="first-json"/>
</enrich>
<log level="custom">
<property name="First json" expression="get-property('first-json')"/>
</log>
<call>
<endpoint>
<http method="GET" uri-template="http://www.mocky.io/v2/56b2d87d1300007c518945d3"/>
</endpoint>
</call>
<payloadFactory media-type="xml">
<format>
<completeJson xmlns="">
<firstjson>$1</firstjson>
<secondjson>$2</secondjson>
</completeJson>
</format>
<args>
<arg evaluator="xml" expression="get-property('first-json')"/>
<arg evaluator="xml" expression="$body"/>
</args>
</payloadFactory>
<property name="messageType" value="application/json" scope="axis2"/>
<send/>
</inSequence>
<outSequence/>
<faultSequence/>
</resource>
</api>
Note that i have retrieved your jsons from mocked services from mocky.io web site.
Thanks.