In the simplest case, with the subreport capability of JasperReports you can to print associated data for each line item in a report—from the same table, from another table in the same database, or from another data source altogether. More complex cases are beyond the scope of this topic; refer to JasperReports documentation for such information.
<queryString><![CDATA[SELECT * FROM ADMINISTRATOR.CUSTOMER]]></queryString>
<field name="CUST_NO" class="java.lang.Integer">
</field>
<field name="CUST_NAME" class="java.lang.String">
</field>
<detail>
<band height="100">
<subreport>
<reportElement positionType="Float" mode="Opaque" x="0" y="31"
width="709" height="12" isRemoveLineWhenBlank="true"/>
<subreportParameter name="CURRENT_CUST">
<subreportParameterExpression>
<![CDATA[$F{CUST_NO}]]>
</subreportParameterExpression>
</subreportParameter>
<connectionExpression>
<![CDATA[$P{REPORT_CONNECTION}]]>
</connectionExpression>
<subreportExpression class="java.lang.String">
<![CDATA[new String("C:\\workspace\\report_project\\bin
\\report_package\\my_subreport.jasper")]]>
</subreportExpression>
</subreport>
<textField>
<reportElement positionType="Float" x="57" y="11"
width="304" height="20"/>
<textElement/>
<textFieldExpression class="java.lang.String">
<![CDATA[$F{CUST_NO} + " " + $F{CUST_NAME}]]>
</textFieldExpression>
</textField>
</band>
</detail>
The <subreport> tag gives JasperReports
the information it needs to run the subreport:<parameter name="CURRENT_CUST" class="java.lang.Integer"/>
<queryString><![CDATA[SELECT * FROM ADMINISTRATOR.ORDERS
WHERE CUST_NO = $P{CURRENT_CUST}]]></queryString>
<field name="CUST_NO" class="java.lang.Integer">
</field>
<field name="INVOICE_NO" class="java.lang.Integer">
</field>
<field name="ORDER_TOTAL" class="java.lang.Float">
</field>
<detail>
<band height="100">
<textField>
<reportElement positionType="Float" x="50" y="10" width="300" height="20"/>
<textElement/>
<textFieldExpression class="java.lang.String">
<![CDATA["Invoice # " + $F{INVOICE_NO} + " total: " +
$F{ORDER_TOTAL}]]>
</textFieldExpression>
</textField>
</band>
</detail>
Even though you passed the parameter CURRENT_CUST
to the subreport, you must tell the report what type the parameter
is, using the class= attribute of the <parameter> tag. Next comes
the query string (JasperReports is very particular about the order
of the tags within the file). Here you reference the value of CURRENT_CUST
as $P{CURRENT_CUST}. The field names refer to column names in the
ORDERS table, which you can then reference inside the <textFieldExpression>
tag.These are the only changes that you need to make to add a subreport; you do not need to change any code in the EGL report driver program. If you want to include other sources of data or complex calculations, however, you must create a report handler (see Creating an EGL report handler).
You can create nested subreports. For example, you might call up line items for each invoice from a third table. This would involve adding the information within a <subreport> tag to the subreport file my_subreport.jasper, and creating a separate design file for the nested subreport (you might call it my_invoice_subreport.jasper). There is no limit to the depth to which you can nest subreports.