Sample Reference - Schema Reference - Configuration Reference - API (Javadoc)
|
|
|
|
JasperReports - Subreport Sample (version 4.0.1) | |
|
|
|
Main Features in This Sample | |
| Subreports |
|
|
|||||
top | ||||||
|
||||||
Subreports | Documented by Luke Shannon | |||||
|
||||||
| Description / Goal |
| How to use the built-in subreport element to create nested content. | |||
| Since |
| 0.3.0 | |||
| Other Samples |
|
|
|||
|
||||||
|
What is a Subreport
A Subreport is a JasperReports Template thats embedded within another JasperReports template (which we will refer to as the Master report). As the Master report executes, each time the Subreport element is reached it is executed and its content seamlessly embedded into the output of the Master report. The end result is a single output containing the blended contents of the Master report and each subreport execution. Subreports can be nested. When to Use Subreports There are several situations when you wish to embed one report into other. Examples of such situations are:
Running the Sample Prerequisites Ant is required. By running 'ant --version' you will be able to check if ant is set up on your system (at least version 1.5 is required): C:\>ant -version Apache Ant version 1.8.0 compiled on February 1 2010You can obtain ant from http://ant.apache.org/, instructions for installation can be found there as well. Starting the Data Source In a command prompt/terminal window browse to the demo/hsqldb folder of the JasperReports source and run the command 'ant runServer'. Leave window/terminal running (see below for sample output). C:\js-workspace\jasperreports\demo\hsqldb>ant runServer Buildfile: C:\js-workspace\jasperreports\demo\hsqldb\build.xml runServer: [java] [Server@83cc67]: [Thread[main,5,main]]: checkRunning(false) entered [java] [Server@83cc67]: [Thread[main,5,main]]: checkRunning(false) exited [java] [Server@83cc67]: Startup sequence initiated from main() method [java] [Server@83cc67]: Loaded properties from [C:\js-workspace\jasperreports\demo\hsqldb\server.properties] [java] [Server@83cc67]: Initiating startup sequence... [java] [Server@83cc67]: Server socket opened successfully in 19 ms. [java] [Server@83cc67]: Database [index=0, id=0, db=file:test, alias=] opened sucessfully in 1104 ms. [java] [Server@83cc67]: Startup sequence completed in 1125 ms. [java] [Server@83cc67]: 2010-03-10 11:32:30.423 HSQLDB server 1.8.0 is online [java] [Server@83cc67]: To close normally, connect and execute SHUTDOWN SQL [java] [Server@83cc67]: From command line, use [Ctrl]+[C] to abort abruptlyGenerating the Report Open up a separate command prompt/terminal window and browse to the root directory of the sample. By running 'ant -p' you will be presented with a list of options available. Of interest in this list is all the exporters available for testing. Each export type will generate a output type in the build/report folder. By running the command 'ant' the following actions will be performed:
You can now run 'ant view' to see a version of the report in the JasperViewer (an applet contained in the JasperReports package which can be used to view a .jrprint object). Each of the these task can be ran separately as well:
You now have a working version of the report you can review. Configuring a Subreport The first thing to note is any JasperReport can be used as a Subreport. However, once a report has embedded into another as a Subreport, the Master report is now responsible for:
In this example the Master Report contains the Address and Product reports embedded as Subreport elements. Lets begin by review the configuration of the Subreport element for the Products Subreport. <subreport> <reportElement isPrintRepeatedValues="false" x="5" y="25" width="325" height="20" isRemoveLineWhenBlank="true" backcolor="#ffcc99"/> <subreportParameter name="City"> <subreportParameterExpression><![ CDATA[$F{City} ]] ></subreportParameterExpression> </subreportParameter> <connectionExpression><![ CDATA[$P{REPORT_CONNECTION}]] ></connectionExpression> <returnValue subreportVariable="PriceSum" toVariable="ProductTotalPrice" calculation="Sum"/> <subreportExpression class="net.sf.jasperreports.engine.JasperReport"><![ CDATA[$P{ProductsSubreport}]] ></subreportExpression> </subreport>This element is in the Detail band of the Master report. This means this Subreport will be executed with each record in the Master report's Result Set. subreportParameter This tag indicates a Parameter in the Product report is being filled by the Master report. In this case, its the City field in the Master report filling the City Parameter of the Product report. If we look at the query of the Product report we see that the value of the City parameter is injected into the Query to constrain the Results: SELECT Product.ID AS ID, Product.Name AS Name, Positions.Quantity AS Quantity, Positions.Price AS Price FROM Positions, Product, Document, Address WHERE Positions.DocumentID = Document.ID AND Document.AddressID = Address.ID AND Positions.ProductID = Product.ID AND Address.City = $P{City} ORDER BY Product.IDWhat this means is the Product report executes for each row in the Master report's ResultSet and displays results related to the city field in that row (Remember: Fields map to the data source, in this case to columns returned in the Result Set). For more information on modifying report queries please view the Query Sample. connectionExpression This tag specifies the JRDataSource to be used to fill the subreport. In this case the built in parameter $P{REPORT_CONNECTION} is used. This parameter contains a reference to JDBC Connection that was used to fill the Master Report. This is best practice when working with Subreports which need to be filled with the same JDBC Connection as the Master report. In situations where your Subreport doesn't use a data source (the report may just contain some text and/or images) a reference to the JREmptyDataSource can be passed in here: <dataSourceExpression><![ CDATA[new net.sf.jasperreports.engine.JREmptyDataSource()]] ></dataSourceExpression> returnValue This tag indicates the value passed from the subreport to the Master report. The calulcation indicates if the value should be accumlated or just passed directly up. In this case the calculation is Sum, meaning the PriceSum variable in the Subreport is going to be accumlated for each Subreport execution and stored in the ProductTotalPrice variable of the master report. If the desired effect is to just pass a variable from the Subreport to the Master, then a calculation type of None should be used. subreport Expression This tag indicates where the design of the Subreport can be located. Note the class. In this example the expression is returning a JasperReports object. The subreport expression represents a very powerful place for extensions/integratoins. Ternary operators can be used here to load different Subreports based on different conditions in the report. Also external Java classes can be called in this expression, provided they return a JasperReport reference, the subreport design can be obtained or created using Java. In the SubreportApp.java the JasperReport reference is obtained by loading a .jasper (serialized JasperReport object) file from the file system. JasperReport subreport = (JasperReport)JRLoader.loadObjectFromLocation("build/reports/ProductReport.jasper");Lets review the Address Report configuration. <subreport> <reportElement positionType="Float" x="335" y="25" width="175" height="20" isRemoveLineWhenBlank="true" backcolor="#99ccff"/> <subreportParameter name="City"> <subreportParameterExpression><![ CDATA[$F{City}]] ></subreportParameterExpression> </subreportParameter> <connectionExpression><![ CDATA[$P{REPORT_CONNECTION}]] ></connectionExpression> <returnValue subreportVariable="REPORT_COUNT" toVariable="CityAddressCount"/> <subreportExpression class="java.lang.String"><![CDATA["AddressReport.jasper"]] ></subreportExpression> </subreport>The main differences are here:
Is there performance concerns with Subreports? The answer to this depends on your system, data source and your report design. A few points to note on Subreports:
The JasperReports property: net.sf.jasperreports.subreport.runner.factory can be used with the following two settings:
is set, then a Javaflow approach will be used to fill the reports rather than threads. If this option is choosen, then the Jakarta Commons Javaflow jar must be included in the application classpath. This jar can be found in the lib directory of the JasperReport reports project distribution package. The jasperreports-javaflow.properties file illustrates how this property could be set in a actual implementation. Other alternatives for processing different queries in the same report are usage of the List element and Sub Datasets. Further Resources: JasperReports Ultimate Guide (available from the JasperSoft eShop) iReport Ultimate Guide (available from the JasperSoft eShop) |
|||||
|
|
© 2001-2010 Jaspersoft Corporation www.jaspersoft.com |