Useful examples:
| Test | Description | Download PDF |
| ar.com.fdvs.dj.test.subreport.SubReportTest | Creates a single Subreport | download |
| ar.com.fdvs.dj.test.subreport.SubReportBuilderTest | Creates a single Subreport | download |
| ar.com.fdvs.dj.test.subreport.ConcatenatedReportTest | Creates a single PDF that concatenates 3 reports | download |
| ar.com.fdvs.dj.test.subreport.SubReportRecursiveTest | Creates a report that contains a subreport, and the subrerport contains a subreport too | download |
An easy way to add subreport is through the DynamicReportBuilder class (which internally uses SubReportBuilder, but makes it even easier) The SubReportBuilder class has much more options to setup a subreport, the quick methods added to the DynamicReportBuilder covers what we consider the most common scenarios, but for specific configurations SubReportBuilder should be used.
Look at the example bellow
DynamicReport drHeaderSubreport = createHeaderSubreport();
drb.addSubreportInGroupHeader(2, drHeaderSubreport, new ClassicLayoutManager(),
"statistics"
, DJConstants.SUBREPORT_DATA_SOURCE_ORIGIN_FIELD
, DJConstants.DATA_SOURCE_TYPE_COLLECTION);
drb.addField("statistics", List.class.getName());
.addSubreportInGroupHeader( <group number>, <dynamicReport>, <LayOutManager>
, <path to the data source>, <origin of the data source>, <type of the data source>)
group number: Subreports are placed in the header or footers of a group. This parameter defines which group
dynamicReport: A DynamicReport object to use as a subreport. In this example we create it in the call to createHeaderSubreport()
LayOutManager: Since the subreport is going to be a DynamicReport, a LayOutManager is needed
path to the data source: A string that points to the data source.
origin of the data source: A constant from DJConstants class which can be: SUBREPORT_DATA_SOURCE_ORIGIN_FIELD or SUBREPORT_DATA_SOURCE_ORIGIN_PARAMETER, it just tells the subreport where to look for the data source (the parameters map, or if its a property of the current row)
For example, if path to the data source is "subreportDatasource" and origin of the data source is SUBREPORT_DATA_SOURCE_ORIGIN_PARAMETER, then it will look in the parameters map for an object under the key of "subreportDatasource", on the other hand if we pass SUBREPORT_DATA_SOURCE_ORIGIN_FIELD, in the current row, there must be a property with the name "subreportDatasource" that returns an object of the type DATA_SOURCE_TYPE_<XXX>
type of the data source: A constant from DJConstants class, all types constants has a name like DATA_SOURCE_TYPE_<XXX>, where <XXX> represents the type. Most known types are java.sql.ResultSet, Collection, Array, Xml, etc.
SubreportParameter[] params An array of parameters (in parent report) to make available in child report.
boolean startInNewPage tells the DJ to make the sub report to start in a new page.
drb.addField("statistics", List.class.getName());
Because in this example, the origin is DJConstants.SUBREPORT_DATA_SOURCE_ORIGIN_FIELD, there must be such a field in the reports datasource. That is why, registering the field is necessary.
This is a example of a report with 2 different subreports

The SubReportBuilder class covers all possible configurations left behind by the DynamicReportBuilder, since the first one is the specific one to do this job.