Chapter 5. Working with Other Datasources
As we mentioned previously, JasperReports allows us to use not only databases, but also many other sources of data to generate reports. In this chapter, we will learn how to use datasources other than databases to create our reports. As creating web-based reports is by far the most common use of JasperReports, most examples in this chapter will use the technique described in Chapter 3, Creating your First Report, to stream a PDF report to a web browser through the JasperRunManager.runReportToPdfStream()
method.
By the end of the chapter, we will be able to:
Use empty datasources for reports that don't require an external datasource
Use any implementation of java.util.Map
as a datasource
Use arrays or collections of Java objects as datasources
Use TableModels as datasources
Use XML files as datasources
Use CSV files as datasources
Create our own custom datasources
All the JasperReports datasources implement the net.sf.jasperreports.engine.JRDataSource
interface...
The first type of datasources that we will discuss in this chapter are empty datasources. There is no way to create a report without using either a database connection or a datasource. If we need to create simple reports that require no external datasources, we can use an empty datasource to accomplish this. JasperReports provides the net.sf.jasperreports.engine.JREmptyDataSource
that we can use for these situations. Let's create a simple report template containing only static data to illustrate this process.
JasperReports allows us to use instances of any class implementing the java.util.Map
interface as a datasource. We can use either an array or a collection of Map
objects to generate a report. Each Map
in the collection or array is a record that will be used to generate the data for each row in the detail area of the report. The JasperReports API provides an implementation of net.sf.jasperreports.engine.JRDataSource
called net.sf.jasperreports.engine.data.JRMapArrayDataSource
that we can use for using an array of Map
objects as a datasource. The following example demonstrates this class in action:
Java objects as datasources
In addition to databases and maps, JasperReports allows us to use Plain Old Java Objects (POJOs) as datasources. We can use any Java object that adheres to the JavaBeans specification as a datasource. The only requirement for an object to adhere to the JavaBeans specification is that it must have no public properties, it must have a no-argument constructor, and it must provide getter and setter methods to access its private and protected properties. Let's create a Java object to be used as a datasource for our next example:
TableModels as datasources
In many client-side applications, data is displayed in tabular format. A common requirement in many applications is to allow the user to print this tabular format as a report.
JasperReports provides an implementation of the JRDataSource
interface that makes the task of generating reports from tabular format trivial for Swing applications. The class in question is net.sf.jasperreports.engine.data.JRTableModelDataSource
. This class takes a javax.swing.table.TableModel
as its only parameter. Because tables in Swing are populated through TableModels, all we need to do for generating a report from a table is to pass the appropriate table's TableModel
as a parameter. The following example is a simple but complete Swing application demonstrating this process:
JasperReports allows us to use any well formatted XML document as a datasource. JasperReports uses XPath expressions to traverse the XML documents and extract the data for the report.
Note
XPath is a language used to navigate through an XML document's attributes and elements. More information about XPath can be found at http://www.w3.org/TR/xpath.
For our next example, we'll need an XML file from which we'll read the data. The following XML document will serve this purpose:
JasperReports allows us to use Comma Separated Value(CSV) files as sources of data for our reports.
We will use the following CSV file to provide data for our report:
tail_num,aircraft_serial,aircraft_model,engine_model
N263Y,T-11,39 ROSCOE TRNR RACER,R1830 SERIES
N4087X,BA100-163,BRADLEY AEROBAT,R2800 SERIES
N43JE,HAYABUSA 1,NAKAJIMA KI-43 IIIA,R1830 SERIES
N912S,9973CC,PA18-150,R-1820 SER
The JRDataSource
implementation we need to use to create reports from CSV files is called net.sf.jasperreports.engine.data.JRCsvDataSource
. The following example demonstrates how to use it:
So far we've seen all of the JRDataSource
implementations provided by JasperReports. If we need to extract data from a type of datasource not directly supported by JasperReports, we can create a class implementing JRDataSource
to meet our needs. In this section, we will create a custom datasource allowing us to generate reports from an instance of java.util.List
containing arrays of strings as its elements.
Writing a custom JRDataSource implementation
In our previous examples, all JasperReports datasources implement the JRDataSource
interface. JasperReports also includes the net.sf.jasperreports.engine.JRRewindableDataSource
interface. This interface extends JRDatasource
, adding a single method called moveFirst()
. The moveFirst()
method is intended to move the cursor to the first element in the datasource. Our custom datasource will implement JRRewindableDataSource
. Let's take a look at the source of the custom datasource class.
This chapter has given us a quick run through all the non-database datasources supported by JasperReports, including how to create our own.
We have created reports that use no external datasources by using an empty datasource. We also used instances of a class implementing java.util.Map
as a datasource by taking advantage of the net.sf.jasperreports.engine.data.JRMapArrayDataSource
class. We learned to use plain Java objects as datasources by employing the net.sf.jasperreports.engine.JRBeanArrayDataSource
and net.sf.jasperreports.engine.JRBeanCollectionDataSource
classes. Besides, we also saw the use of a Swing TableModel
and an XML document as a datasource by implementing the net.sf.jasperreports.engine.data
. JRTableModelDataSource
and net.sf.jasperreports.engine.data.JRXmlDataSource
classes respectively. We also saw how CSV files can be used as datasources for our reports by taking advantage of the net.sf.jasperreports.engine.data.JRCsvDataSource
class.
We have covered not only...