Search code examples
jasper-reportsdatasourcereportireportsubreport

How to pass main report data source to subreport (JasperReports)?


I'm using JasperReports and I fill the JRDataSource for ther report. Now, I want to pass the main REPORT_DATA_SOURCE to the subreport. How can I do this?

As far as I know the REPORT_DATA_SOURCE is a consumable object, so it can only be used once, right?. Can I copy this data source and pass it?

BTW: I use iReport for creating the layout.


Solution

  • You can pass datasource via the built-in REPORT_DATA_SOURCE parameter.

    The example:

    <subreport>
        <reportElement x="261" y="25" width="200" height="100"/>
        <dataSourceExpression><![CDATA[$P{REPORT_DATA_SOURCE}]]></dataSourceExpression>
        <subreportExpression><![CDATA[$P{SUBREPORT_DIR} + "subreport.jasper"]]></subreportExpression>
    </subreport>
    

    You can create new instance of datasource based on variable, parameter or field.

    The sample:

    <variable name="HeadingsCollection" class="java.util.Collection" calculation="System">
        <initialValueExpression><![CDATA[new java.util.ArrayList()]]></initialValueExpression>
    </variable>
    ...
    <subreport>
        <reportElement x="0" y="0" width="515" height="20"/>
        <subreportParameter name="ReportTitle">
            <subreportParameterExpression><![CDATA[$P{ReportTitle}]]></subreportParameterExpression>
        </subreportParameter>
        <dataSourceExpression><![CDATA[new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($V{HeadingsCollection})]]></dataSourceExpression>
        <subreportExpression class="java.lang.String"><![CDATA["HeadingsReport.jasper"]]></subreportExpression>
    </subreport>
    

    Another sample:

    <field name="cast" class="java.util.Collection"/>
    ...
    <subreport>
        <reportElement positionType="Float" x="15" y="25" width="245" height="20" isRemoveLineWhenBlank="true" backcolor="#99CCFF"/>
        <dataSourceExpression><![CDATA[new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($F{cast})]]></dataSourceExpression>
        <subreportExpression class="java.lang.String"><![CDATA["JRMDbCastSubreport.jasper"]]></subreportExpression>
    </subreport>
    

    Or you can pass the datasource via the parameter:

    <parameter name="SubreportDataSource" class="net.sf.jasperreports.engine.JRDataSource"/>
    ...
    <subreport>
        <reportElement positionType="Float" x="15" y="25" width="245" height="20" isRemoveLineWhenBlank="true"/>
        <dataSourceExpression>$P{SubreportDataSource}</dataSourceExpression>
        <subreportExpression class="java.lang.String"><![CDATA["Subreport.jasper"]]></subreportExpression>
    </subreport>
    

    Note: Using the same (with master report) datasource in subreport can cause the effect of loosing the first row in the subreport. You can read Why is the first record missing from my subreport? post for understanding how to avoid this issue.