Sunday, December 19, 2010

Spring 3 MVC - DynamicJasper Integration Tutorial

In this tutorial we will integrate DynamicJasper with a simple Spring 3 MVC application. We will provide a custom data source where DynamicJasper will retrieve its data. The application will be layered so that we can easily modify the features or implementations of our application.

What is DynamicJasper?
DynamicJasper (DJ) is an open source free library that hides the complexity of Jasper Reports, it helps developers to save time when designing simple/medium complexity reports generating the layout of the report elements automatically.

Source: http://dynamicjasper.com/

What is JasperReports?
JasperReports is the world's most popular open source reporting engine. It is entirely written in Java and it is able to use data coming from any kind of data source and produce pixel-perfect documents that can be viewed, printed or exported in a variety of document formats including HTML, PDF, Excel, OpenOffice and Word.

Source: http://jasperforge.org/projects/jasperreports

Similar with our previous tutorial. We will setup our Spring 3 MVC application first. If you need a review with Spring MVC, I suggest you read the other tutorials I've posted. Or you can also Google for related tutorials.

Here's a screenshot of the report document that we will be generating:

This is just basic. You can add and show more features with Jasper and DynamicJasper. For now, we'll stick with the basics.

Our first task is to setup the main controller that will handle the download request.

MainController

This controller declares two mappings:
/download - for showing the download page
/download/xls - for retrieving the actual Excel report

Examine the doSalesReportXLS() controller method. It has a reference to a download service named downloadService. This service handles the actual report processing. Later, we'll discuss that in-depth.

The /download mapping will display the downloadpage view which resolves to /WEB-INF/jsp/downloadpage.jsp

downloadpage.jsp

This is a simple JSP. It has an HTML link for downloading the report. Notice the URL points to /krams/main/download/xls. The same mapping we have in the MainController.

Here's a screenshot of this page:

Next, we enable Spring MVC in the web.xml

web.xml

Take note of the URL pattern. When accessing any pages in our MVC application, the host name must be appended with
/krams

In the web.xml we declared a servlet-name spring. By convention, we must declare a spring-servlet.xml as well.

spring-servlet.xml

This XML config declares a view resolver. All references to a JSP name in the controllers will map to a corresponding JSP in the /WEB-INF/jsp location.

By convention, we must declare an applicationContext.xml

applicationContext.xml

This XML config declares three beans to activate the Spring 3 MVC programming model.

Let's return back to DynamicJasper.

If you remember back in the MainController we declared a reference to a DownloadService which is automatically injected by Spring.

The DownloadService is a delegate. All reporting processing is handled by this service.

DownloadService

To generate the report, we call the downloadXLS() method. This generates an Excel report. Let's examine further how the report is generated:

1. Retrieve an instance of our datasource:
SalesDAO datasource = new SalesDAO();
JRDataSource ds = datasource.getDataSource();

The datasource can come from a variety of sources like from an in-memory list, database, and alike. Later, we'll show what's inside this SalesDAO

2. Generate the Jasper layout:
ReportLayout layout = new ReportLayout();
DynamicReport dr = layout.buildReportLayout();

The layout is like the template of your report. It's basically the design of how you want the report to look like. Our Jasper layout is actually generated on the fly by DynamicJasper. That's the main purpose of DynamicJasper. It will dynamically, programmatically generate the layout. This is useful for generating tabular reports which are mostly used for professional applications. If you need to manually design or create an artistic layout, I advise you try layouting using Jasper's native JRXML format. DynamicJasper can also use a JRXML template, but that's beyond the scope of this tutorial.

3. Compile the Jasper layout into a JasperReport object:
JasperReport jr = DynamicJasperHelper.generateJasperReport(dr, new ClassicLayoutManager(), params);

The JasperReport object is the compiled version of your layout that can be understood by Jasper. Imagine it like this: the layout is for humans, while the compiled object is for the computer.

4. Create the Jasper print:
JasperPrint jp = JasperFillManager.fillReport(jr, params, ds);

This basically fills the JasperReport with contents from the datasource.

5. Export the report to your desired format. For this tutorial we will export it as an
Excel document.
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Exporter exporter = new Exporter();
exporter.export(jp, baos);

Here we pass an instance of a ByteArrayOutputStream and a JasperPrint object.

6. Set the response header and content type:
String fileName = "SalesReport.xls";
response.setHeader("Content-Disposition", "inline; filename="+ fileName);
response.setContentType("application/vnd.ms-excel");
response.setContentLength(baos.size());

Make sure you set the correct contentType.

7. Write the report to the output stream:
writeReportToResponseStream(response, baos);

Now, let's examine the remaining classes.

The ReportLayout
This is a custom wrapper to DynamicJasper's FastReportBuilder. The purpose of this class is to encapsulate the layout of the report. This isn't mandatory. You can remove the contents of buildReportLayout() and place it along with the DownloadService. Take note we're encapsulating a DynamicJasper feature here, not a Jasper. So if you have specific questions about these, make sure to search the DynamicJasper forums.

The Exporter
This is a custom wrapper to Jasper's JRXlsExporter. The purpose of this class is to encapsulate the exporting of the report to different formats. This isn't mandatory. You can remove the contents of export() and place it along with the DownloadService. Take note we're encapsulating a Jasper feature here, not a DynamicJasper. So if you have specific questions about these, make sure to search the Jasper forums.

The datasource
Here we provide a custom datasource made from in-memory list of Sales items. We use the DAO name here to indicate that the data can come from a DAO or other persistence means.

SalesDAO

Our datasource returns a list of Sales. This is a simple Data Transfer Object for containing our data from the database.

Sales

Our application is now finished. We've managed to setup a simple Spring 3 MVC application. Then we added reporting using DynamicJasper. We've divided our application's concerns in various layers: controllers, services, DAO, layout, and exporter so that we can easily change implementation and custom processing. We've also leveraged Spring's MVC programming model via annotation.

To access the download page, enter the following URL:
http://localhost:8080/spring-djasper-integration/krams/main/download


If you want to download the report directly, enter the following URL:
http://localhost:8080/spring-djasper-integration/krams/main/download/xls

The best way to learn further is to try the actual application.

Download the project
You can access the project site at Google's Project Hosting at http://code.google.com/p/spring-mvc-dynamicjasper-integration-tutorial/

You can download the project as a Maven build. Look for the spring-djasper-integration.zip in the Download sections.

You can run the project directly using an embedded server via Maven.
For Tomcat: mvn tomcat:run
For Jetty: mvn jetty:run

If you want to learn more about Spring MVC and Jasper, feel free to read my other tutorials in the Tutorials section.
StumpleUpon DiggIt! Del.icio.us Blinklist Yahoo Furl Technorati Simpy Spurl Reddit Google I'm reading: Spring 3 MVC - DynamicJasper Integration Tutorial ~ Twitter FaceBook

Subscribe by reader Subscribe by email Share