We come across such a situation where a specific report
section appears in multiple reports. Example - An external client focused
company might have a contact information section in all of its reports. Company’s
decision to change the format of contact information section might result in
amending all the reports, involving huge manual effort.
Jasper reports provides a modularization mechanism where we
can develop the working re-usable part of report independently and plug it in where
ever needed. This binding of reusable
part to main report is runtime binding. So any changes in re-usable report
would automatically get reflected wherever it has been used.
As an example to deal with above mentioned problem
efficiently, we could have developed the contact information section as an
independent report and plugged it in all other reports.
Jasper provides subreport tag to achieve modularity, where
we can define how and where the included section should appear in the main
report. We can pass the parent’s or derived connection, data sources or
parameter map to be used for populating the included reports.
Jasper subreport example - To demo the working of sub-reports, we will develop two reports called simpleSubreport.jrxml, simpleSubreport2.jrxml and use these modular components in simpleMaster.jrxml so that the complete report could be generated in a single shot-
simpleSubreport.jrxml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE jasperReport PUBLIC "-//JasperReports//DTD Report Design//EN" "http://jasperreports.sourceforge.net/dtds/jasperreport.dtd">
<jasperReport name="SimpleSubreport" language="java" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="30" bottomMargin="30">
<field name="subTitle" class="java.lang.String"></field>
<detail>
<band height="100">
<textField>
<reportElement positionType="Float" x="55" y="14" width="75" height="41"/>
<textElement/>
<textFieldExpression class="java.lang.String"><![CDATA[$F{subTitle}]]></textFieldExpression>
</textField>
</band>
</detail>
</jasperReport>
simpleSubreport2.jrxml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE jasperReport PUBLIC "-//JasperReports//DTD Report Design//EN" "http://jasperreports.sourceforge.net/dtds/jasperreport.dtd">
<jasperReport name="SimpleSubreport2" language="java" pageWidth="200" pageHeight="842" columnWidth="200" leftMargin="0" rightMargin="0" topMargin="0" bottomMargin="0">
<field name="subTitle" class="java.lang.String"></field>
<detail>
<band height="100">
<staticText>
<reportElement positionType="Float" mode="Opaque" x="36" y="8" width="100" height="16" backcolor="#ff8000"/>
<textElement/>
</staticText>
<textField>
<reportElement positionType="Float" x="35" y="35" width="110" height="30"/>
<textElement/>
<textFieldExpression class="java.lang.String"><![CDATA[$F{subTitle}]]></textFieldExpression>
</textField>
</band>
</detail>
</jasperReport>
simpleMaster.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="SimpleMaster" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="30" bottomMargin="30">
<parameter name="mainReportParameterMap" class="java.util.HashMap"/>
<field name="master" class="java.lang.String"/>
<field name="id" class="java.lang.String"/>
<field name="id2" class="java.lang.String"/>
<title>
<band height="107" splitType="Stretch">
<textField>
<reportElement positionType="Float" x="79" y="8" width="167" height="30"/>
<textElement/>
<textFieldExpression class="java.lang.String"><![CDATA[$P{mainReportParameterMap}.get("title")]]></textFieldExpression>
</textField>
<textField>
<reportElement positionType="Float" x="86" y="63" width="190" height="32"/>
<textElement/>
<textFieldExpression class="java.lang.String"><![CDATA[$F{master}]]></textFieldExpression>
</textField>
</band>
</title>
<detail>
<band height="100" splitType="Stretch">
<subreport>
<reportElement positionType="Float" x="67" y="18" width="168" height="47"/>
<subreportParameter name="id">
<subreportParameterExpression><![CDATA[$P{mainReportParameterMap}.get($F{id})]]></subreportParameterExpression>
</subreportParameter>
<dataSourceExpression><![CDATA[$P{mainReportParameterMap}.get($F{id})]]></dataSourceExpression>
<subreportExpression class="java.lang.String"><![CDATA["simpleSubreport.jasper"]]></subreportExpression>
</subreport>
<subreport>
<reportElement positionType="Float" x="249" y="18" width="168" height="47"/>
<subreportParameter name="id2">
<subreportParameterExpression><![CDATA[$P{mainReportParameterMap}.get($F{id2})]]></subreportParameterExpression>
</subreportParameter>
<dataSourceExpression><![CDATA[$P{mainReportParameterMap}.get($F{id2})]]></dataSourceExpression>
<subreportExpression class="java.lang.String"><![CDATA["simpleSubreport2.jasper"]]></subreportExpression>
</subreport>
</band>
</detail>
<pageFooter>
<band height="15" splitType="Stretch">
<textField>
<reportElement x="0" y="0" width="520" height="15"/>
<textElement textAlignment="Right"/>
<textFieldExpression class="java.lang.Integer"><![CDATA[$V{PAGE_NUMBER}+"/"]]></textFieldExpression>
</textField>
<textField evaluationTime="Report">
<reportElement x="521" y="0" width="14" height="15"/>
<textElement textAlignment="Left"/>
<textFieldExpression class="java.lang.Integer"><![CDATA[$V{PAGE_NUMBER}]]></textFieldExpression>
</textField>
</band>
</pageFooter>
</jasperReport>
SubReportExample.java
package subreportexample;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperRunManager;
import net.sf.jasperreports.engine.data.JRMapCollectionDataSource;
import utility.JasperUtility;
@SuppressWarnings("rawtypes")
public class SubReportExample {
static String jrxmlFileLocation = "src\\main\\resources\\subreportexample\\";
static String jasperFileLocation = "target\\classes\\subreportexample\\";
String outputPDFFile = "target\\classes\\subreportexample\\SubReportFile.pdf";;
final int firstDatasourceNumber = 1;
final int secondDatasourceNumber = 2;
/**
* @throws JRException
*/
@SuppressWarnings("unchecked")
private void generateReport() throws JRException {
List simpleSubMasterList = getMapArrayListForReport(firstDatasourceNumber);
JRMapCollectionDataSource firstReportDataSource = new JRMapCollectionDataSource(
simpleSubMasterList);
simpleSubMasterList = getMapArrayListForReport(secondDatasourceNumber);
JRMapCollectionDataSource secondReportDataSource = new JRMapCollectionDataSource(
simpleSubMasterList);
HashMap mainReportParameterMap = new HashMap();
mainReportParameterMap.put("title", "Title of master report");
mainReportParameterMap.put("subDS", firstReportDataSource);
mainReportParameterMap.put("subDS2", secondReportDataSource);
Map mainReportDSElementMap = new HashMap();
mainReportDSElementMap.put("master",
"This portion is from master report");
mainReportDSElementMap.put("id", "subDS");
mainReportDSElementMap.put("id2", "subDS2");
List simpleMasterList = new ArrayList();
simpleMasterList.add(mainReportDSElementMap);
JRDataSource simpleDS = new JRMapCollectionDataSource(simpleMasterList);
Map parameters = new HashMap();
parameters.put("mainReportParameterMap", mainReportParameterMap);
JasperRunManager.runReportToPdfFile(jasperFileLocation
+ "simpleMaster.jasper", outputPDFFile, parameters, simpleDS);
}
/**
* @param firstDatasourceNumber
* @return
*/
@SuppressWarnings("unchecked")
private List getMapArrayListForReport(int firstDatasourceNumber) {
List simpleSubMasterList = new ArrayList();
for (int i = 0; i < 30; i++) {
Map simpleSubMasterMap = new HashMap();
simpleSubMasterMap.put("subTitle", "This is subtitile no " + i
+ " of data source no " + firstDatasourceNumber);
simpleSubMasterList.add(simpleSubMasterMap);
}
return simpleSubMasterList;
}
public static void main(String[] args) throws JRException {
compileJrxmlFiles();
new SubReportExample().generateReport();
System.out.println("done");
}
private static void compileJrxmlFiles() throws JRException {
JasperUtility.compileAndGenerateJasperFile(jrxmlFileLocation,
jasperFileLocation, "simpleMaster", "simpleSubreport",
"simpleSubreport2");
}
}
Sample Project -
Sample project can be downloaded from here
You will need maven-3 along with java 5 or higher version, setup in your machine to run the sample.
Kindly follow the below mentioned steps to run the sample and get the report -
- Download & unzip the project
- Run- mvn clean eclipse:eclipse install in project's home directory
- Import the application in eclipse
- Execute SubReportExample.java file
- Sample pdf will be generated at target\\classes\\subreportexample\\SubReportFile.pdf location.
http://salilstock.blogspot.in/2012/05/jasperreport-open-source-java-reporting.html
http://salilstock.blogspot.in/2012/05/including-page-number-and-page-count-in.html
Please contact me to discuss jeff_mire(at)yahoo.com
ReplyDelete