Package net.sf.jasperreports.engine.export

Provides utility classes for exporting reports to various popular formats such as PDF, HTML, RTF, CSV, Excel, DOCX, PPTX, ODT, ODS, XML, Text, etc.

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, HTML, RTF, or XLSX. This way, users can view those reports without having to install special viewers on their systems, which is especially important in the case of documents sent over a network.

There is a facade class in JasperReports for this type of functionality: JasperExportManager; it can be used to obtain PDF, HTML, or XML content for the documents produced by the report-filling process. Exporting means taking a JasperPrint object, which represents a JasperReports document, and transforming it into a different format. The main reason to export reports into other formats is to allow 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 a Java applet, if not more).

With time, more and more output formats will be supported by the JasperReports library. For the moment, the various exporter implementations shipped with the library produce Graphics2D, PDF, HTML, RTF, CSV, Excel, DOCX, PPTX, ODT, ODS, XML, pure text and JSON output.

The JasperExportManager class offers easy access for only the PDF, HTML, and XML implementations, as these have historically been the most common formats or required the least export configuration.

Here's how you can export your report to HTML format using the facade export manager class:

 JasperExportManager.exportReportToHtmlFile(myReport); 
To avoid excessive utility methods, this class was originally written such that the default settings only offer easy access to the most common export formats. When new exporters were added to the library, the export manager class was not extended, and users were encouraged to use the exporter classes directly. Only by doing that could they fully customize the behavior of that particular exporter using specific exporter parameters.

JasperReports tries to expose its exporting functionality in a flexible way and allow users to fully customize how documents are exported, as well as extend the existing functionality if needed. All document exporting in JasperReports is done through a very simple interface called Exporter. Every document format that JasperReports currently supports has an implementation of this interface. When a report must be exported, an instance of the desired exporter implementation is created and configured before the export method is called to launch the actual export process on that exporter.

Exporter Input

All the input data the exporter might need is supplied by the so-called exporter input before the exporting process is started. This is because the exporting process is always invoked by calling the exportReport() method of the Exporter interface, and this method does not receive any parameters when called.

The input data for an exporter comes in the form of one or more JasperPrint objects that must be exported to some other document format, along with other optional export settings. These JasperPrint objects may be already in memory, come from the network through an input stream, or reside in files on disk.

An exporter should be able to handle such a wide range of document sources. In fact, all the exporter implementations that are shipped inside the library already do this. They all extend the JRAbstractExporter class, which holds all the logic for dealing with the source documents that need to be exported inside its defined setExporterInput(ExporterInput exporterInput) method.

As shown in the method signature, all we need is an ExporterInput instance that holds the necessary input data. This object must implement the public List<ExporterInputItem> getItems() method in order to obtain a list of ExporterInputItem objects. Each ExporterInputItem object in the list contains a single JasperPrint object along with its related export configuration settings.

Exporter Output

There are at least three types of exporters, depending on the type of output they produce:
  • Exporters that export to text- or character-based file formats (HTML, RTF, CSV, TXT, XML ... exporters)
  • Exporters that export to binary file formats (PDF, XLS ... exporters)
  • Exporters that export directly to graphic devices (Graphics2D and Java Print Service exporters)
The first two categories of exporters reuse generic exporter settings for configuring their output. A text- or character-oriented exporter first looks into its ExporterOutput setting to see whether it needs to output the text content it produces to:
  • a supplied java.lang.StringBuffer object
  • a supplied java.io.Writer object
  • a supplied java.io.OutputStream object
  • a java.io.File object
  • a file with a given java.lang.String file name
If none of these OUT parameters have been set, then the exporter throws an exception to inform the caller.

A binary exporter uses similar logic to find the output destination for the binary content it produces. It checks generic exporter output settings in this exact order: java.io.OutputStream, java.io.File, or file with a given java.lang.String file name.

Special exporters that do not produce character or binary output but rather render the document directly on a target device have special export settings to configure their output.

Output settings for all built-in exporters can be set using the public void setExporterOutput(O exporterOutput) method inherited from their JRAbstractExporter parent class. The exporterOutput argument must be an instance of ExporterOutput interface.

Other Export Configuration Settings

Other export configuration settings can be communicated to exporters using the public void setConfiguration(C configuration) and public void setConfiguration(RC configuration) inherited from the JRAbstractExporter parent class. The first method accepts an ExporterConfiguration argument and applies settings per exporter. The second one accepts a ReportExportConfiguration and applies settings per each exported report in a batch export.

Below are some examples of report configuration settings available in the ReportExportConfiguration class:

  • the start page index - specifies the 0-based index for the first page in a page range to be exported
  • the end page index - specifies the 0-based index for the last page in a page range to be exported
  • the page index - specifies the 0-based index for a single page to be exported. If present, this setting overrides both the first page index and the end page index
  • the x offset - to move the page content horizontally, when it doesn't always fit with the printer page margins
  • the y offset - to move the page content vertically, when it doesn't always fit with the printer page margins
  • etc

Batch Mode Export

The first thing an exporter needs to know is whether it is acting on a single JasperPrint document or a list with several such generated documents. Exporting multiple JasperPrint objects to a single resulting document is called batch mode exporting.

Not all exporters can work in batch mode, but those that do first look into the supplied exporter input values to see whether a java.util.List of JasperPrint object has been supplied to them. If so, the exporter loops through this list of documents and produces a single document from them.

If the exporters act on a single document, then they check whether an in-memory JasperPrint value is supplied to the exporter input data. If no such value is found for this setting, then the input for the exporter is a single JasperPrint document to be loaded from an input stream, an URL, a file object, or a file name. If the exporter does not find any of these settings, then it throws an exception telling the caller that no input source was set for the export process.

Exporter Filters

When exporting a report to any format, it is possible to filter the elements from the generated report by skipping elements that do meet a certain condition. This allows report designers to control what gets exported to each format. In many cases, it's not desirable to export all report sections and elements to all output formats; for instance, some visual report elements should only be displayed in output formats that are meant for on-screen viewing and not in other data-centric output formats.

JasperReports comes with two built-in filter implementations that cover the most frequent use cases. It also defines a set of interfaces that can be used to introduce other filter implementations. Custom export filter can be written by users to support specific filtering mechanisms.

When exporting a report, a filter can be explicitly specified using an export parameter, or a filter can be implicitly created based on the properties/export hints present in the report.

To explicitly specify an export filter, the exporter configuration setting public ExporterFilter getExporterFilter() (method in the ReportExportConfiguration class) should be used to pass a filter object, which would be an instance of a class that implements the ExporterFilter interface. The filter object can be of one the built-in export filter types, or of a custom filter implementation type.

When no value is found for the export filter setting, the exporter will use a default filter factory to instantiate a filter that will be used for the export. The default filter factory class is set via a property named net.sf.jasperreports.engine.export.default.filter.factory.

The built-in default filter factory implementation calls all registered filter factories and allows each of them to apply filters on the exporter report. If any of the filters decides to exclude an element, the element will be excluded from the export process. In most cases the built-in default filter factory provides the desired behavior. However users can choose to change it by setting another value for the default filter factory property. To allow a custom export filter implementation to be used by the implicit export filter mechanism, one needs to register an export filter factory class with JasperReports. To do so, a property named net.sf.jasperreports.engine.export.filter.factory.<factory_name> has to be included in the jasperreports.properties file (or set at runtime via JRPropertiesUtil). The factory name is an arbitrary suffix, and the property value should be the name of a class that implements ExporterFilterFactory. The engine uses the class name to instantiate an export filter factory, therefore the factory class needs to have an accessible no-argument constructor.

Each registered filter factory has the chance of producing a filter every time a report export occurs. The filter factory receives an object that contains information about the current export process, including the exporter report and a property prefix that corresponds to the exporter, and decides based on this information whether it applies to the current export or not. This would usually involve consulting custom properties of the exporter report to determine whether the report contains properties that indicate some filtering criteria. The recommended practice is to make the filter factory recognize properties that have a specific suffix appended to the exporter property prefix. For instance, the element key filter factory recognizes properties that have exclude.key appended after the exporter property prefix.

If the exporter factory decides that it applies to the current report, it needs to return a non null exporter filter, which is an instance of a class that implements ExporterFilter. This filter will be applied to each element in the generated report and will be able to trigger the exclusion elements that match a given criteria.

Each exporter uses a different property prefix such that different filter criteria can be set for each exporter. The built-in exporters use property prefixes of the form net.sf.jasperreports.export.<output_format>. Below are the property prefixes for the built-in output formats:

  • Java Print/Graphics2D - net.sf.jasperreports.export.graphics2d
  • PDF - net.sf.jasperreports.export.pdf
  • RTF - net.sf.jasperreports.export.rtf
  • XML - net.sf.jasperreports.export.xml
  • HTML - net.sf.jasperreports.export.html
  • Excel - net.sf.jasperreports.export.xls
  • DOCX - net.sf.jasperreports.export.docx
  • PPTX - net.sf.jasperreports.export.pptx
  • ODT - net.sf.jasperreports.export.odt
  • ODS - net.sf.jasperreports.export.ods
  • CSV - net.sf.jasperreports.export.csv
  • Text - net.sf.jasperreports.export.txt
In case no filter instance is passed at export time, the exporter searches for some configuration properties with a given prefix, both at report level (exporter hints) and globally, in order to decide if a default exporter filter instance should be created on-the-fly and used internally, when exporting the current document.

If created, this default exporter filter will filter out content from the exported document based on element origin information. Elements present in JasperReports generated documents keep information about their origin. The origin of an element is defined by its parent section in the initial report template, and optionally the name of the group and/or subreport that the element originated from.

This built-in filter implementations also exclude from export elements that match a given element key.

Element keys are set at report design time and are propagated into generated reports. Each element in a filled report has the same key as the element from the report template that generated it.

To trigger an element key filter, the report designer needs to define one or more report properties that start with <exporter_property_prefix>.exclude.key. Each such property matches a single element key which is to be excluded by the filter. The element key is given by the property value, or if no value is set for the property, by the property suffix.

Monitoring Export Progress

Some applications need to display a progress bar to show the user how much has been already processed from the supplied document and how much remains to be exported.

All exporters can inform the caller program of their progress through a simple interface called JRExportProgressMonitor. To monitor the exporter's progress, implement this interface and supply an instance of its export progress monitor class as the value for the getProgressMonitor() report exporter configuration setting, which is recognized by almost all built-in exporters.

The interface has only one method, afterPageExport(), which gets called by the exporter on the monitor object after exporting each page from the supplied document.

The monitor object can keep track of the number of pages already exported and the total number of pages to be exported by checking the number of pages in the source JasperPrint object.

Grid Exporters

The main goal of the JasperReports library is to produce high-quality, pixel-perfect documents for printing. The documents it produces can have rich content, and all the elements on a given page are positioned and sized absolutely. The library tries to keep the same document quality throughout all supported export formats, but there are some limitations for each of these formats. All existing exporters fall into one of two categories, depending on the way the content of the documents they produce can be structured:
  • exporters that target document formats that support free-form page content (Graphics2D, PDF, RTF, XML exporters).
  • exporters that target document formats that only support relative positioning of elements on a page or a grid-based layout (HTML, Excel, CSV exporters).
Exporters from this second category are also known as grid exporters because the layout of the documents they produce is formed by a grid. For instance, the HTML exporter will generate a <table> element for each page and try to put each element on that page inside a <td> tag. Likewise, the XLS exporter must put each element inside a sheet cell.

These grid exporters have an obvious limitation: a built-in algorithm for transforming an absolutely positioned page layout into a grid-based layout. This algorithm analyzes each page and tries to build a virtual table in which to place elements so that the overall layout of the document remains intact. However, since a table cell can contain only a single element, elements that overlap in the initial absolutely positioned layout will not display correctly in a grid-based layout. In fact, when two elements overlap, the element behind will not even appear in the grid-based layout.

When the report templates are very complex or agglomerated, passing from absolute positioning to grid or table layout produces very complex tables with many unused rows and columns, in order to make up for the empty space between elements or their special alignment. Here are a few very simple guidelines for obtaining optimized HTML, XLS, or CSV documents when using the built-in JasperReports grid exporters:

  1. Minimize the number of rows and columns in the grid-oriented formats (the number of "cuts"). To do this, align your report elements as often as you can, both on the horizontal and the vertical axes, and eliminate the space between elements.
  2. Make sure report elements will not overlap when the report is generated. If two elements share a region, they cannot share the same cell in the resulting grid structure. Overlapping elements might lead to unexpected results.

Related Documentation

JasperReports Tutorial
See Also:
JasperExportManager, JasperPrint, JRAbstractExporter, Exporter, ExporterConfiguration, ExporterInput, ExporterInputItem, ExporterOutput, ReportExportConfiguration