Вы находитесь на странице: 1из 36

www.ste.

es
Jasper Report – Tutorial (English Version)
-1-
1

INDEX

1 GENERAL JasperReport INTRODUCTION........................................................................3


1.1 What is JasperReport.....................................................................................................3
1.2 Report Design................................................................................................................3
1.3 Parameters....................................................................................................................4
1.4 Data Source...................................................................................................................4
1.5 Fields.............................................................................................................................5
1.6 Expressions...................................................................................................................5
1.7 Variables........................................................................................................................6
1.8 Report Sections..............................................................................................................7
1.9 Groups...........................................................................................................................8
1.10 Fonts and Unicode Support..........................................................................................8
1.11 Scriptlets......................................................................................................................8
1.12 Subreports...................................................................................................................9
2 QUICK HOW TO REFERENCE.........................................................................................10
2.1 Main Classes................................................................................................................10
2.2 Compiling a Report Desing..........................................................................................10
2.2.1 jasper.reports.compiler.class................................................................................10
2.2.2 jasper.reports.compilation.xml.validation..............................................................11
2.2.3 jasper.reports.compile.class.path.........................................................................11
2.2.4 jasper.reports.compile.temp.................................................................................11
2.2.5 jasper.reports.compile.keep.java.file....................................................................11
2.3 Ant task for compiling report design.............................................................................12
2.4 Viewing a report design................................................................................................13
2.5 Filling a report..............................................................................................................13
2.6 Viewing a report...........................................................................................................13
2.7 Printing a report............................................................................................................15
2.8 Exporting to PDF, HTML, XSL, CSV, or XML format....................................................16
3 TIPS AND TRICKS.............................................................................................................18
3.1 Dymamic Element Formatting......................................................................................18
3.2 “Page i of n”.................................................................................................................18
3.3 Bands larger than one page.........................................................................................19
3.4 Making HTML, XSL, or CSV friendly reports...............................................................20
3.4.1 Minimizing the number of rows and columns in the grid oriented formats.............21
3.4.2 Avoiding overlapping report elements...................................................................22
3.4.3 Give up using page headers and page footers......................................................22
3.5 Excel color palette........................................................................................................22
3.6 Returning values from subreports................................................................................24

47917159.doc
Jasper Report – Tutorial (English Version)
-2-
2

3.7 Fake title and summary sections..................................................................................25


4 FAQs..................................................................................................................................26
4.1 System property org.xml.sax.driver not specified.........................................................26
4.2 Swing application exits when closing the JasperViewer frame.....................................26
4.3 Can not use the && logical operator in report expressions ..........................................27
4.4 Java.io.InvalidClassException:…serialVersionUID=xxx...............................................27
4.5 Images are not appearing in XLS format......................................................................27
5 SCREENSHOTS................................................................................................................28
5.1 Report Design..............................................................................................................28
5.2 Header Sections...........................................................................................................29
5.3 Footer Sections............................................................................................................30
5.4 Columns ......................................................................................................................31
5.5 Groups ........................................................................................................................32
5.6 Calculations.................................................................................................................33
5.7 Text Format..................................................................................................................34
5.8 Images.........................................................................................................................35

47917159.doc
Jasper Report – Tutorial (English Version)
-3-
3

1 GENERAL JasperReport INTRODUCTION


1.1 What is JasperReport

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 dori.jasper.engine.JasperManager class.
Through compilation, the report design is loaded into a report design object that is then serialized and
stored on disk (dori.jasper.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
dori.jasper.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
(dori.jasper.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.

1.2 Report Design

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>

47917159.doc
Jasper Report – Tutorial (English Version)
-4-
4

1.3 Parameters

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

1.4 Data Source

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.

47917159.doc
Jasper Report – Tutorial (English Version)
-5-
5

1.5 Fields

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.

1.6 Expressions

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>

47917159.doc
Jasper Report – Tutorial (English Version)
-6-
6

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>

1.7 Variables
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>

47917159.doc
Jasper Report – Tutorial (English Version)
-7-
7

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

1.8 Report Sections

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: <title>, <pageHeader>,
<columnHeader>, <groupHeader>, <detail>, <groupFooter>, <columnFoter>,
<pageFooter>, <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>

47917159.doc
Jasper Report – Tutorial (English Version)
-8-
8

1.9 Groups

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.

1.10 Fonts and Unicode Support

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 can 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 can
find more details about how to create PDF documents in different languages and different
character sets in the iText documentation.

1.11 Scriptlets

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

47917159.doc
Jasper Report – Tutorial (English Version)
-9-
9

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
dori.jasper.engine.JRAbstractScriptlet class or
dori.jasper.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.
See the scriptlet sample for more details.

1.12 Subreports

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.

47917159.doc
Jasper Report – Tutorial (English Version)
- 10 -
10

2 QUICK HOW TO REFERENCE

2.1 Main Classes

The Main classes to use when working with JasperReports are the following:

dori.jasper.engine.JasperCompileManager This classes represent the JasperReports


engine. They have various static methods that
dori.jasper.engine.JasperFillManager simplify the access to the API functionality and
dori.jasper.engine.JasperPrintManager can be used to compile an XML report design,
to fill a report, to print it, or to export to PDF,
dori.jasper.engine.JasperExportManager HTML and XML files.

dori.jasper.view.JasperViewer This can be used to view the generated


reports.

dori.jasper.view.JasperDesignViewer This can be used to view the report design.

2.2 Compiling a Report Desing

A report design is represented by an XML file that has the structure defined in the jasperreport.dtd file.
In order to generate reports according to such a report design, it needs to be compiled.
Report design compilation can be done using the compileReportXXX() methods exposed by
dori.jasper.engine.JasperCompileManager class.
When compiling a report design, the engine first performs a validation to ensure that the template is
consistent and then transforms all the report expressions, so that they are stored in a ready-to-evaluate
form, inside the resulting .jasper file.
This transformation implies either the on-the-fly compilation of a Java class file that will be associated
with the report template, or the generation of a BeanShell script to use when evaluating report
expressions during the report filling process.
To make report design compilation process as flexible as possible, a special interface called
dori.jasper.engine.design.JRCompiler was introduced.
As seen above, there are two main types of classes implementing this interface and thus performing
report compilation:
1. Java class generating report compilers. These report compilers generate and compile a Java
class containing the report expressions evaluating methods;
2. The BeanShell report compiler that generates a script for runtime report expressions
evaluation, without requiring bytecode Java compilation.
System properties to customize report compilation:

2.2.1 jasper.reports.compiler.class
By default, when compiling report designs, the library tries to identify the Java generating class type of
a report compiler that is compatible with the Java compiler available on the running platform in this
order: JDK 1.3 compatible compiler, JDK 1.2 compatible compiler and the command-line javac.exe
compiler.

47917159.doc
Jasper Report – Tutorial (English Version)
- 11 -
11

To override this default behavior, you can specify the name of a class that implements the
dori.jasper.engine.design.JRCompiler interface to be used to compile the report design by
supplying it to the jasper.reports.compiler.class system property.
The library comes with 5 built-in implementations of this interface:

dori.jasper.engine.design.JRBshCompiler
dori.jasper.engine.design.JRJavacCompiler
dori.jasper.engine.design.JRJdk12Compiler
dori.jasper.engine.design.JRJdk13Compiler
dori.jasper.engine.design.JRJikesCompiler
Note that the classes implementing the JRCompiler interface can also be used directly in the
programs without the need to call them through the JasperCompilerManager class.

2.2.2 jasper.reports.compilation.xml.validation
The XML validation, which is ON by default, can be turned off by setting the system property called
jasper.reports.compilation.xml.validation to false.
When working with a Java class generating type of a report compiler, further customizations can be
made using the following system properties, which only apply to them:

2.2.3 jasper.reports.compile.class.path
By default, JasperReports uses the current JVM classpath to compile the report class
(java.class.path system property). To customize this report compilation process, JasperReports
lets you override the default behavior by supplying a value to the
jasper.reports.compile.class.path system property, which will be used as classpath for the
report class compilation.

2.2.4 jasper.reports.compile.temp
The temporary location for the files generated on-the-fly is by default the current working directory. It
can be changed by supplying a value to the jasper.reports.compile.temp system property.

2.2.5 jasper.reports.compile.keep.java.file
Sometimes, for debugging purposes, it is useful to have the generated .java file in order to fix the
compilation problems related to report expressions. By default, the engine deletes this file after report
compilation, along with its corresponding .class file. To keep it however, you can set the system
property jasper.reports.compile.keep.java.file to true.

47917159.doc
Jasper Report – Tutorial (English Version)
- 12 -
12

2.3 Ant task for compiling report design

Since the report design compilation process is more like a design-time job than a runtime
one, an Ant task was provided with the library in order to simplify development.
This Ant task is implemented by the dori.jasper.ant.JRAntCompileTask and is very
similar to the <javac> Ant built-in task, as far as syntax and behavior are concerned.
The report design compilation task can be declared like this, in a project's build.xml file:

<taskdef name="jrc" classname="dori.jasper.ant.JRAntCompileTask">


<classpath>
<fileset dir="./lib">
<include name="**/*.jar"/>
</fileset>
</classpath>
</taskdef>

In the example above, the lib should contain the jasperreports.jar file along with its
required libraries.
This user-defined Ant task can be then used to compile multiple XML report design files in a
single operation, by specifying the root directory that contains those files or by selecting them
using file patterns.
Attributes of the report design compilation task:

Location of the XML report design files to compile. Required unless nested
srcdir <src> elements are present.

Location to store the compiled report design files (the same as the source
destdir directory by default).

Name of the class that implements the


compiler dori.jasper.engine.design.JRCompiler interface (optional).

Flag to indicate if the XML validation should be performed on the source


xmlvalidation report design files (true by default).

Location to store the temporary generated files (the current working


tempdir directory by default).

Flag to indicate if the temporary Java files generated on-the-fly should be


keepjava kept and not deleted automatically (false by default).

The report design compilation task supports nested <src> and <classpath> elements, just
like the Ant <javac> built-in task.
To see this in action, check the "antcompile" sample provided with the project source files.

47917159.doc
Jasper Report – Tutorial (English Version)
- 13 -
13

2.4 Viewing a report design

Reports designs can be viewed using the dori.jasper.view.JasperDesignViewer application.


In its main() method, it receives the name of the file which contains the report design to view.
This can be the XML file itself, or the compiled report design.

2.5 Filling a report

A compiled report design can be used to generate reports by calling the fillReportXXX() methods
of the dori.jasper.engine.JasperFillManager class.

public JasperPrint rellena(InterfaceSesionUsuario isu,


String clavePlantilla,
String nombrePlantilla,
Map campos,
Map param)
throws RemoteException {
try {
JasperReport JR = obtenPlantilla(clavePlantilla, nombrePlantilla);

ListMapDataSource lmds = null;


if (campos == null) {
lmds = new ListMapDataSource(isu);
} else {
lmds = new ListMapDataSource((HashMap) campos, false, isu);
}

return(JasperFillManager.fillReport(JR, (HashMap) param, lmds));

} catch (Exception e) {
Debug.error(this, e);

return(null);
}
}

2.6 Viewing a report

Generated reports can be viewed using the dori.jasper.view.JasperViewer application. In its


main() method, it receives the name of the file which contains the report to view.

47917159.doc
Jasper Report – Tutorial (English Version)
- 14 -
14

import dori.jasper.engine.JasperPrint;
import dori.jasper.engine.JRException;
import dori.jasper.view.JRViewer;

import java.awt.BorderLayout;
import javax.swing.JOptionPane;

/**
* Permite la visualización en un panel de un objeto JasperPrint
*/
public class VerInforme
extends javax.swing.JFrame {

/**
* Constructor.
* @param jasperPrint
* €xception JRException
*/
public VerInforme(JasperPrint jasperPrint)
throws JRException {
getRevision();

initComponents();

JRViewer viewer = new JRViewer(jasperPrint);


this.pnlMain.add(viewer, BorderLayout.CENTER);
}

/** This method is called from within the constructor to


* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
private void initComponents() {
pnlMain = new javax.swing.JPanel();

setTitle("Visualizador de informes.");
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
pnlMain.setLayout(new java.awt.BorderLayout());

47917159.doc
Jasper Report – Tutorial (English Version)
- 15 -
15

getContentPane().add(pnlMain, java.awt.BorderLayout.CENTER);

pack();
java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
setSize(new java.awt.Dimension(800, 600)); //XXX
setLocation(50,50); //XXX
}

/**
* Información de la revisión del fichero fuente
* @return Una cadena con el <i>keyword</i> Id:
*/
public static String getRevision() {
return "$Id: VerInforme.java,v 1.5 2004/06/21 10:27:34 sergio_alonso Exp $";
}

// Variables declaration - do not modify


private javax.swing.JPanel pnlMain;
// End of variables declaration
}

2.7 Printing a report

Generated reports can be printed using the printReport(), printPage() or printPages()


static methods exposed by the doriJasper.engine.JasperPrintManager class.

private static JRPrintServiceExporter trabajoDeImpresion(JasperPrint jp,


Attribute orientacion,
PrintService servicioImpresora,
boolean dlgImpresora) {

PrintRequestAttributeSet printRequestAttributeSet = new HashPrintRequestAttributeSet();


printRequestAttributeSet.add(MediaSizeName.ISO_A4);
printRequestAttributeSet.add(orientacion);
printRequestAttributeSet.add(new JobName("Informe SICAS.", null)); //XXX

PrintServiceAttributeSet printServiceAttributeSet = new HashPrintServiceAttributeSet();

47917159.doc
Jasper Report – Tutorial (English Version)
- 16 -
16

JRPrintServiceExporter exporter = new JRPrintServiceExporter();

exporter.setParameter(
JRPrintServiceExporterParameter.PRINT_REQUEST_ATTRIBUTE_SET,
printRequestAttributeSet);
exporter.setParameter(
JRPrintServiceExporterParameter.PRINT_SERVICE_ATTRIBUTE_SET,
printServiceAttributeSet);
exporter.setParameter(
JRPrintServiceExporterParameter.DISPLAY_PAGE_DIALOG,
Boolean.FALSE);
exporter.setParameter(
JRPrintServiceExporterParameter.DISPLAY_PRINT_DIALOG,
new Boolean(dlgImpresora));

if (servicioImpresora != null) {
exporter.setImpresora(servicioImpresora);
}

exporter.setParameter(JRExporterParameter.JASPER_PRINT, jp);

return(exporter);
}
.......

exporter.exportReport();

2.8 Exporting to PDF, HTML, XSL, CSV, or XML format

After having filled a report, we can also export it in PDF, HTML or XML format using the
exportReportXXX() methods of the dori.jasper.engine.JasperExportManager class.

protected static void exportaPDF(JasperPrint jp, OutputStream os)


throws JRException, IOException {

miDebugMensaje("local.informes.obj.Exportador : exportando a PDF...");

JRPdfExporter exporter = new JRPdfExporter();

exporter.setParameter(JRExporterParameter.JASPER_PRINT, jp);
exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, os);
exporter.setParameter(JRExporterParameter.CHARACTER_ENCODING, "ISO-8859-1");

exporter.exportReport();

47917159.doc
Jasper Report – Tutorial (English Version)
- 17 -
17

os.flush();
}

47917159.doc
Jasper Report – Tutorial (English Version)
- 18 -
18

3 TIPS AND TRICKS


3.1 Dymamic Element Formatting

Some reports may require that the same kind of data be displayed differently, depending on its
significance.
For example, someone would want to highlight on an orders list, all the orders that have a total value
greater than 100$, like in the following table:

OrderIDCity Date Value


Buenos
10251 07/15/2001 98.64
Aires
10263 Paris 09/19/2001 106.75
11320 Caracas 10/19/2001 88.10

How to do that, since the format of a text field can not change dynamically? The solution is within
reach. We can put in the same place two text fields, one on top of the other, both displaying the same
value, but having different formats: one black and the other bold and red.
In addition, we should make use of the <printWhenExpression> element that is available for every
report element and switch between those two text fields.
The red text field should be displayed only when its value is greater than 100 and the black one in the
rest of the cases.

3.2 “Page i of n”
Quite often we might need to put at the beginning of our reports, values that are calculated only after
the entire document is generated.
The most common situation of this kind would be the display of the total number of pages on the page
footer or header of each page.
How to do that, since the report is filled page by page and the total number of pages is known only
when we reach the end of our document? Well, that's easy.
JasperReports allows us to specify the exact moment at which an expression for a text field is
evaluated. To display the total number of pages, we only need to put on our page footer (or any other
report section) a text field that will use the PAGE_NUMBER report variable in its expression. For this
field we will specify that the evaluation time should be "Report", because only when the end of the
report is reached, this system variable will contain the total number of pages on our report.
The text field declaration in the XML report design file for the total number of pages in a document will
look like this:
<textField evaluationTime="Report">
<reportElement x="280" y="10" width="275" height="20"/>
<textElement textAlignment="Left">
<font fontName="Helvetica" size="14"/>
</textElement>
<textFieldExpression class="java.lang.Integer">
$V{PAGE_NUMBER}
</textFieldExpression>
</textField>

47917159.doc
Jasper Report – Tutorial (English Version)
- 19 -
19

If we remove the attribute evaluationTime from the <textField> element, the text field
expression will be evaluated when the section is filled (default behavior) so we will obtain the current
page number on the document.
To display the current page number and the total number of pages simultaneously, like in "Page 3 of
5" phrases, we need two text fields with the same expression (PAGE_NUMBER variable value), but
with different evaluationTime attributes:

evaluationTime="Now" for the current page number (default)


evaluationTime="Report" for the total number of pages
There are 5 possible values for the attribute evaluationTime: Now, Report, Page, Column and
Group. For more information about this attribute, see the <textField> element in the Quick Reference
at the JasperReport site
An example is also supplied in the sample application.

3.3 Bands larger than one page

Sometimes the content of a particular report band is larger than one page and we have to find a way to
force page breaks at certain points, inside the band structure.
Of course, this issue does not concern all the report bands. I imagine that we shall never have page or
column headers or footers larger than one page ... but who knows?
If the title band or the summary band are larger than one page, you should consider placing their
content into a subreport element and applying the following trick to this particular subreport. This might
even work for the page or column headers, but never for the page or column footers, since the engine
judge them to be of fixed height and do not perform stretch for the elements placed on those sections.
We have eliminated from our discussion some of the report sections and all that remains are the group
headers and footers and the detail band.
The group headers and footers we'll be treated together, so let's start with the detail band.
If we have a detail band that contains so many elements on it that we have to split it on multiple pages,
we have to find a way to introduce page breaks. But there is no such "page break" element available in
JasperReports, so what to do?
The only way to deliberately introduce page breaks in JasperReports is by using the
isStartNewPage attribute of the <group> element. We cannot use this to solve our problem.
Normally, the reporting engine starts a new page or column every time it sees that the band it has to fill
does not fit on the remaining space on the current page. This is why we have that validation performed
when the report design is compiled, so that the bands do not have a height greater than the page
height. Without such a constraint, the reporting engine would get confused and behave uncontrollably.
So, in order to solve our problem, we have to find a way to somehow pass this band height validation
check.
Well, we could do that by splitting the detail band content on multiple bands, each one of them smaller
that one page, so that the report design remains valid.
And what other report bands could we use? Group headers and footers of course.
We could place some of our detail elements on a special group header, some of them will probably
remain on the detail section, and the rest could go on the group footer. The only condition to this is that
the group header and footer should always accompany our detail section, so that all three behave like
a normal large detail band.

47917159.doc
Jasper Report – Tutorial (English Version)
- 20 -
20

That's the easiest part, because we can introduce a dummy group that will break with every row in the
data source. Such a group would have an expression like the following:

<groupExpression>$V{REPORT_COUNT}</groupExpression>

If one dummy group is not sufficient for you and you have a giant detail band, you could introduce as
many dummy groups as you want to, all of them with the same dummy expression. Problem solved.
Hey, we forgot about that other situation when one of the group headers or footers is larger than one
page.
No problem. The solution is the same. You just have to introduce a new group, with the same
expression as the one which poses the problem, and to split that group header or footer content
between the two. Those two groups will break together and behave like one, so you can distribute the
elements on their headers and footers as you want to.
The band height validation check could be passed this way.

3.4 Making HTML, XSL, or CSV friendly reports

When generating reports, the JasperReports engine uses the absolute position of each report element
to layout the content of each page. Absolute positioning the report elements allows full control over the
content of the output documents.
The PDF format supports absolute positioning of the text and graphic elements on a document page
and this is why it is widely used on various platforms. You can be sure that once created, a PDF
document will look the same no matter what is the viewer's platform.
The JasperReports proprietary document format (dori.jasper.engine.JasperPrint objects) is
also based on absolute positioning of elements on the page. The position and size of each element are
defined by the x, y, width and height properties.
However, other document formats such as HTML or XLS, do not support absolute positioning of the
text and graphic elements. The content of such documents is arranged in a grid or table structure.
Of course, some may argue that absolute positioning of elements in HTML is possible thanks to CSS,
but you can be sure that the CSS standard functionality is far from being implemented in all browsers
or that the same HTML document won't look the same everywhere.
This is why the JasperReports built-in exporters that produce HTML, XLS or CSV documents use a
special algorithm in order to arrange the elements present on a certain document page in some sort of
a grid.
When the report designs are very complex or agglomerated, passing from absolute positioning to grid
or table layout produces very complex tables with many unused rows and columns, to make it for the
empty space between elements or their special alignment.
There are a few, very simple guidelines that should be followed by those who want to obtain optimized
HTML, XLS or CSV documents when using the built-in JasperReports grid exporters.

47917159.doc
Jasper Report – Tutorial (English Version)
- 21 -
21

3.4.1 Minimizing the number of rows and columns in the grid


oriented formats

Minimizing the number of “cuts”. To do that, you have to make sure you align your report elements
as often as you can, both on the horizontal and the vertical axis and that you eliminate the space
between elements.

Inefficient layout

Grid friendly layout

47917159.doc
Jasper Report – Tutorial (English Version)
- 22 -
22

3.4.2 Avoiding overlapping report elements.


Make sure report element will not overlap when the report will be generated. This is because if you
have two elements that share some region, it will be impossible for them to share the same cell in the
resulting grid structure. You might obtain some unexpected results if elements overlap.

3.4.3 Give up using page headers and page footers.


Especially when you want to obtain documents in which the page breaks are not relevant (CSV for
example), make sure that you suppress the page header and page footer sections in your report
design. You could also minimize the top and bottom margins for your report, so that when exported to
HTML, XLS or CSV, your documents will be made of a single chunk, without page separators.

3.5 Excel color palette

JasperReports allows you to use any color for your report elements. However, when exporting to XLS
format, you have to be aware that this type of files supports only a limited set of colors.
If the colors you use in your report designs do not match any of these acceptable colors, the XLS
exporter will use a special algorithm to determine which is the nearest one by comparing the RGB
levels. But the results might not be always what you expect.
Here is the Excel Color Palette containing all the 40 colors that XLS may use. Make sure you use one
of these colors if you want to eventually export your reports to XLS format.

47917159.doc
Jasper Report – Tutorial (English Version)
- 23 -
23

#FFFF00 YELLOW #003300 DARK_GREEN


#969696 GREY_40_PERCENT #808000 DARK_YELLOW
#99CC00 LIME #FF00FF PINK
#CC99FF LAVENDER #FF99CC ROSE
#FFFF99 LIGHT_YELLOW #3366FF LIGHT_BLUE
#008000 GREEN #FF6600 ORANGE
#C0C0C0 GREY_25_PERCENT #993300 BROWN
#339966 SEA_GREEN #993366 PLUM
#FF9900 LIGHT_ORANGE #800080 VIOLET
#FF0000 RED #333399 INDIGO
#003366 DARK_TEAL #000000 BLACK
#FFFFFF WHITE #00CCFF SKY_BLUE
#99CCFF PALE_BLUE #333333 GREY_80_PERCENT
#00FFFF TURQUOISE #CCFFFF LIGHT_TURQUOISE
#008080 TEAL #CCFFCC LIGHT_GREEN
#000080 DARK_BLUE #666699 BLUE_GREY
#FFCC00 GOLD #0000FF BLUE
#33CCCC AQUA #00FF00 BRIGHT_GREEN
#333300 OLIVE_GREEN #800000 DARK_RED
#808080 GREY_50_PERCENT #FFCC99 TAN

47917159.doc
Jasper Report – Tutorial (English Version)
- 24 -
24

3.6 Returning values from subreports

You can return values from subreports using special parameters as containers. Here’s an example:
Problem: I want to pass to my master report the total number of records that the subreport had.
Solution: In the master report, I define a special container parameter that will hold the values that I
want to return from the subreport.

<parameter name="ReturnedValuesMap" class="java.util.Map">


<defaultValueExpression>
new java.util.HashMap()
</defaultValueExpression>
</parameter>

I pass this container parameter to my subreport, so that it can store the returned values in it.

<subreportParameter name="ReturnedValuesMap">
<subreportParameterExpression>
$P{ReturnedValuesMap}
</subreportParameterExpression>
</subreportParameter>

In the subreport template, I declare the container parameter. Even they both have the same name, the
master report parameter and the subreport parameter are in fact totally different entities.
<parameter name="ReturnedValuesMap" class="java.util.Map"/>
In the subreport, I use the dummy <printWhenExpression> of an invisible line element placed on
the summary section to put in the container parameter the value that I want to return to my master
report:

<line>
<reportElement x="0" y="0" width="0" height="0">
<printWhenExpression>
($P{ReturnedValuesMap}.put(
"MY_RETURNED_VALUE", $V{REPORT_COUNT}) == null
)?Boolean.FALSE:Boolean.FALSE
</printWhenExpression>
</reportElement>
</line>

Remember that the returned value can be placed in the container parameter also using scriptlets. I
chose this trick for simplicity reasons.
Back in the master report, if I want to display the returned value, I just extract it from the container
parameter:
<textField evaluationTime="Group" evaluationGroup="DetailGroup">
<reportElement x="335" y="50" width="175" height="15"/>

47917159.doc
Jasper Report – Tutorial (English Version)
- 25 -
25

<textFieldExpression class="java.lang.Integer">
$P{ReturnedValuesMap}.get("MY_RETURNED_VALUE")
</textFieldExpression>
</textField>

You might ask why is it that the text field uses evaluationTime="Group".
This is because one of the problems with the returned values from subreports is that these values are
returned after the content of the band elements has already been evaluated.
If you want to display subreport returned values in the same band as the subreport itself, you'll end up
seeing that they were returned too late for that.
So, in order to be able to display the returned values in the same master report band that contains the
subreport itself, I had to delay the text field evaluation. This was done by introducing a dummy group in
the master report and let my text field be evaluated when this dummy group ends.
This dummy group breaks with every record in the data source and has no header and footer of its
own.

<group name="DetailGroup">
<groupExpression>$V{REPORT_COUNT}</groupExpression>
</group>

This dummy group served my purpose because my subreport and the text field were placed in the
detail section of the master report and it had to break with every detail. If the subreport is placed in a
different report section, the dummy group expression should be adapted to fit the given situation.
The use of a dummy group is not necessary if you do not need to display the returned values in the
same report section that contains the subreport itself.

3.7 Fake title and summary sections

The title and the summary are special report sections that are not accompanied by the page header
and footer on the pages that they occupy. This is more obvious when the title or the summary
overflows.
Sometimes is useful to have a title section that starts after the page header on the first page or a
summary section that gets accompanied by the page header and footer on all the pages that it
overflows to.
This can be achieved by introducing fake title and summary sections.
A fake title can be the group header section of a report group that breaks only once per report. Such a
dummy group would have an empty group expression. Its header will get printed only once at the
beginning of the report.
The fake summary can be introduced also by using the footer section of such a dummy group wit an
empty group expression.

47917159.doc
Jasper Report – Tutorial (English Version)
- 26 -
26

4 FAQs
4.1 System property org.xml.sax.driver not specified

JasperReports uses the SAX 2.0 API to parse the XML files. However, it is not tied to a particular SAX
2.0 implementation, like Xerces for examples, but instead you are able to decide at runtime what XML
parser you are using.
To instantiate the parser class, JasperReports uses the createXMLReader() method of the
org.xml.sax.helpers.XMLReaderFactory class.
In this case, it will be necessary at runtime to set the org.xml.sax.driver Java system property to
the full class name of the SAX driver, as specified in the SAX 2.0 documentation.
You can achieve this in two ways. We shall explain both using the Xerces XML parser, just like we do it
in the provided samples. If you use a different SAX 2.0 XML parser, you have to modify the name of
the parser class accordingly.
The first way you can set a system property is by using the -D switch in the command line when you
launch the Java Virtual Machine:

java -Dorg.xml.sax.driver=org.apache.xerces.parsers.SAXParser MySAXApp sample.xml

In all the provided samples we use the ANT build tool to perform different tasks. We supply this system
property to the JVM using the <sysproperty> element of the <java> built-in task:

<sysproperty
key="org.xml.sax.driver"
value="org.apache.xerces.parsers.SAXParser"/>

The second way to set a system property is by using the java.lang.System.setProperty(String


key, String value) method like this:

System.setProperty(
"org.xml.sax.driver",
"org.apache.xerces.parsers.SAXParser"
);

Check the jsp/compile.jsp and WEB-INF/classes/servlets/CompileServlet.java files in the


"webapp" sample provided, to see this in action.

4.2 Swing application exits when closing the JasperViewer frame

This happens if you directly use the dori.jasper.view.JasperViewer class in your Swing
application.
The viewer application implemented in this class should be considered more like a demo application
that shows how the dori.jasper.view.JRViewer component can be used in Swing applications to
display reports.
Your application unexpectedly terminates when you close the report viewer frame because the
JasperViewer class makes a call to the System.exit(0).
To get around this, use the constructor that allows you to set the "isExitOnClose" to false.

47917159.doc
Jasper Report – Tutorial (English Version)
- 27 -
27

But you are encouraged to create your own viewer that uses the more basic visual component
implemented by the dori.jasper.view.JRViewer class. Feel free to copy what code portion you
might want to keep from the supplied JasperViewer class.

4.3 Can not use the && logical operator in report expressions

If you want to create some complex report expressions in which you have to use the Java AND logical
operator, you might be surprised to see an error when compiling you report design. The error message
would say something like this:
"The entity name must immediately follow the '&' in the entity reference."
This is because the '&' character is a special XML character and the XML parser is confused when it
encounters such characters in the body of an XML element.
The solution is to use the XML special syntax that allows you to introduce XML special characters in
the body of an XML element. Put your expression content between the <![CDATA[ and ]]> character
sequences like in the following demo text field expression:
0)?
($F{MyStringField}):("MISSING")
]]>
</textFieldExpression>
]]>

4.4 Java.io.InvalidClassException:…serialVersionUID=xxx

When upgrading to a new version of the library, you need to recompile your XML report design and
regenerate the *.jasper files.

4.5 Images are not appearing in XLS format

The Jakarta POI library that we use when exporting the report to XLS format does not currently
supports images.

47917159.doc
Jasper Report – Tutorial (English Version)
- 28 -
28

5 SCREENSHOTS

5.1 Report Design

47917159.doc
Jasper Report – Tutorial (English Version)
- 29 -
29

5.2 Header Sections

47917159.doc
Jasper Report – Tutorial (English Version)
- 30 -
30

5.3 Footer Sections

47917159.doc
Jasper Report – Tutorial (English Version)
- 31 -
31

5.4 Columns

47917159.doc
Jasper Report – Tutorial (English Version)
- 32 -
32

5.5 Groups

47917159.doc
Jasper Report – Tutorial (English Version)
- 33 -
33

5.6 Calculations

47917159.doc
Jasper Report – Tutorial (English Version)
- 34 -
34

5.7 Text Format

47917159.doc
Jasper Report – Tutorial (English Version)
- 35 -
35

5.8 Images

47917159.doc

Оценить