Jump to content
Changes to the Jaspersoft community edition download ×

  • Giulio Toffoli
    • Version: v3.6.0 Product: iReport Designer

    by Giulio Toffoli

    A subreport is a report included inside another report. This allows the creation of very complex layouts with different portions of a single document filled using different data sources and reports.

    In this tutorial we want to create an address book printing for each person in the address book the name, the list of phone numbers and the list of email addresses.

    The layout we want to obtain is the one in figure 1.

    figure_1.png.5018c423e836aa63c00d2cde66d497ef.png
    Figure 1

    A master report will be used to select the persons from the address book and render the main page and the person details. A first subreport will be used to select the email addresses of each person and render the orange portion. Finally a second subreport will be used to extract the phone numbers and print them (blue portion).

    To fill the report, we will use the following database script.

    create table PERSONS (
       ID int primary key,
       NAME varchar(30),
       CITY varchar(30) );

    insert into PERSONS values(1, 'ETHAN', 'NEW YORK');
    insert into PERSONS values(2, 'CALEB', 'SAN FRANCISCO');
    insert into PERSONS values(3, 'WILLIAM', 'LONDON');
              
    create table EMAIL_ADDRESSES (
       ID int primary key,
       ID_PERSON varchar(30),
       EMAIL varchar(100) );

    insert into EMAIL_ADDRESSES values(1, 1, 'ethan@yahoo.com');
    insert into EMAIL_ADDRESSES values(2, 1, 'ethan@gmail.com');
    insert into EMAIL_ADDRESSES values(3, 2, 'caleb@yahoo.com');
    insert into EMAIL_ADDRESSES values(4, 2, 'caleb2@linux.com');
    insert into EMAIL_ADDRESSES values(5, 2, 'cccleb@jaspersoft.com');
    insert into EMAIL_ADDRESSES values(6, 3, 'wlm@somedomain.co.uk');
    insert into EMAIL_ADDRESSES values(7, 3, 'william@someemail.eu');
    insert into EMAIL_ADDRESSES values(8, 3, 'willy@myemail.org');
       
    create table PHONE_NUMBERS (
       ID int primary key,
       ID_PERSON varchar(30),
       PHONE varchar(100) );
       
    insert into PHONE_NUMBERS values(1, 1, '1(111) 111-1111');
    insert into PHONE_NUMBERS values(2, 1, '1(222) 222-2222');
    insert into PHONE_NUMBERS values(3, 1, '1(333) 333-3333');
    insert into PHONE_NUMBERS values(4, 2, '1(444) 444-4444');
    insert into PHONE_NUMBERS values(5, 3, '1(555) 555-5555');
    insert into PHONE_NUMBERS values(6, 3, '1(666) 666-6666');

    We start from a blank report to create the master report, the one to show the person names. It is a very simple report based on the query:

    SELECT * FROM PERSONS;

    In the detail band we add the field NAME and CITY. The gray background is obtained using a frame element that contains the two fields.

    The line at the bottom of the detail band has the property Position Type set to float, in this way, when we will add the subreports, whatever space the subreport elements will take at run time, the line will move accordingly.

    The figure 2 shows the layout of the master report.

    figure_2.png.724284a1b0215cc51d4b566c542efd4e.png
    Figure 2

    Run the report, the result must be similar to the one in figure 3.

    figure_3.png.7e457f283773033ba65687dd1f2cdb44.png
    Figure 3

    The second step is to create the subreport to display the email addresses. Start with a blank report, save it in the same directory as the master, and call it subreport_1.jrxml.

    Open the page format dialog (Format → Page format...) and reduce the size of the page to 270 pixels and remove the margins, since they are not useful in a subreport. The height of the report in this case is not very interesting, since it will managed by the master report once this report will be used as subreport.                         

    figure_4.png.43ef8f15a72c0c7fd4aaff477d291521.png
    Figure 4

    This report will not list all the email addresses read from the table EMAIL_ADDRESSES, but just the ones of the current person in the master. To filter the email addresses, we will use a parameter. In the report inspector right click the Parameters node and select Add Parameter. In the property sheet change the parameter name to ID_PERSON, set the parameter class to java.lang.Integer and set a default value, i.e. 1.

    figure_5.png.6bb9353cac3cc76b8ba4f3a8d6e511ab.png
    Figure 5

    Open the query dialog and paste the query:

    SELECT * FROM EMAIL_ADDRESSES WHERE ID_PERSON=$P{ID_PERSON}

    The syntax $P{ID_PERSON} allows the use of a parameter inside a query, in this case to filter the result using a where condition.

    Close the query dialog and proceed with the report layout (see figure 6).

    figure_6.png.ef3577096096e5ec7b0b86da38ab18dc.png
    Figure 6

    If you want you can run this report to see the result.

    Repeat the same steps to create the second subreport to display the phone numbers. Call it subreport_2.jrxml and save it in the same directory as the other two jrxml files.
    This time the query will be:

    SELECT * FROM PHONE_NUMBERS WHERE ID_PERSON=$P{ID_PERSON}

    The layout of the second subreport should be similar to the following picture:

    figure_7.png.5031c7aeee86d7d309a012964e13c484.png
    Figure 7

    It's time to put all togheter. Go back to the master report and drag from the palette into the detail band the subreport element.

    The report wizards pops up. Select the second option (Use an existing report) and select the subreport_1.jrxml (or subreport_1.jasper if you have already tried it).

    figure_8.png.25e600eb124d1401836bc2b6e410f7a4.png
    Figure 8

    In the following step use the option "Use the same connection used to fill the master report" (which should be selected by defaut). In this way the database connection will be passed to the subreport to let it execute its SQL query.

    Click next. In the next step we can set an expression for the parameter exposed by the subreport. Set it to the field ID. When the report will be executed, the email addresses will be filtered based on the ID of the current report (which is the ID of the person we are processing).

    figure_9.png.7f300c387d788cf5638138254185fe26.png
    Figure 9

    Complete the wizard keeping all the default settings. The new subreport element will be placed inside the detail, adjust its size (the width must be set to 270 pixels) and the position so it can fit in the available space (see figure 10).

    figure_10.png.199c279218aaf0b69eb1325ce31d3b23.png
    Figure 10

    Copy and paste the subreport element. The only difference between the two subreport elements is the reference to the jasper file to use as subreport. In the property sheet change the Subreport expression as follow:

    $P{SUBREPORT_DIR} + "subreport_2.jasper"

    The parameter name (ID_PERSON) is the same in both the subreports, like the way it is passed from the master, so there are no other changes to do. Fix the position of the second subreport to be on the right of the first one.

    figure_11.png.070db40fae821b94220654ed8a2d2d26.png
    Figure 11

    Finally run the report. The expected result is shown in figure 12.

    figure_12.png.8fb5dde260858ced8b87edf5f65d9760.png
    Figure 12

    This tutorial covers just the basics of subreporting in JasperReports. It uses a JDBC connection and staic paths to the subreports. Subreports can be filled with any kind of data source, including XML, a collection of java beans, an empty data source and so on. The subreport is then able to return to the master results of calculations using return values, the jasper file to be used a subreoprt can be loaded dynamically and a subreport can include other subreports, allowing the creation of very complex layouts.


    More on Complex Reporting

    Creating Charts and Subreports with Jaspersoft Studio

     


    User Feedback

    Recommended Comments

    Is there any way I can connect the report master with the subreport without performing the use of the bank adapter in either of the two reports? I'm calling the file.jasper direct in code to generate the report with a database created, but wanted to do this without having to relate the database to the report directly in jasper using the adapters. Would you have that possibility?

    Link to comment
    Share on other sites

    i have a requirement , where i have a master report  and i need to iterate N number or sub report , how can i achieve that . 
    There should be synchronous iteration between master and sub report .

     

    Link to comment
    Share on other sites

    1 hour ago, srivatsan.p said:

    i have a requirement , where i have a master report  and i need to iterate N number or sub report , how can i achieve that . 
    There should be synchronous iteration between master and sub report .

     

    Placing a sub-report in the detail will iterate the sub-report as many times as the number of rows returned in the master report's result set

    Link to comment
    Share on other sites



    Create an account or sign in to comment

    You need to be a member in order to leave a comment

    Create an account

    Sign up for a new account in our community. It's easy!

    Register a new account

    Sign in

    Already have an account? Sign in here.

    Sign In Now

×
×
  • Create New...