javajasper-reportsdatasourcesubreport

How to use same JRBeanCollectionDataSource on multiple sub reports?


I call two subreports with same datasource, however when I print this report, only my 1st sub-report is populated with table.

This is how I pass the statsData1 to report.

List<BasicStats> summaryList = new ArrayList<>();
summaryList.add(new BasicStats("A", 5d, 6.5d, 25d));
summaryList.add(new BasicStats("B", 1.47d, 2.7d, 72d));
summaryList.add(new BasicStats("c", .39d, 9.5d, 91d));
summaryList.add(new BasicStats("D", 8.2d, 1.3d, 37d));
summaryList.add(new BasicStats("E", 6.8d, 4.5d, 19d));

Map<String, Object> paramsMap = new HashMap<>();
JRBeanCollectionDataSource jbcdSummary = new JRBeanCollectionDataSource(summaryList);
paramsMap.put("statsData1", jbcdSummary);

Although, I have notice that if I pass 2 different objects like below, it works (with relevant modifications to jrxml below) I get both sub-report tables.

paramsMap.put("statsData1", new JRBeanCollectionDataSource(summaryList));
paramsMap.put("statsData2", new JRBeanCollectionDataSource(summaryList));

Does this have something to do with JRBeanCollectionDataSource being a consumable object or something?

This is my main jrxml

<?xml version="1.0" encoding="UTF-8"?>
<!-- Created with Jaspersoft Studio version 6.6.0.final using JasperReports Library version 6.6.0  -->
<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="main" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="0" rightMargin="0" topMargin="0" bottomMargin="0" uuid="6a63a79b-6f04-46c7-b3b9-a067e835ea4d">
    <parameter name="subRptTitle" class="java.lang.String"/>
    <parameter name="statsData1" class="net.sf.jasperreports.engine.data.JRBeanCollectionDataSource"/>
    <background>
        <band splitType="Stretch"/>
    </background>
    <title>
        <band height="79" splitType="Stretch">
            <textField>
                <reportElement x="250" y="20" width="100" height="30" uuid="42f86896-5b37-4ee3-8f0c-29bf90eb3846"/>
                <textFieldExpression><![CDATA[$P{subRptTitle}]]></textFieldExpression>
            </textField>
        </band>
    </title>
    <summary>
        <band height="203" splitType="Stretch">
            <subreport>
                <reportElement x="10" y="31" width="281" height="161" uuid="73d60b1f-1b66-44b1-a8a5-d9738067aaf1"/>
                <subreportParameter name="statsData">
                    <subreportParameterExpression><![CDATA[$P{statsData1}]]></subreportParameterExpression>
                </subreportParameter>
                <dataSourceExpression><![CDATA[new net.sf.jasperreports.engine.JREmptyDataSource()]]></dataSourceExpression>
                <subreportExpression><![CDATA["sub-table.jasper"]]></subreportExpression>
            </subreport>
            <subreport>
                <reportElement x="310" y="31" width="273" height="161" uuid="686bb10d-7018-4cf1-b72b-c17e534ec5e0"/>
                <subreportParameter name="statsData">
                    <subreportParameterExpression><![CDATA[$P{statsData1}]]></subreportParameterExpression>
                </subreportParameter>
                <dataSourceExpression><![CDATA[new net.sf.jasperreports.engine.JREmptyDataSource()]]></dataSourceExpression>
                <subreportExpression><![CDATA["sub-table.jasper"]]></subreportExpression>
            </subreport>
        </band>
    </summary>
</jasperReport>

This is my sub-report, sub-table.jrxml

<?xml version="1.0" encoding="UTF-8"?>
<!-- Created with Jaspersoft Studio version 6.6.0.final using JasperReports Library version 6.6.0  -->
<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="main" pageWidth="200" pageHeight="842" columnWidth="200" leftMargin="0" rightMargin="0" topMargin="0" bottomMargin="0" uuid="6a63a79b-6f04-46c7-b3b9-a067e835ea4d">
    <style name="Table_TH" mode="Opaque" backcolor="#F0F8FF">
        <box>
            <pen lineWidth="0.5" lineColor="#000000"/>
            <topPen lineWidth="0.5" lineColor="#000000"/>
            <leftPen lineWidth="0.5" lineColor="#000000"/>
            <bottomPen lineWidth="0.5" lineColor="#000000"/>
            <rightPen lineWidth="0.5" lineColor="#000000"/>
        </box>
    </style>
    <style name="Table_CH" mode="Opaque" backcolor="#BFE1FF">
        <box>
            <pen lineWidth="0.5" lineColor="#000000"/>
            <topPen lineWidth="0.5" lineColor="#000000"/>
            <leftPen lineWidth="0.5" lineColor="#000000"/>
            <bottomPen lineWidth="0.5" lineColor="#000000"/>
            <rightPen lineWidth="0.5" lineColor="#000000"/>
        </box>
    </style>
    <style name="Table_TD" mode="Opaque" backcolor="#FFFFFF">
        <box>
            <pen lineWidth="0.5" lineColor="#000000"/>
            <topPen lineWidth="0.5" lineColor="#000000"/>
            <leftPen lineWidth="0.5" lineColor="#000000"/>
            <bottomPen lineWidth="0.5" lineColor="#000000"/>
            <rightPen lineWidth="0.5" lineColor="#000000"/>
        </box>
        <conditionalStyle>
            <conditionExpression><![CDATA[new Boolean($V{REPORT_COUNT}.intValue()%2==0)]]></conditionExpression>
            <style backcolor="#FBFDFF"/>
        </conditionalStyle>
    </style>
    <subDataset name="tableDataSet" uuid="2914f7c6-c2d7-448b-b0c1-090970e18ed6">
        <field name="subEntity" class="java.lang.String"/>
        <field name="total" class="java.lang.Double"/>
        <field name="pending" class="java.lang.Double"/>
        <field name="percentage" class="java.lang.Double"/>
        <variable name="vTotalSum" class="java.lang.Double" calculation="Sum">
            <variableExpression><![CDATA[$F{total}]]></variableExpression>
        </variable>
        <variable name="vPendingSum" class="java.lang.Double" calculation="Sum">
            <variableExpression><![CDATA[$F{pending}]]></variableExpression>
        </variable>
        <variable name="vPercentageSum" class="java.lang.Double" calculation="Sum">
            <variableExpression><![CDATA[$F{percentage}]]></variableExpression>
        </variable>
    </subDataset>
    <parameter name="subRptTitle" class="java.lang.String"/>
    <parameter name="statsData" class="net.sf.jasperreports.engine.data.JRBeanCollectionDataSource"/>
    <background>
        <band splitType="Stretch"/>
    </background>
    <title>
        <band height="79" splitType="Stretch">
            <textField>
                <reportElement x="50" y="30" width="100" height="30" uuid="42f86896-5b37-4ee3-8f0c-29bf90eb3846"/>
                <textFieldExpression><![CDATA[$P{subRptTitle}]]></textFieldExpression>
            </textField>
        </band>
    </title>
    <summary>
        <band height="203" splitType="Stretch">
            <componentElement>
                <reportElement x="9" y="11" width="182" height="181" uuid="7451c7aa-8532-471e-ad02-eb98ca21d171">
                    <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="tableDataSet" uuid="eecbe24c-593f-42fa-a7ab-2fbe8b59cb34">
                        <dataSourceExpression><![CDATA[$P{statsData}]]></dataSourceExpression>
                    </datasetRun>
                    <jr:column width="45" uuid="6ea97833-5ba6-48f1-9096-66bb2d6d5978">
                        <jr:tableHeader style="Table_TH" height="30"/>
                        <jr:tableFooter style="Table_TH" height="30"/>
                        <jr:columnHeader style="Table_CH" height="30">
                            <staticText>
                                <reportElement x="0" y="0" width="45" height="30" uuid="afce87c3-7a33-4b79-9627-2c2f37d78609"/>
                                <text><![CDATA[subEntity]]></text>
                            </staticText>
                        </jr:columnHeader>
                        <jr:columnFooter style="Table_CH" height="30"/>
                        <jr:detailCell style="Table_TD" height="30">
                            <textField>
                                <reportElement x="0" y="0" width="45" height="30" uuid="f312e4dc-bd65-4cf6-8c2c-27c1d88940b9"/>
                                <textFieldExpression><![CDATA[$F{subEntity}]]></textFieldExpression>
                            </textField>
                        </jr:detailCell>
                    </jr:column>
                    <jr:column width="45" uuid="89672e7b-ee57-4a0d-8f6e-885c189a9c1d">
                        <jr:tableHeader style="Table_TH" height="30"/>
                        <jr:tableFooter style="Table_TH" height="30">
                            <textField>
                                <reportElement x="0" y="0" width="45" height="30" uuid="c8ef39c5-ea48-41e4-a069-9d07e1ce301b"/>
                                <textFieldExpression><![CDATA[$V{vTotalSum}]]></textFieldExpression>
                            </textField>
                        </jr:tableFooter>
                        <jr:columnHeader style="Table_CH" height="30">
                            <staticText>
                                <reportElement x="0" y="0" width="45" height="30" uuid="c57bbc8c-b840-45fd-b21a-3b7121c29f71"/>
                                <text><![CDATA[total]]></text>
                            </staticText>
                        </jr:columnHeader>
                        <jr:columnFooter style="Table_CH" height="30"/>
                        <jr:detailCell style="Table_TD" height="30">
                            <textField>
                                <reportElement x="0" y="0" width="45" height="30" uuid="bf1068c6-42f2-4cb4-b1f0-8b195d362247"/>
                                <textFieldExpression><![CDATA[$F{total}]]></textFieldExpression>
                            </textField>
                        </jr:detailCell>
                    </jr:column>
                    <jr:column width="45" uuid="4b3eea40-3cca-48a8-961f-6fbe9edfb973">
                        <jr:tableHeader style="Table_TH" height="30"/>
                        <jr:tableFooter style="Table_TH" height="30">
                            <textField>
                                <reportElement x="0" y="0" width="45" height="30" uuid="f4787fdd-5f5b-4f03-97e7-05e4c2c34f0f"/>
                                <textFieldExpression><![CDATA[$V{vPendingSum}]]></textFieldExpression>
                            </textField>
                        </jr:tableFooter>
                        <jr:columnHeader style="Table_CH" height="30">
                            <staticText>
                                <reportElement x="0" y="0" width="45" height="30" uuid="5aa2afde-3b32-480e-b115-9ffddf95ab64"/>
                                <text><![CDATA[pending]]></text>
                            </staticText>
                        </jr:columnHeader>
                        <jr:columnFooter style="Table_CH" height="30"/>
                        <jr:detailCell style="Table_TD" height="30">
                            <textField>
                                <reportElement x="0" y="0" width="45" height="30" uuid="89a528bc-2e09-467f-b709-7434bc6732da"/>
                                <textFieldExpression><![CDATA[$F{pending}]]></textFieldExpression>
                            </textField>
                        </jr:detailCell>
                    </jr:column>
                    <jr:column width="45" uuid="a7c26c8f-361f-4d33-820a-abd2cb3268ad">
                        <jr:tableHeader style="Table_TH" height="30"/>
                        <jr:tableFooter style="Table_TH" height="30">
                            <textField>
                                <reportElement x="0" y="0" width="45" height="30" uuid="7e1115c0-35fb-48d2-b0bd-b36e5a782d67"/>
                                <textFieldExpression><![CDATA[$V{vPercentageSum}]]></textFieldExpression>
                            </textField>
                        </jr:tableFooter>
                        <jr:columnHeader style="Table_CH" height="30">
                            <staticText>
                                <reportElement x="0" y="0" width="45" height="30" uuid="20743d33-811c-411a-b7d1-c78e57ccd018"/>
                                <text><![CDATA[percentage]]></text>
                            </staticText>
                        </jr:columnHeader>
                        <jr:columnFooter style="Table_CH" height="30"/>
                        <jr:detailCell style="Table_TD" height="30">
                            <textField>
                                <reportElement x="0" y="0" width="45" height="30" uuid="ebeb9419-af5d-4475-a8f7-ab13ab4a7b9f"/>
                                <textFieldExpression><![CDATA[$F{percentage}]]></textFieldExpression>
                            </textField>
                        </jr:detailCell>
                    </jr:column>
                </jr:table>
            </componentElement>
        </band>
    </summary>
</jasperReport>

Changes to sub-table.jrxml to make it work with 2 parameters

<parameter name="statsData1" class="net.sf.jasperreports.engine.data.JRBeanCollectionDataSource"/>
<parameter name="statsData2" class="net.sf.jasperreports.engine.data.JRBeanCollectionDataSource"/>
<subreport>
                    <reportElement x="310" y="31" width="273" height="161" uuid="686bb10d-7018-4cf1-b72b-c17e534ec5e0"/>
                    <subreportParameter name="statsData">
                        <subreportParameterExpression><![CDATA[$P{statsData2}]]></subreportParameterExpression>
                    </subreportParameter>
                    <dataSourceExpression><![CDATA[new net.sf.jasperreports.engine.JREmptyDataSource()]]></dataSourceExpression>
                    <subreportExpression><![CDATA["sub-table.jasper"]]></subreportExpression>
                </subreport>

What is a better workaround for this?


Solution

  • The JRBeanCollectionDataSource as you can see in api implements both JRDataSource and JRRewindableDataSource.

    The JRDataSource is a consumable datasource (only next() method) but the JRRewindableDataSource adds a moveFirst() method which makes it possibile to rewind the datasource.

    However, this is not simple to do in the jrxml file (the design file) and I would not recommend doing it.

    The simplest solution in your case is that instead of passing a JRBeanCollectionDataSource pass the List (your summaryList) and create the JRBeanCollectionDataSource in side your jrxml as many times as you need.

    Example

    In java

    paramsMap.put("statsData", summaryList);
    

    In jrxml

    <parameter name="statsData" class="java.util.List"/>
    ...
    <subreportParameter name="statsData">
        <subreportParameterExpression><![CDATA[new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($P{statsData})]]></subreportParameterExpression>
    </subreportParameter>
    ...
    

    Note for future readers: This subreport is particular it passes a datasource as a parameter (that will be used to populate a jr:table in the subreport), normally you would pass the datasource in the <dataSourceExpression>