Last updated by sebastian.hohns 4 months ago
Jasper-Plugin Tutorial
This plugin allows you to integrate reports
Jasperreports
into your Grails application. This allows you to export data from your DBS to a number of different file formats.
Currently the following formats are supported:
- PDF
- HTML
- XML
- CSV
- XLS
- RTF
- TEXT
- ODT
- ODS
- DOCX
- XLSX
- PPTX
Contact
Please report bugs and feature requests at
JIRA or at the
Grails-User Mailinglist.
Authors :
- Marcos Pereira (marcos.pereira@signove.com)
- Sebastian Hohns (sebastian.hohns@googlemail.com)
Contributers :
- Egon Jensen
- JoÃÂão Paulo
- VinÃÂÃÂcius Cavalcanti
- Craig Jones
- Aaron Eischeid
Index
- Configuration
- Tags
- Services
- Step-by-step guide
- Releases
Configuration
The default location for your report templates is web-app/reports in your project directory. Here you can place
your *.jasper or *.jrxml (jrxml files will be compiled automatically by the plugin).
Work with jrxml files if you can! They can be compiled by the plugin if a newer jasperreport version is available. This way you
don't need to manually recompile all your reports if you want to use the new version with braking changes.
You can set another report folder location with the jasper.dir.reports property in your Config.groovy. Of course it's possible
to use different locations for different environments.
environments {
development {
// relative to web-app
jasper.dir.reports = '../src/reports'
}
production {
// relative to web-app
jasper.dir.reports = '/home/sampleuser/Jasper-Reports'
}
}Tags
The plugin provides a number of tags to help with the integration in your pages.
jasperReport
The jasperReport tag generates a button for every file specified file format. With a click on one of these icons
you generate the report which is returned as the response.
<g:jasperReport
jasper="sample-jasper-plugin"
format="PDF,HTML,XML,CSV,XLS,RTF,TEXT,ODT,ODS,DOCX,XLSX,PPTX"
name="Parameter Example">
Your name: <input type="text" name="name"/>
</g:jasperReport>The input of the text field will be passed to the report as a parameter.
Attributes:
- jasper - filepath, relative to your configured report folder, of the report, no file extension needed (Required)
- format - supply the file formats you want to use in a simple list (Required)
- name - name of the report
- delimiter - delimiter between the icons representing the file formats.
- delimiterBefore - delimiter in front of the icons
- delimiterAfter - delimiter at the end of the icons
- description - description of the report
- buttonPosition - position of the icons (top or below)
jasperForm & jasperButton
The jasperForm-Tag works the same way as the jasperReport tag, but gives you more control over how the form is rendered in HTML.
Use the jasperButton-Tag inside a jasperForm to submit and generate the report.
jasperForm-Attributes:
- jasper - filepath, relative to your configured report folder, of the report, no file extension needed. (Required)
- controller - The controller the form will submit to. (Required)
- action - The action the form will submit to. (Required)
- id - The id attribute for the form.
- class - Style class to use for the form. The default is "jasperReport".
jasperButton-Attributes:
- format - The name of the supported output format. ex. 'pdf' or 'PDF'. (Required)
- class - Class of the element in addition to default.
- text - Text to be included next to button ex. 'print'.
<g:jasperForm controller="jasper"
action="exampleWithData"
id="1498"
jasper="w_iReport" > ..form contents.. <g:jasperButton format="pdf" jasper="jasper-test" text="PDF" /> .. other html.. </g:jasperForm>
Services
From version 1.1 upwards it's possible to generate your report, without the controller action from above, with simple
service methods (so that you can generate your reports with a cron job in combination with the Quartz plugin).
The central element for this feature is a new wrapper class JasperReportDef. Instead of putting everything in the parameter
map you create a simple object containing the relevant data.
def reportDef = JasperReportDef(name:'your_report.jasper',
fileFormat:JasperExportFormat.PDF_FORMAT
)As you can see there are only two required attributes. Of course you need provide the name of your report and the target file
format. All available file formats can be found in the <strong>JasperExportFormat</strong> enum. You just have to choose one.
JasperReportDef has the following properties:
- name - Name of the Report. (Required)
- fileFormat - Fileformat of the Report. Please use the JasperExportFormat Enum. (Required)
- folder - The folder where you placed your reports. Defaults to /reports if unset and no global setting (jasper.report.dir in Config.groovy) exists.
- reportData - Collection containing the data of your report (leave empty if you want to use a SQL query inside your report)
- locale - Locale to use in the report generation.
- parameters - All additional parameters as a Map.
All you need to do now is to call one of the methods provided in <strong>JasperService</strong>:
- generateReport(JasperReportDef reportDef) - Generate a "normal" report.
- generateReport(List<JasperReportDef> reports) - Generate a single response containing multiple reports.
Both return a ByteArrayOutputStream with which you can do everything you want.
import org.codehaus.groovy.grails.plugins.jasper.JasperExportFormat
import org.codehaus.groovy.grails.plugins.jasper.JasperReportDef class YourClass {
def jasperService
public void yourMethod() {
def reportDef = new JasperReportDef(name:'your_report.jasper',
fileFormat:JasperExportFormat.PDF_FORMAT
) FileUtils.writeByteArrayToFile(new File("/your/target/path/test.pdf"), jasperService.generateReport(reportDef).toByteArray())
}
}
The example above uses the apache common-io FileUtils to store the response on the disc.
Step-by-step guide;
This guide shows how to call JasperReports from within Grails.
Written by Egon Jensen and Marcos FÃÂábio Pereira.
I liked the
Racetrack application in
Getting Started with Grails, but I'm missing something. Wouldn't it be nice if you were able to create a report with all the races in, say, PDF format?
Don't worry; JasperReports can do that, and it is easy to use in Grails.
To follow this tutorial, you first have to create the Racetrack application from Getting Started with Grails. But of course you can use your own application, just remember to do the necessary changes as you follow along.
First you have to install JasperGrails
grails install-plugin jasper
Now modify "Racetrack/grails-app/views/race/list.gsp"
[...]<div class="paginateButtons"><g:paginate total="${Race.count()}" />
</div>
<g:jasperReport jasper="all-races" format="PDF" name="All Races" /></div></body></html>
That's right; all we need is one line :-)
Now start the application
Open a browser, and go to
http://localhost:8080/racetrackLogon and below the Race List, you'll now find a PDF icon.
">
Press the icon, and ...
Ups!
We forgot the JasperReports file :-(
As you can see in the error message, we are supposed to create and save "all-races.jasper" (a good tool to do this is IReport) in "racetrack/web-app/reports/". After doing that, use the browsers back button and try the PDF icon again. This time it works better.

Open the file and you get a beautiful report with all the races.

OK, I admit it, JasperReports (and iReports) is not my strong side.
Besides, this is a tutorial for JasperGrails, not for JasperReports :-)
Let's try another example.
This time we will export all the registrations for a given race to Excel. Again we start with modifying the view: "racetrack/grails-app/views/race/show.gsp"
[...]<div class="buttons"><g:form><input type="hidden" name="id" value="${race?.id}" />
<span class="button"><g:actionSubmit class="edit" value="Edit" /></span><span class="button"><g:actionSubmit class="delete" onclick="return warnBeforeRaceDelete();" value="Delete" /></span></g:form></div><g:jasperReport jasper="registrations" format="XLS" name="Registrations">
<input type="hidden" name="race_id" value="${race.id}" />
</g:jasperReport></div></body></html>
We want to pass an argument to JasperReport, and we can do just that with a hidden field. Remember to include the JasperReports file.
This time we will try with the jrxml format. Thus we save "registrations.jrxml" in "racetrack/web-app/plugins/jasper-0.8/reports/".
Remember to include the following in "registrations.jrxml", to accept the argument we send from "show.gsp":
<parameter name="race_id" isForPrompting="false" class="java.lang.String"><defaultValueExpression><![CDATA["<parameter error>"]]></defaultValueExpression></parameter><queryString><![CDATA[select * from registration where race_id = $P{race_id}]]></queryString>
Click on "Turkey Trot", and below Show Race, we now have an Excel icon.
Press the icon and open the resulting file.
Releases
Version 1.5* Update to jasperreport 4.5.0 and POI 3.7
- Support for Images in HTML Reports (thanks to Rafael Gutierrez for the patch)
- various bugfixes
release 9-Jan-2012
Version 1.2
- Update to jasperreport 4.0.0 (sounds like a new major release of the lib, but it isn't)
Version 1.1.0
release 7-Aug-2010
New features:
- Update to jasperreport 3.7.4
- generate reports with service methods (see the included demo.gsp for documentation)
Version 1.0.0
release 08-Jul-2010
New features:
- Support for OpenDocument and OOXML export (ODS, ODT, DOCX, XLSX, PPTX)
- Option to disable default parameters
- Parameter pass-through
- Japser libraries updated to newest version (3.7.3)
- Refactored service with the ability to create a single document form more than one jrxml/jasper file.
- finally uses packages
Bug fixes:
Changelog
Version 0.9.5
release 23-Jan-2009
New features:
- New tags which allow for greater control of JasperForms layout and button placement, and unobtrusive JS and CSS. see demo.gsp for documentation
- Icons rendered via CSS and new small PDF icon included
- Can now use latest iReport to edit reports thanks to updated Jasper libraries
Version 0.9 (Thanks to Craig Jones)
(Pending release as of 16-Aug-2008, so obtain from subversion trunk)
New features:
- Added many new attributes to <g:jasperReport> that control the rendering (see demo.gsp)
- Now, if the g:jasperReport tag does not have a body, then the rendered HTML will be just a series of one or more <A> tags (no form and no javascript for submitting said form).
- Combined the redundant admin.gsp and howto.gsp into a single demo.gsp.
- Added lots more documentation and examples to demo.gsp.
Bug fixes:
- The Format attribute is now tolerant of lower case format values (pdf vs. PDF) and spaces between values.
- The tag validation code now checks for the two required attributes: jasper and format
- Rendering now uses and <strong> (rather than nothing and <b>) in places
- No longer renders the word "null" when the name attribute is left blank
Infrastructure changes:
- Numerous. (See subversion log.)
Version 0.8
New features:
- Attribute 'from' was removed.
- Attributes 'controller' and 'action' was included.
The developer have to use the follow architecture if the developer don't want to use SQL into reports:

Version 0.7.7 (Thanks to Achim Breunig)
New features:
- Attribute 'inline=<boolean>' was included in jasperReport tag. Now, pdf-files can be shown inline in the web-browser.
- Bug fixed:
- Solved problem that the 'format'-attribute did not accept spaces.
- Solved problem that sometimes the from-parameter was not found.
- The default locale of the report is the request locale.
- The default subreport folder is the same of the report.
Version 0.7.6
New features:
- The user can to retrieve data report from domain classes:
- Attribute 'from' was included in jasperReport tag.
- XLS parameters were improved: (Thanks to Sebastian Esch)
- One page per sheet;
- Auto detect cell type;
- Remove empty space between rows;
- White page background is disabled.
- Bug fixed:
- Plugin didn't work on Linux (File separator was wrong). (Thanks to Sebastian Esch)
Version 0.7.5
- Bug fixed:
- Bug in JasperService.groovy that can cause connection leaks, connection is never closed. (Thanks to Pass F. B. Travis)
Last updated by bridgetwidget 6 months ago
FAQ
MalformedByteSequenceException
In some configurations exceptions like
com.sun.org.apache.xerces.internal.impl.io.MalformedByteSequenceException: Invalid byte 1 of 1-byte UTF-8 sequence.
are thrown. This is a iReport problem. Install the "XML and Schema" plugin in iReport. This should give you a more specific error message with a specific location. This bug is odd, sometimes it's enough to compile the exactly same report on a different system to solve it.
In some cases it helps to add
"-J-Dfile.encoding=UTF-8"
to the default_options in the iReport configuration file ireport.conf.
If this doesn't help and you are on windows you can manually quick-fix the jrxml file the following way:
- Open notepad, don't type anything, click File - Save as… - and change the coding to UTF-8 and choose a new filename, then save. Now you have a file with the right encoding.
- Paste the content of your malformed jrxml file into this new file and save again. From now on the encoding will stay UTF-8.
- Dont't forget to change your gsp to the new filename or delete the malformed file and rename the UTF one back.
Can i get the report data from domain classes, instead of a sql query?
Yes, the user can retrieve data to the report directly from domain classes, without using SQL queries in the .jrxml file. It's only necessary to set the 'controller' and 'action' attributes in jasperReport tag, like showed bellow:
<g:jasperReport controller="my-controller" action="my-action" jasper="all-races" format="PDF" name="All Races" />
In the action "my-controller/my-action", the developer has to get all data from model using the line bellow and updating <MODEL_DATA> string:
<MODEL_DATA> = Domain-Class.list() or
<MODEL_DATA> = ['field1':value1,'field2':value2] or
<MODEL_DATA> = anything you want that returns a map or a list of map...
chain(controller:'jasper',action:'index',model:[data:<MODEL_DATA>],params:params)
Now, the .jrxml file can be defined without a datasource. The only thing you have to remember is to set the name of all fields in the report with the same name of the attributes in the <MODEL_DATA> object.
You can also do some groovy drilling down on the objects you pass into the report. For example if you passed in a list of races from your controller like:
def races = Race.getAll(23,25,26)
races.each{
println it.sposor.address
}
chain(controller:'jasper',action:'index',model:[data:races],params:params)(grails 1.0.4 does something different with lazy fetching and the println is just a dirty work around for getting the GORM to load the objects.)
You could reference them in the jrxml file like:
<field name="sponsor.address.city" class="java.lang.String"/>
…
…
<textFieldExpression class="java.lang.String">
<![CDATA[$F{sponsor.address.city}]]>
</textFieldExpression>
Remember to set the language of your report to Groovy instead of Java!
<jasperReport … language="groovy" … >
Can i use sub reports with Jasper Plugin?
Yes, if you put the sub report file in the same folder of the parent report file "APP-FOLDER/web-app/plugins/jasper-x.x/reports/" then it should work fine.
But, if you want to put the sub report file in another folder, you've to add the SUBREPORT_DIR as a parameter to your jasperReport tag.
Thanks to Achim Breunig.
<parameter name="SUB_REPORTDIR" class="java.lang.String" isForPrompting="false"/>
…
<field name="races" class="java.util.Collection"/>
<subreport isUsingCache="true">
<reportElement key="subreport-1" x="17" y="362" width="387" height="89"/> <dataSourceExpression>
<![CDATA[new JRBeanCollectionDataSource($F{races})]]>
</dataSourceExpression> <subreportExpression class="java.lang.String">
<![CDATA[$P{SUBREPORT_DIR} + "/jasper-test_subreport1.jasper"]]>
</subreportExpression></subreport>where you have to put the subreports seems to differ for differet OS's:
Windows and Mac users can usually get away with putting the reports in the web-app/reports dir, but not always...
If this isn't working try using the compiled reports, and/or moving things into WEB-INF/reports.
Sub Report Work arounds
// For Local Grails Server
File folder = new File(".");
String folderString = folder.getAbsolutePath().toString();
folderString = folderString.substring(0, folderString.length()-2);// For Tomcat Deployment
if (folderString.endsWith("/bin")) {
folderString = folderString.substring(0, folderString.length()-4)
+ "/webapps/{APP_NAME}"
}// Reset SUBREPORT_DIR
parameters.SUBREPORT_DIR = folderString + "/WEB-INF/" + parameters.SUBREPORT_DIR;
"In My experience putting reports into WEB-INF/reports, you need to keep your parents report in /web-app/reports else jasper will not be able to find the parent reports. Please consider the following code above for single level sub reports, if you have sub report in sub report, this wont help" Churk
Another alternative could be the described in this stackoverflow question:
http://stackoverflow.com/questions/4288254/grails-jasper-plugin-invalid-byte-1-of-1-byte-utf-8-sequence-error-with-jas/8010221#8010221