Try the examples first!

The source code comes with examples ready to run (you need Maven 2 to build the source code)

The examples classes are:

Test Description Download PDF
ar.com.fdvs.dj.test.FastReportTest A simple example that shows the basic setup of a report and its columns download
ar.com.fdvs.dj.test.PlainReportTest A example that shows how to get more control on the basic setup of a report and its columns download
ar.com.fdvs.dj.test.StylesReportTest Based on the PlainReportTest test, shows how to add some styles to the different elements in the report download
ar.com.fdvs.dj.test.GroupsReportTest Based on the StylesReportTest test, this test shows how to define groups and variables at the header and footer of each group download
ar.com.fdvs.dj.test.ConditionalStylesReportTest This test shows how to create a simple conditional style. The style of the values from a column changes as a certain condition is meat download
ar.com.fdvs.dj.test.ImageBannerReportTest This test shows how to add images to the title of the report and the header download
ar.com.fdvs.dj.test.ChartReportTest Based on GroupsReportTest, shows how to add charts to a report, using a chart builder download
ar.com.fdvs.dj.test.AutotextReportTest Based on FastReportTest, shows how to add autotext out-of-the-box such as "page x/y", etc download
ar.com.fdvs.dj.test.ReflectiveReportTest With almoust no code, you get an instant report! it uses the ReflectiveReportBuilder wich make some guesses upon the data type of the elements contained in the datasource and apply a style to them download

Here is the online source code off the tests

Note: This tests extends junit.framework.TestCase, but they also contain a main(...) method, we recommend to execute the test through the main method because the JUnit framework closes the JasperViewer (a window that shows the report) inmeadiatly after exiting the program.

Creating a simple Report

This fragment shows how to create a report in an ease and fast way. see the code

        FastReportBuilder drb = new FastReportBuilder();
        DynamicReport dr = drb.addColumn("State", "state", String.class.getName(),30)
                        .addColumn("Branch", "branch", String.class.getName(),30)
                        .addColumn("Product Line", "productLine", String.class.getName(),50)
                        .addColumn("Item", "item", String.class.getName(),50)
                        .addColumn("Item Code", "id", Long.class.getName(),30,true)
                        .addColumn("Quantity", "quantity", Long.class.getName(),60,true)
                        .addColumn("Amount", "amount", Float.class.getName(),70,true)
                        .addGroups(2)
                        .setTitle("November 2006 sales report")
                        .setSubtitle("This report was generated at " + new Date())
                        .setPrintBackgroundOnOddRows(true)                      
                        .setUseFullPageWidth(true)
                .build();       
        
        JRDataSource ds = new JRBeanCollectionDataSource(TestRepositoryProducts.getDummyCollection());   
        JasperPrint jp = DynamicJasperHelper.generateJasperPrint(dr, new ClassicLayoutManager(), ds);
        JasperViewer.viewReport(jp);    //finally display the report report             

This code produces the report shown below

Fast Report

The FastReportBuilder provides the methods to pass the basic parameters to the report:

  • addColumn( <title>, <field/property to show>, <class name of the property to show>, <width of the column> )
  • addGroups (<number of columns to group by>)
  • setTitle(...) , setSubtitle( ...) : guess!!!
  • setUseFullPageWidth( <boolean> ) : if true, the columns width will be resized proportionally until meet the page width

In the previous report, the DynamicJasper API makes a lot of decisions setting default values to the styles in general (title, column header, report detail, etc). This defaults are defined in the FastReportBuilder class. More control in all this aspects can be achieved using the DynamicReportBuilder class, as shown in the next example

Getting more control on the report options

This code shows how to create a simple report but taking more control on the report options, the code is self explained. see the code

        DynamicReportBuilder drb = new DynamicReportBuilder();
        drb.setTitle("November 2006 sales report")                                      //defines the title of the report
                .setSubtitle("The items in this report correspond "
                                +"to the main products: DVDs, Books, Foods and Magazines")
                .setDetailHeight(15)                                            //defines the height for each record of the report
                .setMargins(30, 20, 30, 15)                                                     //define the margin space for each side (top, bottom, left and right)
                .setDefaultStyles(titleStyle, subtitleStyle, headerStyle, detailStyle)
                .setColumnsPerPage(1);                                          //defines columns per page (like in the telephone guide)

        /**
         * Note that we still didn't call the build() method
         */

        /**
         * Column definitions. We use a new ColumnBuilder instance for each
         * column, the ColumnBuilder.getInstance() method returns a new instance
         * of the builder
         */
        AbstractColumn columnState = ColumnBuilder.getInstance()                //creates a new instance of a ColumnBuilder
                .setColumnProperty("state", String.class.getName())                     //defines the field of the data source that this column will show, also its type
                .setTitle("State")                                                                                      //the title for the column
                .setWidth(85)                                                                   //the width of the column
                .build();                                                                                                       //builds and return a new AbstractColumn

        //Create more columns
        AbstractColumn columnBranch = ColumnBuilder.getInstance()
                .setColumnProperty("branch", String.class.getName())
                .setTitle("Branch").setWidth(85)
                .build();

        AbstractColumn columnaProductLine = ColumnBuilder.getInstance()
                .setColumnProperty("productLine", String.class.getName())
                .setTitle("Product Line").setWidth(85)
                .build();

        AbstractColumn columnaItem = ColumnBuilder.getInstance()
                .setColumnProperty("item", String.class.getName())
                .setTitle("Item").setWidth(85)
                .build();

        AbstractColumn columnCode = ColumnBuilder.getInstance()
                .setColumnProperty("id", Long.class.getName())
                .setTitle("ID").setWidth(40)
                .build();

        AbstractColumn columnaCantidad = ColumnBuilder.getInstance()
                .setColumnProperty("quantity", Long.class.getName())
                .setTitle("Quantity").setWidth(80)
                .build();

        AbstractColumn columnAmount = ColumnBuilder.getInstance()
                .setColumnProperty("amount", Float.class.getName())
                .setTitle("Amount").setWidth(90)
                .setPattern("$ 0.00")           //defines a pattern to apply to the values swhown (uses TextFormat)
                .setStyle(amountStyle)          //special style for this column (align right)
                .build();

        /**
         * We add the columns to the report (through the builder) in the order
         * we want them to appear
         */
        drb.addColumn(columnState);
        drb.addColumn(columnBranch);
        drb.addColumn(columnaProductLine);
        drb.addColumn(columnaItem);
        drb.addColumn(columnCode);
        drb.addColumn(columnaCantidad);
        drb.addColumn(columnAmount);

        /**
         * add some more options to the report (through the builder)
         */
        drb.setUseFullPageWidth(true);  //we tell the report to use the full width of the page. this rezises
                                                                        //the columns width proportionally to meat the page width.


        DynamicReport dr = drb.build(); //Finally build the report!


    JRDataSource ds = new JRBeanCollectionDataSource(TestRepositoryProducts.getDummyCollection());    //Create a JRDataSource, the Collection used
                                                                                                        //here contains dummy hardcoded objects...

    JasperPrint jp = DynamicJasperHelper.generateJasperPrint(dr, new ClassicLayoutManager(), ds);    //Creates the JasperPrint object, we pass as a Parameter
                                                                                                        //the DynamicReport, a new ClassicLayoutManager instance (this
                                                                                                        //one does the magic) and the JRDataSource
    JasperViewer.viewReport(jp);    //finally display the report report

The DynamicReportBuilder builds DynamicReport objects, this object contains the main options of the report (title, subtitle, styles, page size, orientation and a list of columns and groups)

The ColumnBuilder builds SimpleColumn and ExpressionColumn objects depending the case (they both inherit from AbstractColumn). Each column holds basic data like the column title, the field from the datasource to show (it uses BeanUtils, so "a.b.c" can be passed as a property parameter), and how to show this data (style, pattern to apply, etc).

Note that the property_name passed to ColumnBuilder.setColumnProperty("property_name", "property_class_name") method must match the name of a field/property in the elements contained in the datasource

Adding groups

Using the same code as before, we add this few lines. see the code

 GroupBuilder gb1 = new GroupBuilder();
 ColumnsGroup g1 = gb1.addCriteriaColumn((PropertyColumn) columnState).build();
 drb.addGroup(g1);              //add the group to the DynamicReportBuilder

Up to here, the DJ API will handle how to do the grouping stuff, but this isn't enough for most of the users so lets see how to put some variables (totals) in the footer and header of the group

GroupBuilder gb1 = new GroupBuilder();
        ColumnsGroup g1 = gb1.addCriteriaColumn((PropertyColumn) columnState)        //define the criteria column to group by (columnState)
            .addFooterVariable(columnAmount,ColumnsGroupVariableOperation.SUM)        //tell the group place a variable in the footer
                                                                                    //of the column "columnAmount" with the SUM of all
                                                                                    //values of the columnAmount in this group.

            .addFooterVariable(columnaQuantity,ColumnsGroupVariableOperation.SUM)    //idem for the columnaQuantity column
            .setGroupLayout(GroupLayout.DEFAULT_WITH_HEADER)                //tells the group how to be shown, there are many
                                                                                    //posibilities, see the GroupLayout class for more.
            .build();

        GroupBuilder gb2 = new GroupBuilder();                                        //Create another group (using another column as criteria)
        ColumnsGroup g2 = gb2.setCriteriaColumn((PropertyColumn) columnBranch)        //and we add the same operations for the columnAmount and
            .addFooterVariable(columnAmount,ColumnsGroupVariableOperation.SUM)        //columnaQuantity columns
            .addFooterVariable(columnaQuantity,ColumnsGroupVariableOperation.SUM)
            .build();

 //then we add the groups to the report (through the builder)

        drb.addGroup(g1);    //add group g1
        drb.addGroup(g2);    //add group g2

Here the order of the group registration is important and should be consistent with the order of the registration of the columns. If we mess here, the resultant report wont have any meaning.

Note: It's important to remember tha the data from the datasource must be ordered with the same criteria we want to group them.

Many more examples on groups: Grouping Styles

Adding charts

Using the same code as before, we add this few lines. see the code

DJChartBuilder cb = new DJChartBuilder();                               // create a chart builder
DJChart chart =  cb.addType(DJChart.PIE_CHART)                          // define the type of chart (Pie)
                                .setOperation(DJChart.CALCULATION_SUM)         // define the type of operation to be done
                                .setColumnsGroup(g1)                           // define the group that will be represented
                                .addColumn(columnAmount)                       // define the column that will be represented
                                .build();

then we add the groups to the report (through the builder)

drb.addChart(chart);    //add chart

Just changing the chart type parameter to a different constant, we make a bar chart

DJChartBuilder cb = new DJChartBuilder();                               // create a chart builder
DJChart chart =  cb.addType(DJChart.BAR_CHART)                          // define the type of chart (Bar)
                                .addOperation(DJChart.CALCULATION_SUM)         // define the type of operation to be done
                                .addColumnsGroup(g1)                           // define the group that will be represented
                                .addColumn(columnAmount)                       // define the column that will be represented
                                .build();

This code generate a report like this:

Fast Report