1. Introduction
|
top
|
|
|
^JasperReports is a powerful open source reporting tool that has the ability to deliver rich content onto the screen, to the printer or into PDF, HTML, XLS, CSV and XML files. It is entirely written in Java and can be used in a variety of Java enabled applications to generate dynamic content.
|
|
Its main purpose is to help creating page oriented, ready to print documents in a simple and flexible manner. |
|
|
^JasperReports organizes data retrieved from a relational database through JDBC according to the report design defined in an XML file. In order to fill a report with data, the report design must be compiled first.
|
|
|
The compilation of the XML file representing the report design is performed by the compileReport() method exposed by the net.sf.jasperreports.engine.JasperManager class.
|
|
Through compilation, the report design is loaded into a report design object that is then serialized and stored on disk (net.sf.jasperreports.engine.JasperReport ). This serialized object is then used when the application wants to fill the specified report design with data. In fact, the compilation of a report design implies the compilation of all Java expressions defined in the XML file representing the report design. Various verifications are made at compilation time, to check the report design consistency. The result is a ready to fill report design that will be then used to generate documents on different sets of data.
|
|
|
In order to fill a report design, one can use the fillReportXXX() methods exposed by the net.sf.jasperreports.engine.JasperManager class. Those methods receive as a parameter the report design object, or a file representing the specified report design object, in a serialized form, and also a JDBC connection to the database from where to retrieve the data to fill the report.
|
|
The result is an object that represents the ready to print document (net.sf.jasperreports.engine.JasperPrint ) and can be stored onto the disk, in a serialized form, for later use, or can be delivered to the printer, to the screen or can be transformed into a PDF, HTML, XLS, CSV or XML document.
|
|
2. Report Designs
|
top
|
|
|
As mentioned, a report design represents a template that will be used by the ^JasperReports engine to deliver dynamic content to the printer, to the screen or to the Web. Data stored in the database is organized according to the report design to obtain ready to print, page oriented documents.
|
|
|
The report designs are defined in XML files and must have a special structure. This structure is declared in a DTD file supplied with the ^JasperReports engine. The XML files are then compiled, in order to use them in report filling operations.
|
|
|
To create a simple report design, we have to edit an XML file with the following structure: |
|
|
<?xml version="1.0"?>
<!DOCTYPE jasperReport
PUBLIC "-//JasperReports//DTD Report Design//EN"
"http://jasperreports.sourceforge.net/dtds/jasperreport.dtd">
<jasperReport name="name_of_the_report" ... >
...
</jasperReport>
|
|
3. Parameters
|
top
|
|
|
Parameters are object references that are passed-in to the report filling operations. |
|
|
They are very useful for passing to the report engine data that it can not normally find in its data source. |
|
|
For example, we could pass to the report engine the name of the user that has launched the report filling operation, if we want it to appear on the report, or we could dynamically change the title of our report. |
|
|
An import aspect is the use of report parameters in the query string of the report, in order to be able to further customize the data set retrieved from the database. Those parameters could act like dynamic filters in the query that supplies data for the report. |
|
|
Declaring a parameter in a report design is very simple and it requires specifying only its name and its class: |
|
|
<parameter name="ReportTitle" class="java.lang.String"/>
<parameter name="MaxOrderID" class="java.lang.Integer"/>
<parameter name="SummaryImage" class="java.awt.Image"/>
|
|
There are two possible ways to use parameters in the query: |
|
|
1. The parameters are used like normal java.sql.PreparedStatement parameters using the following syntax: |
|
|
|
|
2. Sometimes is useful to use parameters to dynamically modify portions of the SQL query or to pass the entire SQL query as a parameter to the report filling routines. In such a case, the syntax differs a little, like in the following example: |
|
|
SELECT * FROM Orders ORDER BY $P!{OrderByClause}
|
|
There are also the following built-in system parameters, ready to use in expressions: |
|
REPORT_PARAMETERS_MAP
|
|
REPORT_CONNECTION
|
|
REPORT_DATA_SOURCE
|
|
REPORT_SCRIPTLET
|
|
REPORT_LOCALE
|
|
REPORT_RESOURCE_BUNDLE
|
|
Documentation pending... |
|
4. Data Source
|
top
|
|
|
^JasperReports support various types of data sources using a special interface called JRDataSource .
|
|
|
There is a default implementation of this interface (JRResultSetDataSource class) that wraps a ResultSet object. It allows the use of any RDMS database through JDBC.
|
|
|
When using a JDBC data source, one could pass a Connection object to the report filling operations and specify the query in the report definition itself (see the <queryString> element in the XML file) or could create a new instance of the JRResultSetDataSource by supplying the ResultSet object directly.
|
|
|
With other types of data sources, things should not be different and all we have to do is to implement the JRDataSource interface.
|
|
5. Fields
|
top
|
|
|
Report fields represent the only way to map data from the data source into the report generating routines. When the data source of the report is a ResultSet , all fields must map to corresponding columns in the ResultSet object. That is, they must have the same name as the columns they map and a compatible type.
|
|
|
For example: |
|
|
If we want to generate a report using data retrieved from the table Employees, which has the following structure: |
|
|
Column Name Datatype Length
--------------------------------------
EmployeeID int 4
LastName varchar 20
FirstName varchar 10
HireDate datetime 8
|
|
we can define the following fields in our report design: |
|
|
<field name="EmployeeID" class="java.lang.Integer"/>
<field name="LastName" class="java.lang.String"/>
<field name="FirstName" class="java.lang.String"/>
<field name="HireDate" class="java.util.Date"/>
|
|
If we declare a field that does not have a corresponding column in the ResultSet , an exception will be thrown at runtime. Columns present in the ResultSet object that do not have corresponding fields in the report design do not affect the report filling operations, but they also wont be accessible.
|
|
6. Expressions
|
top
|
|
|
Expressions are a powerful feature of ^JasperReports. They can be used for declaring report variables that perform various calculations, for data grouping on the report, to specify report text fields content or to further customize the appearance of objects on the report.
|
|
|
Basically, all report expressions are Java expressions that can reference report fields and report variables. |
|
In an XML report design there are several elements that define expressions: <variableExpression>, <initialValueExpression>, <groupExpression>, <printWhenExpression>, <imageExpression> and <textFieldExpression> .
|
|
|
In order to use a report field reference in an expression, the name of the field must be put between $F{ and } character sequences.
|
|
|
For example, if we want to display in a text field, on the report, the concatenated values of two fields, we can define an expression like this one: |
|
|
<textFieldExpression>
$F{FirstName} + " " + $F{LastName}
</textFieldExpression>
|
|
The expression can be even more complex: |
|
|
<textFieldExpression>
$F{FirstName} + " " + $F{LastName} + " was hired on " +
(new SimpleDateFormat("MM/dd/yyyy")).format($F{HireDate}) + "."
</textFieldExpression>
|
|
To reference a variable in an expression, we must put the name of the variable between $V{ and } like in the example below:
|
|
|
<textFieldExpression>
"Total quantity : " + $V{QuantitySum} + " kg."
</textFieldExpression>
|
|
There is an equivalent syntax for using parameters in expressions. The name of the parameter should be put between $P{ and } like in the following example: |
|
|
<textFieldExpression>
"Max Order ID is : " + $P{MaxOrderID}
</textFieldExpression>
|
7. Variables
|
top
|
|
|
A Report variable is a special objects build on top of an expression. Variables can be used to simplify the report design by declaring only once an expression that is heavily used throughout the report design or to perform various calculations on the corresponding expressions. |
|
|
In its expression, a variable can reference other report variables, but only if those referenced variables were previously defined in the report design. So the order in which the variables are declared in a report design is important. |
|
|
As mentioned, variables can perform built-in types of calculations on their corresponding expression values like : count, sum, average, lowest, highest, variance, etc. |
|
|
A variable that performs the sum of the Quantity field should be declared like this:
|
|
|
<variable name="QuantitySum"
class="java.lang.Double" calculation="Sum">
<variableExpression>$F{Quantity}</variableExpression>
</variable>
|
|
For variables that perform calculation we can specify the level at which they are reinitialized. The default level is Report and it means that the variable is initialized only once at the beginning of the report and that it performs the specified calculation until the end of the report is reached. But we can choose a lower level of reset for our variables in order to perform calculation at page, column or group level.
|
|
|
For example, if we want to calculate the total quantity on each page, we should declare our variable like this: |
|
|
<variable name="QuantitySum" class="java.lang.Double"
resetType="Page" calculation="Sum">
<variableExpression>$F{Quantity}</variableExpression>
<initialValueExpression>new Double(0) </initialValueExpression>
</variable>
|
|
Our variable will be initialized with zero at the beginning of each new page. |
|
|
There are also the following built-in system variables, ready to use in expressions: |
|
PAGE_NUMBER
|
|
COLUMN_NUMBER
|
|
REPORT_COUNT
|
|
PAGE_COUNT
|
|
COLUMN_COUNT
|
|
GroupName_COUNT
|
|
Documentation pending... |
|
8. Report Sections
|
top
|
|
|
When building a report design we need to define the content and the layout of its sections. The entire structure of the report design is based on the following sections: <background>, <title>, <pageHeader>, <columnHeader>, <groupHeader>, <detail>, <groupFooter>, <columnFoter>, <pageFooter>, <lastPageFooter>, <summary> .
|
|
|
Sections are portions of the report that have a specified height and width and can contain report objects like lines, rectangles, images or text fields. |
|
When declaring the content and layout of a report section in an XML report design we use the generic element <band> .
|
|
|
This is how a page header declaration should look. It contains only a line object and a static text: |
|
|
<pageHeader>
<band height="30">
<rectangle>
<reportElement x="0" y="0" width="555" height="25"/>
<graphicElement/>
</rectangle>
<staticText>
<reportElement x="0" y="0" width="555" height="25"/>
<textElement textAlignment="Center">
<font fontName="Helvetica" size="18"/>
</textElement>
<text>Northwind Order List</text>
</staticText>
</band>
</pageHeader>
|
9. Groups
|
top
|
|
|
Groups represent a flexible way to organize data on a report. When filling a report, the ^JasperReports engine test all the defined group expressions to see whether a group rupture has occurred and if so it introduces the corresponding <groupFooter> and <groupHeader> sections on the report.
|
|
|
We can have as many groups as we want on a report. The order of groups declared in a report design is important because groups contain each other. One group contains the following group and so on. And when a larger group encounters a rupture, all subsequent groups are reinitialized. |
|
|
When declaring a report group, along with its corresponding data grouping expression, we have to declare the two sections: the group's header section and the group's footer section. |
|
|
See the sample report for an example on how to define groups. |
|
10. Fonts and Unicode Support
|
top
|
|
|
Now you can create your reports in any language! |
|
|
New attributes in the <font> element where introduced to allow the mapping between the Java fonts and the PDF fonts.
|
|
|
PDF uses special font settings and there was no way to make use of them in the previous version of ^JasperReports.
|
|
|
With the introduction of those new attributes, the users can specify what PDF specific font should be used to display different character sets (pdfFontName attribute), what is the type of the encoding (pdfEncoding attribute) and whether the font should be embedded in the PDF document or not (isPdfEmbedded ).
|
|
|
To simplify the use of the font settings, a new element was introduced: <reportFont> .
|
|
Report fonts are report level font definitions that ca be used as default or base font settings in other font definitions throughout the entire report. |
|
|
Since the support for international characters is somehow tied to the iText library, you ca find more details about how to create PDF documents in different languages and different character sets in the iText documentation.
|
|
11. Scriptlets
|
top
|
|
|
All the data displayed on a report comes from the report parameters and from the report fields. This data can be processed using the report variables and their expressions. |
|
|
There are specific moments in time when variable processing occurs. Some variables are initialized according to their reset type when the report starts, or when a page or column break is encountered, or when a group changes. Furthermore, variables are evaluated every time new data is fetched from the data source (for every row). |
|
|
But only simple variable expressions cannot always implement complex functionality. This is where scriptlets intervene. |
|
|
Scriptlets are sequences of Java code that are executed every time a report event occurs. Through scriptlets, users now have the possibility to affect the values stored by the report variables. |
|
|
Since scriptlets work mainly with report variables, is important to have full control over the exact moment the scriptlet is executed. ^JasperReports allows the execution of custom Java code BEFORE or AFTER it initializes the report variables according to their reset type: Report, Page, Column or Group .
|
|
|
In order to make use of this functionality, users only have to create a scriptlet class by extending net.sf.jasperreports.engine.JRAbstractScriptlet class or net.sf.jasperreports.engine.JRDefaultScriptlet class. The name of this custom scriptlet class has to be specified in the scriptletClass attribute of the <jasperReport> element.
|
|
|
When creating a ^JasperReports scriptlet class, there are several methods that developers should implement or override, like: beforeReportInit(), afterReportInit(), beforePageInit(), afterPageInit(), beforeGroupInit(), afterGroupInit() , etc. Those methods will be called by the report engine at the appropriate time, when filling the report.
|
|
|
There is a default report parameter called REPORT_SCRIPTLET which represent a reference to the scriptlet object instantiated by the report engine when filling the report. It can be used in expressions throughout the report, to call custom methods on the scriptlet object, making the whole mechanism even more flexible.
|
|
|
And that is all! |
|
|
See the scriptlet sample for more details. |
|
12. Subreports
|
top
|
|
|
Subreports are an import feature for a report-generating tool. They allow the creation of more complex reports and simplify the design work. |
|
|
The subreports are very useful when creating master-detail type of reports. |
|
|
Documentation pending... |
|
13. I18n support
|
top
|
|
|
JasperReports allows associating a java.util.ResourceBundle with the report design, either at runtime, by using the new resourceBundle attribute or at runtime, by providing a value for the REPORT_RESOURCE_BUNDLE build-in parameter.
|
|
|
If the report needs to be generated in a locale that is different from the current locale, then the build-in REPORT_LOCALE parameter should be used to specify the runtime locale when filling the report.
|
|
|
In order to ease the internationalization of the reports there is a special syntax available inside report expressions that allows referencing String resources placed inside a java.util.ResourceBundle object associated with the report. The $R{...} syntax is for wrapping resource bundle keys in order to retrieve the value for that key.
|
|
|
For formatting messages in different languages, based on the report locale, there is a built-in method inside the net.sf.jasperreports.engine.fill.JRCalculator associated with the report that offers functionality similar to the java.text.MessageFormat class. This method is called msg() and has 3 convenience signatures that allow using up to 3 message parameters in the messages. There is also the build-in str() method which is the equivalent of the $R{厎 syntax inside the report expressions, giving access to the resource bundle content based on the report locale.
|
|
|
In the generated output, the library now keeps information about the text run direction so that documents generated in languages that have right-to-left writing (like Arabic and Hebrew) could be rendered properly. |
|
|
Check the "i18n" and "unicode" samples for details. |