JasperReports 英文收费文档(文本)

The JasperReports Ultimate Guide

Version 1.0

Author:

Teodor Danciu

Copyright . 2002 Teodor Danciu (teodord@hotmail.com). All rights reserved.

Table of contents

1 Introduction______________________________________________________4

2 API Overview_____________________________________________________5

3 Main Tasks and Processes _________________________________________10

3.1 XML Parsing _____________________________________________________ 10

3.2 Compiling Report Designs __________________________________________ 10

3.3 Report Design Preview _____________________________________________ 12

3.4 Filling Reports ____________________________________________________ 13

3.5 Viewing Reports___________________________________________________ 15

3.6 Printing Reports___________________________________________________ 16

3.7 Exporting Reports _________________________________________________ 17

3.8 Object Loading and Saving__________________________________________ 17

4 Report Designs___________________________________________________19

4.1 DTD Reference____________________________________________________ 19

4.2 XML Encoding____________________________________________________ 20

4.3 Report Properties__________________________________________________ 21

5 Report Data _____________________________________________________25

5.1 Expressions _______________________________________________________ 25

5.2 Parameters _______________________________________________________ 26

5.2.1 Built-in Report Parameters ______________________________________________ 28

5.3 Data Source_______________________________________________________ 29

5.4 Report Query _____________________________________________________ 31

5.5 Fields ____________________________________________________________ 32

5.6 Variables _________________________________________________________ 34

5.6.1 Calculations __________________________________________________________ 35

5.6.2 Built-in Report Variables________________________________________________37

6 Report Sections __________________________________________________38

6.1 Main Report Sections ______________________________________________ 39

6.2 Data Grouping ____________________________________________________ 40

7 Scriptlets________________________________________________________43

8 Report Elements _________________________________________________44

8.1 Text Elements_____________________________________________________ 48

8.1.1 Fonts and Unicode Support ______________________________________________ 49

8.1.2 Static Texts __________________________________________________________53

8.1.3 Text Fields ___________________________________________________________ 53

8.2 Graphic Elements__________________________________________________ 56

8.2.1 Lines _______________________________________________________________57

8.2.2 Rectangles ___________________________________________________________ 58

8.2.3 Images ______________________________________________________________58

8.2.4 Charts and Graphics____________________________________________________60

8.3 Hyperlinks _______________________________________________________ 60

8.4 Element Groups ___________________________________________________ 62

9 Subreports ______________________________________________________63

9.1 Subreport Parameters ______________________________________________ 65

9.2 Subreport Data Source _____________________________________________ 66

10 Advanced JasperReports _________________________________________67

10.1 XML Report Designs Loading and Writing ____________________________ 67

10.2 Implementing Data Sources _________________________________________ 67

10.3 Customizing Viewers _______________________________________________ 68

10.4 Exporting to New Output Formats____________________________________ 68

Introduction

The JasperReports library is a very powerful and flexible report-generating tool that has the ability to deliver rich content onto the screen, to the printer or into PDF, HTML or XML files. Hopefully, in the future, other output formats such as CSV, XLS, RTF and other will be supported.

The library is entirely written in Java and can be used in a variety of Java enabled applications, including J2EE or Web 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 according to the report design defined in an XML file. This data may come from various data sources including relational databases, collections or arrays of Java objects. Users can plug the reporting library to custom made data sources, by implementing a simple interface, as you will see later in this book.

In order to fill a report with data, the XML report design must be compiled first. Through compilation, a report design object is generated and then serialized in order to store it on disk or send it over the network. 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.

To fill a report design, the engine needs to receive the report data. This may come in various forms. Some of this data can be passed in as report parameters. But most of the data will be found in the report data source. The reporting engine can directly receive special data source objects from which to get the information to put on the report, or can deal itself with a supplied JDBC connection object, if that data is located in a relational database.

The result of the report filling operation is a new object that represents the ready to print document. This one is also serialized for storage on disk or network transfer. It can be viewed directly using the JasperReports built-in viewer or can be exported to other, more popular formats like PDF, HTML or XML.

API Overview

Most of the time, when using the JasperReports library, people will get to work only with a few classes and won't have to get to know the entire API, in order to benefit from all its features and functionality.

In this section we shall get a close look at the classes and interfaces which are significant when using the library and see how to make use of them in applications that need the reporting functionality that JasperReports offer.

- figure 1 -

Class dori.jasper.engine.design.JasperDesign

We begin with this class because instances of it represent the raw material, which the JasperReports library uses for report generating purposes. Such instances are obtained after the XML report design files are parsed by the library internal XML parsing procedures, for example, but can be build programmatically, by the application that uses JasperReports, if working with XML files is not an option. Among the supplied samples that come with the project source files, there is one called noxmldesign that you can check to see how to dynamically create a dori.jasper.engine.design.JasperDesign object without editing an XML report design file.

All instances of the dori.jasper.engine.design.JasperDesign class are subject to compilation before being used for filling and report generation. This is why they are considered the raw material for the library.

Class dori.jasper.engine.JasperReport

Instances of this class represent compiled report design objects. These can be obtained only as a result of the JasperReports report compilation process and are ready to use for filling with data and report generation.

Through compilation, along with various consistency checks and rearrangements of the report elements for more rapid later utilization, the library creates a temporary class file containing all the report expressions such as report variables expressions, text field and image expressions, group expressions, etc.

This temporary Java source file is compiled on the fly using either the Java compiler classes from the JDK used to run the application. If the tools.jar file is not found in the classpath in order to do that, the compilation will go ahead anyway by launching at runtime the javac.exe compiler, behind the scenes. The bytecodes of the resulting class file are stored in the resulting dori.jasper.engine.JasperReport for using when filling the report with data, to evaluate the various report expressions at runtime.

Class dori.jasper.engine.JasperCompileManager

This is the class that exposes all the library functionality concerning the report compilation.

It has various methods that allow the users to compile XML report designs found in files on disk or that come from input streams. It also lets you compile in-memory report designs by directly passing a dori.jasper.engine.design.JasperDesign object and receiving the corresponding dori.jasper.engine.JasperReport object.

Other utility methods include report design verification and XML report design generation for inmemory constructed dori.jasper.engine.design.JasperDesign class instances. Those are very useful especially in GUI tools that simplify the report design work.

Class dori.jasper.engine.JasperPrint

After a compiled report design is filled with data, the resulting document comes in the form of a dori.jasper.engine.JasperPrint instance. Such an object can be viewed directly using the JasperReports build-in report viewer, or can be serialized for disk storage and later use, or for sending it over the network.

The instances of this class represent the output of the report filling process of the JasperReports library and can be considered as a custom format for storing full featured, page oriented documents. They can be transformed into other more popular formats like PDF, HTML, XML or other by using the library's export functionality.

Interface dori.jasper.engine.JRDataSource

JasperReports is a very flexible reporting tool as far as the source of the report data is concerned. It lets people use any kind of data source they might want to, as long as they can provide an appropriate implementation of this interface, so that the reporting engine can interpret and retrieve the data from that data source when filling the reports.

Normally, every time a report is being filled, an instance of this interface is always supplied or created behind the scenes by the reporting engine.

Class dori.jasper.engine.JRResultSetDataSource

This is a default implementation of the dori.jasper.engine.JRDataSource interface.

Since most of the reports are generated using data that comes from a relational database, JasperReports includes by default this implementation that wraps a java.sql.ResultSet object.

This class can be instantiated on purpose, to wrap already loaded result sets, before passing it to the report filling routines, but it is also used by the reporting engine to wrap the data retrieved from the database after having executed through JDBC the report query, if present.

Class dori.jasper.engine.data.JRTableModelDataSource

This class represents another default implementation of the dori.jasper.engine.JRDataSource interface that is shipped with the library. It wraps a javax.swing.table.TableModel object and can be used in Java Swing applications to generate reports using data that has already been loaded into on-screen tables.

Class dori.jasper.engine.JREmptyDataSource

Being the most simple implementation of the dori.jasper.engine.JRDataSource interface, this class can be used in reports that do not display data from the supplied data source, but rather from parameters, and when only the number of virtual rows in the data source is important.

Many of the provided samples such as fonts, images, shapes and unicode use an instance of this class when filling the reports, to simulate a data source with one record in it, but with all the fields null.

Class dori.jasper.engine.JasperFillManager

This class is the fa.ade to the report filling functionality of the JasperReports library.

It exposes a variety of methods that receive a report design in the form of an object, file or input stream and produce a document also in various output forms: object, file or output stream.

But along with the report design, the report filling engine has to receive also the data source from which to retrieve data and the values for the report parameters, in order to generate the documents.

Parameter values are always supplied in a java.util.Map object in which the keys are the report parameter names.

The data source can be supplied in two different forms, depending on the situation:

Normally, it has to be is supplied as a dori.jasper.engine.JRDataSource object, like already mentioned above.

But with the majority of reports in the reporting world being filled with data from relational databases, JasperReports has a built-in default behavior that lets people specify an SQL query in the report design itself. This SQL query is executed in order to retrieve the data to use when filling the report at runtime.

In such cases, the only thing JasperReports needs is a java.sqlConnection object, instead of the usual data source object. It needs this connection object to connect to the relational database management system through JDBC and execute the report query.

It will automatically creates a dori.jasper.engine.JRResultSetDataSource behind the scenes to wrap the java.sql.ResultSet object returned after the execution of the query and passes it to the normal report filling process.

Class dori.jasper.engine.JRAbstractScriptlet

Scriptlets are a very powerful feature of the JasperReports library. They allow users to write custom code that will be executed by the reporting engine during the report filling process. This user code can deal with report data manipulation and gets executed at well-defined moments such as page, column or group breaks, opening a whole new range of possibilities in customizing the content of the generated documents.

Class dori.jasper.engine.JRDefaultScriptlet

This is a convenience subclass of the dori.jasper.engine.JRAbstractScriptlet class. Most of the time users will chose to subclass this when working with scriptlets, so they won't have to implement all the abstract methods declared in the abstract class.

Class dori.jasper.engine.JasperPrintManager

We are talking here about a Java reporting tool and what reporting tools are meant for is printing.

After having filed a report, we have the option of viewing it, exporting it into a different format and last but not least printing it.

In JasperReports, we can print reports using this particular manager class, which is a fa.ade to the printing functionality exposed by the library.

We can find here various methods that send to the printer entire documents or only portions of it, either by displaying the print dialog or not.

The content of a page from a JasperReports document can be displayed by generating a java.awt.Image object for it using this manager class.

Class dori.jasper.engine.JasperExportManager

As already mentioned, JasperReports allows transforming generated documents from its proprietary format into more popular documents formats such as PDF, HTML or XML. With time, this part of the JasperReports functionality will be extended to support other formats like CSV, XSL and other.

This manager class has various methods that ca process data that comes from different sources and goes to different destinations: files, input and output streams, etc.

Class dori.jasper.engine.JasperRunManager

Sometimes is useful to produce documents only in a popular format such as PDF or HTML, without having to store on disk the serialized, intermediate dori.jasper.egine.JasperPrint object, produced by the report filling process.

This can be achieved using this manager class which immediately exports the document produced by the report filling process into the desired output format.

The use of this manager class is shown and can be tested in the supplied webapp sample, where PDF and HTML content is produced on the fly.

Class dori.jasper.view.JRViewer

This class is different from the rest of the classes listed above in the way that it is more like pluggable visual component than an utility class.

It can be used in Swing based applications to view the reports generated by the JasperReports library.

- figure 2 -

This visual component is not meant to satisfy everybody. It was included in the main library more like a demo component, to show how the core printing functionality can be used to display the reports in Swing based applications, by generating java.awt.Image objects for the document pages, using the dori.jasper.engine.JasperPrintManager class.

The preferred way to adapt this component to a particular application needs is by subclassing it.

Class dori.jasper.view.JasperViewer

This is also more like a didactical purpose class that uses the dori.jasper.view.JRViewer component to display reports. It represents a simple Java Swing application that can load and display reports. It is used in almost all of the supplied samples to display the generated documents.

Class dori.jasper.view.JasperDesignViewer

Usually, an application that uses the JasperReports library for reporting purposes will never get to work with this class. This can be used at design time to preview the report templates before going into production and help with the design work. It was included in the main library as a development tool in order to make up for the missing visual designer.

- figure 3 -

This is also used in all the samples to preview the report designs, either in the raw XML form or the compiled form.

Class dori.jasper.engine.util.JRLoader

All JasperReports main processes, like report compilation, report filling and exporting, often work with serialized objects. Sometimes it is useful to manually load those serialized objects before submitting them to the desired JasperReport process.

This is why we have the dori.jasper.engine.util.JRLoader class, which is a utility class that helps loading serialized objects found in various locations such as files, URLs or input streams.

The most interesting method exposed by this class is the loadObjectFromLocation(String location) method.

When calling this method to load an object from the supplied location, the program will first try to interpret the location as a valid URL. If this fails, then the program will consider that the supplied location is the name of a file on disk and will try to read from it. If no file is found at that location, it will try to locate a resource through classpath that would correspond to the location. Only after this third try fails, an exception will be thrown.

Main Tasks and Processes

In this chapter we shall see what you have to know in order to parse your XML report designs, compile them, fill them with data, view them, print them, or export them to other formats.

XML Parsing

JasperReports uses the SAX 2.0 API to parse the XML files. However, it is not tided 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.

Compiling Report Designs

In order to generate a report, one has to create the report's design first, either by editing an XML file or by programmatically building a dori.jasper.engine.design.JasperDesign object. In this book, we shall mainly deal with the XML approach, because it is the preferred way to use the JasperReports library at least for the moment, and we'll have the chance to better understand its behavior.

It is very likely that the present and future GUI tools that are and will be developed to help and simplify the report design work will directly use the JasperReports API to create the report design objects, without the need to pass through the XML form.

But this book does not try to document the use of such GUI tools and concentrates only on the JasperReports core functionality. This is why the entire book is oriented towards explaining the content

and syntax of the XML report designs. Once this approach understood, the other, programmatic approach should be more then intuitive.

As already mentioned, the XML report designs are the raw material that the library uses to generate reports. This is because this XML content has to be parsed and loaded into a dori.jasper.engine.design.JasperDesign object that has to suffer the report compilation process before being ready to be filed with data by the reporting engine.

Note that most of the time, the report compilation should be considered more like a development time job. You should compile your application report designs just like you compile your Java source files, and you should ship them already compiled, with your application, to be installed on the deployment platform. That's because in the majority of cases, the report designs are static and few applications need to offer their users the possibility to dynamically generate report designs, that would need to be compiled at runtime.

The main purpose of the report compilation process is to produce and load the bytecodes of a class containing all the report expressions. This dynamically created class will be used when filling the report to evaluate all those report expressions.

But before proceeding with this class generation, the engine verifies the report design for consistency and will not continue if at least one validation check fails. We shall see what are the conditions for a report design to be considered valid in the following chapters of this book.

For now, we only need to know how the report compilation works, so that we can make sure it can be performed successfully.

There are at least three important aspects concerning the way the bytecodes for this class containing all the report expressions are obtained:

temporary working directory;

Java compiler used;

classpath;

In order to be able to compile a Java source file, this file must be created and saved on disk. The output of the Java compilation process is also a file with the .class extension. This is why JasperReports needs access to a temporary, working directory for it to create the class containing the report expressions and to compile it. After the report compilation task is finished, those temporary class files will be automatically deleted and the resulting bytecodes are stored in the resulting dori.jasper.engine.JasperReport, which can be serialized itself and stored on disk, if desired.

By default, the temporary working directory is the current directory when launching the JVM, and it is obtained interrogating the user.dir system property. It can easily be changed, by supplying a value to a system property called jasper.reports.compile.temp. This is useful especially in Web environment when you don't want to end up using the same directory that contains the batch files that launch the Web server, as a temporary working location for the report compilation process.

The second aspect mentioned concerns the Java compiler used to compile the report expressions class. First, the reporting engine tries to compile the Java source file using the sun.tools.javac.Main class. This approach may succeed only if the tools.jar file that contains this class, usually found in the /lib directory of the JDK installation directory, is available through classpath.

If loading the compiler class sun.tools.javac.Main fails, the program tries to dynamically launch the Java compilation process, just like we would normally do it from the command line, using the javac.exe program found in the /bin directory of the JDK installation directory.

This is why in the project tree available for download, copying the tools.jar file from the JDK location into the /lib directory of the JasperReports project is an optional operation. If the tools.jar file is not found in classpath, JasperReports displays a warning and continues as mentioned.

When compiling Java source files, the most important thing seems to be the classpath. If the Java compiler does not find in the supplied classpath all the classes that are referenced by the source files it tries to compile, the whole process fails and stops, the errors being displayed on the console.

The same happens also when JasperReports compiles the report expressions class. It is important then to make sure we supply to the Java compiler at runtime the correct classpath for the compilation process to succeed. For instance, we have to make sure that in the classpath we supply the custom classes that we might use in the report expressions.

There is a default behavior for this aspect also. If no special classpath for compiling the report classes is supplied, the engine will use the current JVM classpath returned by the system property java.class.path. This default behavior can be overridden by putting the desired classpath in the system property called jasper.reports.compile.class.path.

You can see the jsp/compile.jsp and WEB-INF/classes/servlets/CompileServlet.java files in the webapp sample provided, for the code snippet that makes use of this Java system properties to override the default behavior of the JasperReports report compilation process.

Most of the time, compiling a report requires only a simple call to the JasperReports library like in the following line of code:

dori.jasper.engine.JasperCompileManager.compileReport(myXmlFileName);

This call will produce the compiled report design and will store it in a file with the .jasper extension, located in the same directory as the supplied XML report design file.

Report Design Preview

The JasperReports library is not shipped with an advanced GUI tool to help the design work. At this time, there are at least 4 projects that try to provide such a tool.

However, the library contains a very helpful visual component that allows report creators to preview the report designs as they build them.

The dori.jasper.view.JasperDesigner class is a simple Swing based Java application that can load and display a report design either in its XML form or in the compiled form. Even if it is not a complex GUI application, lacking advance functionality like the drag and dropping of the visual report elements, it is very helpful instrument. All the supplied samples were created using this design viewer.

All the supplied samples have already prepared ANT tasks in their build.xml files that will launch this design viewer for you to see the report designs.

In fact there are 2 ANT tasks for each sample report: viewDesign and viewDesignXML.

The first one loads the compiled report design that is normally found in the .jasper file. The second one loads the XML report design, being the most useful since you can edit the XML file and push the Reload button to immediately see the modification appearing on the screen.

If you have the ANT build tool installed on your system, in order to preview a sample report design, you simply go to the desired sample directory and launch from the command line something like this:

>ant viewDesignXML

or

>ant viewDesign

In case you do not have ANT installed and you don't want to get it (you'll miss all the fun), here's the complete command line that will launch the design viewer to preview one of the sample XML report designs. We assume that you have a copy of the entire JasperReports source tree on your system (Windows command line syntax):

>java -classpath ./;../../../lib/commons-digester.jar;

../../../lib/commons-beanutils.jar;../../../lib/commons-collections.jar;

../../../lib/xerces.jar;../../../lib/jasperreports.jar

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

dori.jasper.view.JasperDesignViewer -XML -FFirstJasper.xml

By launching this command line, you should be able to see this window:

- figure 4 -

Filling Reports

The report filling process is the most important of all the JasperReports library functionality. It represents the main objective for this piece of software, as it is the process that manipulates sets of data in order to produce high quality documents, just like any reporting tool is supposed to do.

There are tree things that should be supplied to the report filling process as input:

report design (report template);

parameters;

data source.

The output is always a single, final document that is ready to be viewed, printed or exported to other formats.

We have already seen that in order to fill a report, we are going to use the dori.jasper.engine.JasperFillManager class. This class has various methods that allow us to fill report designs that are located on disk, come from input streams or are supplied directly as inmemory dori.jasper.engine.JasperReport objects.

The output produced always corresponds to the type of the input received. That is, when receiving a file name for the report design, the generated report will be also placed in a file on disk. When the report design is read from an input stream, the generated report will be written to an output stream and so forth.

It might be that those various utility methods for filling the reports are not sufficient for a particular application, who for example would want to load report designs as resources from classpath and output the generated documents to files on disk, at a certain location.

In such cases, the developers should consider loading the report design objects before passing them to the report filling routines, using the dori.jasper.engine.util.JRLoader utility class. This way, they could retrieve some report design properties such as the report name, so they can construct the name of the resulting document, to place at the desired disk location.

There are a lot of report filling scenarios that could be imagined in a real world application, and the report filling manager class only tries to cover a portion of them, considered to be used more often. But it should be no problem for anybody who might want to customize the report-filling process using the library's basic functionality, as suggested above.

The report parameter values are supplied always packed in a java.util.Map object, which has the parameter names as its keys.

As for the third thing that the report filling process expects to receive, the data source, there are two different scenarios.

Normally, the engine works with an instance of the dori.jasper.engine.JRDataSource interface, from which it extracts the data when filling the report.

And the fa.ade class dori.jasper.engine.JasperFillManager has a full set of methods that receive a dori.jasper.engine.JRDataSource object as the data source of the report that is going to be filled.

But there is another set of report filling methods in this manager class that receive a java.sql.Connection object as a parameters, instead of expected data source object.

This is because most of the time reports are generated using data that comes from tables found in relational databases.

Users have the possibility to specify the SQL query needed to retrieve the report data from the database, in the report design itself. At runtime, the only thing the engine would need would be a JDBC connection object to use in order to connect to the desired relational database, execute the SQL query and retrieve the report data.

Behind the scenes, the engine will still use a special dori.jasper.engine.JRDataSource object, but this is preformed transparently for the calling program.

There are at least 4 sample applications provided with the project, which fill the reports using data from an also supplied HSQL database server. Those are jasper, query, scriptlet and subreport samples. To run them, you have to start the HSQL database server first, by going to the /demo/hsqldb directory of the JasperReports project and launching this command:

>ant

or

>ant runServer

Note that you have to have ANT build tool installed on your system for you to launch the server in such as simple manner. Otherwise you could still launch it like this:

>java -classpath ./;../../lib/hsqldb.jar org.hsqldb.Server

Here's a simple code snippet taken from the query sample that shows how to fill a report:

//Preparing parameters

Map parameters = new HashMap();

parameters.put("ReportTitle", "Address Report");

parameters.put("FilterClause", "'Boston', 'Chicago', 'Oslo'");

parameters.put("OrderClause", "City");

//Invoking the filling process

JasperFillManager.fillReportToFile(fileName, parameters, getConnection());

Viewing Reports

The output of the report filling process is always a dori.jasper.engine.JasperPrint object.

If we serialize this object and store it on disk, normally in a .jrprint file, we could say that this is the proprietary format in which JasperReports stores its generated documents.

In order to view the generated reports in this proprietary format or in the proprietary XML format produced by the internal XML exporter, JasperReports has a built-in viewer. It is a Swing based component that can be easily integrated in other Java applications that want to offer this functionality, without the need for them to export the documents in more popular formats, so that they can be viewed. The dori.jasper.view.JRViewer class represents this visual component. It can be customized to respond to a particular application needs by subclassing it. This way we could add or remove buttons from the existing toolbar it displays, or perform other modifications.

This is shown in the supplied webapp sample, where the JRViewerPlus class adds a new button to the existing toolbar of this report viewer component.

JasperReports comes also with an included simple Swing application that uses the visual component for viewing the reports. It helps viewing reports stored on disk, in the JasperReports .jrprint proprietary format as we called it or in the XML format produced by the default XML exporter.

This simple Java Swing application is implemented in the dori.jasper.view.JasperViewer class and it is used in almost all the provided samples to view the generated reports.

If you have the ANT build tool installed on your system, in order to view a sample report, you go to the desired sample directory and launch the following from the command line:

>ant view

or

>ant viewXML

Here are the corresponding complete command lines in case you don't have ANT installed, to view one of the sample report both in the .jrprint and XML formats (Windows command line syntax):

>java -classpath ./;../../../lib/jasperreports.jar

dori.jasper.view.JasperViewer -FFirstJasper.jrprint

or

>java -classpath ./;../../../lib/commons-digester.jar;

../../../lib/commons-beanutils.jar;

../../../lib/commons-collections.jar;

../../../lib/xerces.jar;../../../lib/jasperreports.jar

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

dori.jasper.view.JasperViewer -XML -FFirstJasper.jrpxml

By launching these command lines, you should be able to see this window:

- figure 5 -

The viewer application implemented in the dori.jasper.view.JasperViewer 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.

Those who will try to use it directly in their applications, by calling the public and static viewReport() methods it exposes, will end up noticing that when they close the report viewer frame, their application will unexpectedly terminate. This is because the JasperViewer class makes a call to the System.exit(0) and a way around this would be to subclass it and remove the java.awt.event.WindowListener it has registered by default.

Printing Reports

The main objective of the JasperReports library, if not of all existing reporting tools, is to create ready to print documents. The majority of reports that are generated by applications end up or are supposed to end up on paper.

We can print the documents generated by the JasperReports library using the dori.jasper.engine.JasperPrintManager class. Of course, documents can also be printed after they are exported to other formats such as HTML or PDF. But we are going to explain how to use the specialized manager class mentioned, to print documents that are stored or transferred in the JasperReports proprietary format (dori.jasper.engine.JasperPrint objects).

Among the various methods that the dori.jasper.engine.JasperPrintManager class exposes, we can find some that allow printing a whole document, a single page or a page range, with and without displaying the print dialog.

Here's how you could print an entire document without displaying the standard print dialog:

dori.jasper.engine.JasperPrintManager.printReport(myReport, false);

And now another code snippet that shows how to print all the pages from 5 to 11 of your document, after having displayed the standard print dialog:

dori.jasper.engine.JasperPrintManager.printPages(myReport, 4, 10, true);

Exporting Reports

In some application environments, it is useful to transform the JasperReports generated documents, from the proprietary format into other, more popular formats like PDF or HTML. Doing this, you can make sure other people can view those reports without having to install special viewers on their systems, especially when sending the documents over the network.

There is a fa.ade class in JasperReports also for this type of functionality. Its name is dori.jasper.engine.JasperExportmanager and can be used to obtain PDF, HTML or XML content for the documents produced by the report filling process.

Exporting means taking a dori.jasper.engine.JasperPrint object, which represents a JasperReport document and transform it in a different format. The main reason to export the reports into other formats is to allow more and more people to view those reports. HTML reports can be viewed by anybody these days, since at least one browser is available on any system. Viewing JasperReports documents in their proprietary form would require the installation of special software on the target platform, at least in the form of a Java applet if not more.

In conclusion, the ability to export reports into other formats is a very useful feature and with time, more and more output formats will be supported.

Those who want to export their reports into other, new formats, have to implement a special interface called dori.jasper.engine.JRExporter or to extend the corresponding dori.jasper.engine.JRAbstractExporter class.

For the moment, the library is shipped with 3 special exporter classes that produce PDF, HTML and XML. Those are found in the dori.jasper.engine.export package, but can be used by calling the appropriate methods on the fa.ade manager class mentioned previously.

Here's how you could export your report to HTML format:

dori.jasper.engine.JasperExportManager.exportReportToHtmlFile(myReport);

Object Loading and Saving

When using the JasperReports library functionality, you'll often get to work with serialized objects such as compiled report designs, generated reports, etc.

Sometimes you'll have to manually load serialized objects from different sources like files and input streams or to serialize the object you produce yourself using the library's core functionality.

There are two utility classes, specially created for these kinds of operations, which are often used by the reporting engine itself:

dori.jasper.engine.util.JRLoader

dori.jasper.engine.util.JRSaver.

The first one exposes various methods that allow people to load serialized object from different types of sources like files, URLs, input streams or classpath resources.

The most interesting utility method found in this class, is the one called loadObjectFromLocation.

It receives a java.lang.String as a parameter and returns the serialized object loaded from that particular location. First, the program tries to see whether the supplied location is a valid URL. If it is, it will try to load a serialized object from that URL. If it is not a valid URL, the program will assume that the parameter represents the name of a file and will try to locate on disk in order to read the serialized object from there. If it is no file is found, the program will finally assume that the specified location represents a classpath resource name and will read from there. Only if those operations fail, an exception will be thrown.

The counter part of this object loading utility class is the dori.jasper.engine.util.JRSaver class that you could use to serialize your objects and put them into files on disk or send them over the network through output streams.

There is another important aspect that we mention in this section because it has to do with object loading. It is about loading already generated reports or final JasperReports documents that have been previously exported to the XML format.

Unlike the above loader, it is not about loading serialized objects, but about parsing XML content and creating a dori.jasper.engine.JasperPrint object that will mirror the document found in that XML content.

This can be achieved using the dori.jasper.engine.xml.JRPrintXmlLoader class, which has public static methods that can create in-memory document objects by parsing XML content read from files or input streams.

Report Designs

The 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 during the report filling process according to this report design to obtain ready to print, page oriented documents.

Generally speaking, a report design contains all the information concerning the structure and the aspect of the documents that will be generated when the data will be provided. This information concerns the position and the content of various text or graphic elements that will appear on the document, their appearance, the custom calculations, data grouping and data manipulation that should be performed when generating the documents, etc.

Normally, the report designs are defined in XML files with a special structure that we shall see in detail later and are subject to the JasperReports compilation process before being filled with data. But they also can be constructed in-memory, programmatically, using the JasperReports API. There is a sample called noxmldesign shipped with the JasperReports project source files that shows how to directly create in-memory report designs, without editing any XML files at all.

DTD Reference

When working with XML report designs, JasperReports uses its own internal DTD files to validate the XML content it receives for processing. If the XML validation is passed, it means that the supplied report design corresponds to the JasperReports required XML structure and syntax and the engine is able to generate the compiled version of the report design.

Valid XML report designs always point to the JasperReports internal DTD files for validation. Without the DTD reference specified, the report compilation process fails abruptly. This should not be considered a too much burden for anybody since the DTD reference is always the same and can simply be copied from previous report designs. At the beginning you will copy it from the supplied samples.

As already mentioned, the engine recognizes only the DTD references that point to its internal DTD files. You cannot make a copy of the DTD files found among the library source files and point to that copy in your XML report designs. If you want to do that, you will also have to alter the code of some of the library classes including the dori.jasper.engine.xml.JRXmlDigester class.

If you ever encounter problems such as the engine not finding its own internal DTD files due to some resource loading problems, make sure you have eliminated every possible cause before deciding to use external DTD files. Encountering such a problem is very unlikely since the resource loading mechanism of the library was improved with time.

There are only two valid DTD references for the XML report designs and they are the following:

<!DOCTYPE jasperReport PUBLIC "-//JasperReports//DTD Report Design//EN" "http://jasperreports.sourceforge.net/dtds/jasperreport.dtd">

or

<!DOCTYPE jasperReport PUBLIC "-//JasperReports//DTD Report Design//EN" "http://www.jasperreports.com/dtds/jasperreport.dtd">

The root element of an XML report design is <jasperReport> and this is how an usual JasperReports XML report design file looks:

<?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" ... >

...

</jasperReports>

The first 3 points make it for the report design properties and settings and the other 3 for the suppressed various report design elements such as report parameters, fields, variables, groups, report sections, etc. We shall see all of them in detail in the following chapters of this book.

XML Encoding

When creating XML report designs in different languages, a special attention should be accorded to the encoding attribute that can be used in the header of the XML file. By default, if no value is specified for this attribute, the XML parser uses "UTF-8" as the encoding for the content of the XML file.

This important because the report design often contains localized static texts, which are introduced when manually editing the XML file.

For most of the West European languages, the "ISO-8859-1" encoding, also known as LATIN1, should be sufficient to deal with special characters like é, a, è, ., that we have in French for example.

<?xml version="1.0" encoding="ISO-8859-1"?>

<!DOCTYPE jasperReport PUBLIC "-//JasperReports//DTD Report Design//EN" "http://jasperreports.sourceforge.net/dtds/jasperreport.dtd">

<jasperReport name="name_of_the_report" ... >

...

</jasperReports>

To find out what is the exact encoding type to specify when editing XML files in a particular language, you have to check the XML documentation. FIXME

Report Properties

We have already seen that <jasperReport> is the root element of an XML report design. In this section will get to know in detail what are the properties of a report design objects and what is are the XML attributes that correspond to them.

XML Syntax

<!ELEMENT jasperReport (reportFont*, parameter*, queryString?, field*, variable*, group*, title?, pageHeader?, columnHeader?, detail?, columnFooter?, pageFooter?, summary?)>

<!ATTLIST jasperReport

name NMTOKEN #REQUIRED

columnCount NMTOKEN "1"

printOrder (Vertical | Horizontal) "Vertical"

pageWidth NMTOKEN "595"

pageHeight NMTOKEN "842"

orientation (Portrait | Landscape) "Portrait"

whenNoDataType (NoPages | BlankPage | AllSectionsNoDetail) "NoPages"

columnWidth NMTOKEN "555"

columnSpacing NMTOKEN "0"

leftMargin NMTOKEN "20"

rightMargin NMTOKEN "20"

topMargin NMTOKEN "30"

bottomMargin NMTOKEN "30"

isTitleNewPage (true | false) "false"

isSummaryNewPage (true | false) "false"

scriptletClass NMTOKEN #IMPLIED

>

Report Name

Every report design has to have a name. Its name is important because the library uses it when generating files, especially when the default behavior is preferred for compiling, filling or exporting the report.

The name of the report is specified using the name attribute of the <jasperReport> element and is mandatory. Spaces are not allowed in the report name, which has to be one word.

Column Count

JasperReports allows creating reports with more than one column on each page, like in the following picture, where we can see the layout of a report with two columns:

- figure 6 -

By default, the reporting engine creates report with one column on each page.

Print Order

For the reports having more that one column, is important to specify the order in which the columns will be filled and this can be done using the printOrder attribute of the <jasperReport> element.

There are two possible situations:

Vertical filling: Selecting this option will ensure the columns are filled from top to bottom and left to right (printOrder="Vertical").

Horizontal filling: Columns are filled from left to right and top to bottom (printOrder="Horizontal").

The default print order is: printOrder="Vertical"

Page Size

There are two attributes at this level to specify the page size of the document that is going to be generated: pageWidth and pageHeight.

Like all the other JasperReports attributes that represent element dimensions and position, those should be specified in pixels. JasperReports uses the default Java resolution of 72 dots per inch.

This means that a pageWidth="595" will make about 8.26 inches, which is roughly the width of an A4 paper.

The default page size corresponds to an A4 paper:

pageWith="595" pageHeight="842"

Page Orientation

The orientation attribute is used to specify whether we are creating documents using the "Portrait" or the "Landscape" formats.

JasperReports requires you to adapt the page width and the page height when switching from "Portrait" documents to "Landscape" or vice-versa.

Let's see an example:

We assume that we want to create an A4 report using the "Portrait" layout.

An A4 has approximately this size:

pageWidth="595" pageHeight="842" orientation="Portrait"

If we decide to use the "Landscape" layout for our A4 document, we have to make sure we modify the page with and page height accordingly, like in the following:

pageWidth="842" pageHeight="595" orientation="Landscape"

This is because JasperReports has to know exactly the absolute width and height of the pages it will draw on, and does not necessarily consider the value that we supply in the orientation attribute, at least not at report filling time.

This orientation attribute is only useful at report printing time, to inform the printer about the page orientation or in some special exporters.

The default page orientation is "Portrait".

Page Margins

Once the page size decided, you can specify what margins should the reporting engine preserve when generating the reports. And there are 4 attributes for the job: topMargin, leftMargin, bottomMargin and rightMargin (figure 6).

There is a 20 pixels default margin for the top and bottom of the page and a 30 pixels default margin for the right and left margins.

Column Size and Spacing

Reports may have more that one column, as we have already seen when we have talked about the columnCount attribute above.

But the reporting engine has to know how large a column can be and what space should it let between columns. There are two attributes for this job: columnWidth and columnSpacing.

There is also a validation check performed when we compile the report designs, that do not let us create reports in which the width of the overall columns and the space between does not fit on the specified page width and page margins.

Since there is only one column by default, the default column spacing is 0 pixels and the default column width is equal to the default page width, minus the default left and right margins, which make 555 pixels.

Empty Data Source Behavior

Sometimes the data source that we supply to our reports has no records in it. In this case, it is not clear what the output should be.

Some may expect to see a blank document in these situations and others might want to have some of the report sections displayed anyway.

There is an attribute called whenNoDataType that lets you decide how the generated document should look when there is no data in the data source supplied to it.

There are 3 possibilities you can choose from:

Empty document: The generated document will have no pages in it. Viewers might throw an error when trying to load such documents (whenNoDataType="NoPages").

Blank page: The generated document will contain a single blank page (whenNoDataType="BlankPage").

All sections displayed: All the report sections except the detail section will appear in the generated document (whenNoDataType="AllSectionsNoDetail").

The default value for this attribute is whenNoDataType="NoPages".

Title and Summary Sections Placement

If you want to have the title section or the summary section displayed on separate pages, all you have to do is to set one or both of the following attributes to "true": isTitleNewPage and isSummaryNewPage.

Both this boolean attributes are set to false by default.

Note that even if you choose to display the summary section on the remaining space of the last page, a new page will automatically be started if the report has more than one column and the second column was already started on this last page.

Scriptlet Class

The scriptletClass attribute lets you specify the name of the scriptlet class designed for the current report. You learn more about scriptlets in the 7 Scriptlets chapter of this book dedicated to them.

If no value is supplied to this attribute, the reporting engine will use a dori.jasper.engine.JRDefaultScriptlet instance anyway.

Report Data

When we have talked about the report filling process, we have said that there are those 3 things that have to be supplied as input to it: the report design, the parameter values and the data source of the report.

In the previous chapter we have already seen some of the aspects regarding the reports designs and now we are going to take a close look at the other two: the parameters and the report data source. They represent the only source of data that the reporting engine will use when filling the report.

This data will be organized according to the template defined in the report design and will produce a ready to print, page oriented document, as you might expect from any reporting tool.

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 parameters, report fields and report variables, using a special syntax.

In an XML report design there are several elements that define expressions: <variableExpression>, <initialValueExpression>, <groupExpression>, <printWhenExpression>, <imageExpression>, <textFieldExpression> and others.

Since all the JasperReports expressions are real Java expressions, you can use in them any class that you might want to, as long as you refer to it using its complete class name (including the package). You also have to make sure the classes you are using in the report expressions are available in the classpath when you compile your report and when you fill it with data.

The report expressions would be useless, if there would be no way to reference in them the report parameters, the report fields or the declared report variables. Fortunately, there is a special JasperReports syntax that allows you to introduce such references in the expressions you create in the XML report design.

Report parameter references are introduced using the $P{} character sequence like in the following example:

<textFieldExpression>

$P{ReportTitle}

</textFieldExpression>

This example assumes that we have a report parameter called ReportTitle declared in the report design, who's class is java.lang.String. The text field will display the value of this parameter when the report will be filled.

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 data source 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 report 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>

As you can see, the parameter, field and variable references introduced by the special JasperReports syntax are in fact real Java objects. And knowing their class from the parameter, field or variable declaration mate in the report design, we are able to even call methods on those object references in our expressions.

Here's how we might be able to extract and display the first letter from a java.lang.String report field:

<textFieldExpression>

$F{FirstName}.substring(0, 1)

</textFieldExpression>

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.

XML Syntax

<!ELEMENT parameter (parameterDescription?, defaultValueExpression?)>

<!ATTLIST parameter

name NMTOKEN #REQUIRED

class NMTOKEN #REQUIRED

isForPrompting (true | false) "true"

>

<!ELEMENT parameterDescription (#PCDATA)>

<!ELEMENT defaultValueExpression (#PCDATA)>

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"/>

The supplied values for the report parameters can be used in the various report expressions, in the report SQL query or even in the report scriptlet class. We are going to see all this in the following special sections of this book that will tread each report expression, the query and the scriptlets.

Here are the components that make a report parameter definition complete:

Parameter Name

The name attribute of the <parameter> element is mandatory and allows referencing the parameter by its declared name. The naming conventions of JasperReports are similar to the naming conventions of the Java language, in regards with variable declaration. That means that the parameter name should be a single word, with no special characters in it, like a dot or a comma.

Parameter Class

The second mandatory attribute for a report parameter is the one who specifies the class name for the parameter values. The class attribute can have any value as long it represent

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值