PDF Reports - AtlasOfLivingAustralia/profile-hub GitHub Wiki

eFlora Reports

General Info

This piece of documentation provides some information and guidelines around how the eFlora report has been implemented and what libraries and tools have been used in the development process.

The first prototype of the report tried to use the Wkhtmltopdf Grails plugin but there were memory issues when generating really big documents (some pdfs can contain thousands of pages). The use case of adding a TOC, a cover page as well as adding page indexes in the footer were also very difficult to implement using this mechanism.

After that, we decided to give a go to the good old JasperReports (JR) library that has been battle tested for quite a few years already, although in principle, not as easy to use as the previous approach.

Requirements

gvm install groovy 2.3.10

Reporting engine and tooling

As we already mentioned, the chosen reporting engine is called JasperReports. More specifically we are using the latest version to date which is 6.1.0. Since version 6 also hapens that a new Report Book feature has been added which covers our requirements of having a TOC, a cover page and a colophon page. This version also provides better support for JSON based Data Sources, which is what has been used to populate this report.

To start with JR is essential to read the following guide:

  • "JasperReports Ultimate Guide": PDF
  • A good compilation of reference information and doco can be found in this link.

Jaspersoft Studio is a custom distribution of the Eclipse IDE with a plugin specifically designed to work with JR, which among other things, provides a very convenient WYSIWYG editor. Familiarity with the Eclipse IDE would be beneficial, but the following guide is must read, regardless of your proficiency with the Eclipse IDE:

  • Jaspersoft Studio 6.1.0 guide: PDF | HTML

To integrate JR inside our Grails app we have used the Jasper Grails plugin, but adding some modifications on top:

  • Created the service JasperNonTransactionalService which does not require a classic relational DB based data source to be configured. Mainly because we don't have one as this app make use of web services as the backend. The modification performed have been included in a Pull Request for this plugin.
  • Modified plugin dependencies so we can use JR lib version 6.1.0 instead of the one included with the plugin:
  dependencies {
      ...

      compile('net.sf.jasperreports:jasperreports:6.1.0') {
          excludes 'antlr', 'commons-logging',
                  'ant', 'mondrian', 'commons-javaflow','barbecue', 'xml-apis-ext','xml-apis', 'xalan', 'groovy-all', 'hibernate', 'saaj-api', 'servlet-api',
                  'xercesImpl','xmlParserAPIs','spring-core','bsh', 'spring-beans', 'jaxen', 'barcode4j','batik-svg-dom','batik-xml','batik-awt-util','batik-dom',
                  'batik-css','batik-gvt','batik-script', 'batik-svggen','batik-util','batik-bridge','persistence-api','jdtcore','bcmail-jdk16','bcprov-jdk16','bctsp-jdk16',
                  'bcmail-jdk14','bcprov-jdk14','bctsp-jdk14','xmlbeans', 'olap4j'
      }
      compile 'net.sf.jasperreports:jasperreports-functions:6.1.0'
      compile 'net.sf.jasperreports:jasperreports-fonts:6.1.0'
      ...
  }

  plugins {
      ...
      compile(":jasper:1.11.0") {
          excludes 'jasperreports'
      }
      ...
  }

Project setup

To start developing the report using Jaspersoft Studio we need to import the project from our source code. Given the special nature of a JasperReport project all the Eclipse IDE specific meta-information has also been checked in our SCM repository, including the .classpath and '.project' files, as well as the .settings folder.

Steps to import the project

  1. Open Jaspersoft Studio.
  2. Make sure you use a workspace whose root folder is outside the profile-hub local repository.
  3. On the "Report Design" perspective we choose File -> Import to open the import dialog.
  4. In the dialog we select "Existing Projects into Workspace" and click "Next".
  5. Now we need to select the directory that contains our JasperReport project within the profile-hub local repository. Relative to this repo location, the JR project should be at .../grails-app/conf/reports. Make sure you don't select the "Copy projects to workspace" option. Once you have everything as per the following screenshot you can click on "Finish": Import project dialog
  6. After that you should have the project available in your workspace.

Setup classpath library dependencies

Given that the .classpath file is machine dependant, the JRE and Groovy dependencies will be probably broken as you might have them in a different place.

To fix it:

  1. Right click and the project and select: "Build Path" -> "Configure Build Path"...
  2. Edit the JRE and Groovy library locations if required

Setup JSON data source sample file location for testing

In order to render the report for development purposes without having to run tho whole profile-hub app, we use a sample JSON file that is configured using its absolute path in your file system. That means you will probably have to modify to point to the Acacia-paradoxa-DC.json file using its current absolute path:

  1. In the "Repository Explorer" tab, right-click on the "JSON Sample Data Source" and click on the "Edit Data Adapter" option as per the following screenshot: json data source
  2. That will open a dialog where you have to set the absolute path to the JSON sample file which is within the report sources at .../grails-app/reports/profiles

After all that you should be able to compile the reports and preview the report output.

Other considerations

  • The main or master report file is the PROFILES.jrxml file. You will have to open this file to run a full preview of the report. All the other .jrxml files are subreports.

  • Groovy language is used as the default expression language in all reports instead of Java. Here is why -> link

  • .jasper files are not to be included in the Git repository.

  • .jasper files are opened in Jaspersoft Studio the same way as .jrxml files. That can mislead the developers and make them loose all their changes next time the compilation process is run. So I suggest to filter all .jasper files from the project view like this: exclude .jasper files step 1 exclude .jasper files step 2

  • All the .jrxml files are compiled into .jasper files at compilation time via the Grails _Events.groovy script file

Other resources

  • Library to generate a QR code image for the report: QRGen