
Chapter 3. Creating Your First Report
In this chapter, you will create, compile, and preview your first report. At the end of this chapter, you will be able to:
- Create a simple JRXML report template
- Generate Jasper binary report templates by compiling JRXML files
- Preview report templates by using JasperReports custom ANT targets
- Write code that will generate a report from a JasperReport template
- View generated reports in JasperReports' native format using the tools provided by JasperReports
- Generate reports that can be viewed in a web browser
- Identify the JRXML elements corresponding to the different report sections
Creating a JRXML Report Template
The first step when creating a report is to create a JRXML template. As mentioned in Chapter 1, JasperReports JRXML templates are standard XML files. However, by convention, they have an extension of .jrxml
, and are referred to as JRXML files or JRXML templates. All JRXML files contain a<jasperReport>
root element that can contain many sub-elements. All of these sub-elements are optional. Since our goal for this chapter is to get a feel of how to design a report, we will obviate most of the<jasperReport>
sub-elements. We will use only one sub-element, namely the<detail>
sub-element.
Our first report will display a static String. Its JRXML follows:
<?xml version="1.0"?>
<!DOCTYPE jasperReport
PUBLIC "-//JasperReports//DTD Report Design//EN"
"http://jasperreports.sourceforge.net/dtds/jasperreport.dtd">
<jasperReport name="FirstReport">
<detail>
<band height="20">
<staticText> <reportElement x="20" y="0" width="200" height="20"/> <text><! [CDATA[If you don't see this, it didn't work]]></text> </staticText>
</band>
</detail>
</jasperReport>
There are some elements in this JRXML file that we haven't seen before:
We have seen the<band>
element in previous examples. The<detail>
element can contain only a single<band>
element as its only sub-element. The<band>
element can contain many different elements that can be used to display text, charts, images, or geometric figures. In this example, it contains a single<staticText>
element.
Previewing the XML Report Template
JasperReports includes a utility that can be used to preview report designs. This utility makes designing reports much faster, since we can immediately preview a report design without having to compile or fill it.
The utility is a standalone Java application included in the JasperReports JAR file. The class that needs to be executed is net.sf.jasperreports.view.JasperDesignViewer
. The easiest way to execute this class is to use an ANT target, including all the required libraries in the CLASSPATH. This is the approach that is used in the JasperReports samples, included in the project ZIP file, and by us as well. The following ANT build file will launch the JasperDesignViewer to preview our report:
<project name="FirstReport XML Design Preview" default="viewDesignXML" basedir=".">
<description>Previews our First Report XML Design</description>
<property name="file.name" value="FirstReport"/>
<!-- Directory where the JasperReports project file was extracted
needs to be changed to match the local environment -->
<property name="jasper.dir" value="/usr/local/share/java/jasperreports-1.1.0"/>
<property name="classes.dir" value="${jasper.dir}/build/classes"/>
<property name="lib.dir" value="${jasper.dir}/lib"/>
<path id="classpath">
<pathelement location="./"/>
<pathelement location="${classes.dir}"/>
<fileset dir="${lib.dir}">
<include name="**/*.jar"/>
</fileset>
</path>
<target name="viewDesignXML" description="Launches the design viewer to preview the XML report design."> <java classname="net.sf.jasperreports.view.JasperDesignViewer" fork="true"> <arg value="-XML"/> <arg value="-F${file.name}.jrxml"/> <classpath refid="classpath"/> </java> </target>
</project>
This ANT build file must be saved in the same directory as our JRXML file. It is recommended that the JRXML file be saved with the report name as its file name. The report name is defined in the<jasperReport>
root element. In the JRXML file, we chose to use FirstReport
as the report name. Therefore, the recommended file name for this report template is FirstReport.jrxml
.
If we save our ANT build file with the standard name of build.xml
, there is no need to specify the build file name in the command line. The build file, in this example, has one<target>
element named viewDesignXML
. Since this target is the default target, there is no need to specify it in the command line; just typing ant
in the command line will execute the default target and a preview of our report will be displayed.
$ ant Buildfile: previewReportDesignXML.xml viewDesignXML:
After executing the viewDesignXML
target, we should see a window labeled JasperDesignViewer displaying our report template preview.

The JasperDesignViewer can be safely terminated by closing the window or by hitting Ctrl-c in the command-line window.
In this particular case we can see all the text in the preview, since this report contains only static text. For reports displaying data coming from datasources or report parameters, the actual text won't be displayed in the report. Instead, report expressions for obtaining the data are displayed. This is because JasperDesignViewer does not have access to the actual datasource or report parameters.
Creating a Binary Report Template
JRXML files cannot be used directly to generate reports. They need to be compiled into JasperReports' native binary format. Compiled report templates are called Jasper files. There are two ways to compile a JRXML file into a Jasper file. We can either do it programmatically, or we can do it through a custom ANT task provided by JasperReports.
A JRXML template can be compiled into a Jasper file and saved to disk by calling the compileReportToFile()
method on the net.sf.jasperreports.engine.JasperCompileManager
class. There are three overloaded versions of the JasperCompileManager.compileReportToFile()
method, listed below:
JasperCompileManager.compileReportToFile(String sourceFileName)
.JasperCompileManager.compileReportToFile(String sourceFileName, String destFileName)
.JasperCompileManager.compileReportToFile(JasperDesign jasperDesign, String destFileName)
.
The following table illustrates the parameters used in these methods:

The following code fragment demonstrates the use of the JasperCompileManager.compileReportToFile()
method:
package net.ensode.jasperbook; import net.sf.jasperreports.engine.JRException; import net.sf.jasperreports.engine.JasperCompileManager; public class FirstReportCompile { public static void main(String[] args) { try { System.out.println("Compiling report..."); JasperCompileManager.compileReportToFile( "reports/FirstReport.jrxml"); System.out.println("Done!"); } catch (JRException e) { e.printStackTrace(); } } }
After compiling and executing the code, we should see a file called FirstReport.jasper
in the file system. This file is the compiled template in JasperReports' native format. For this example, we chose to use the first version of the JasperCompileManager.compileReportToFile()
method we discussed, since by default the root file name is used for the compiled report, and we did not have an in-memory representation of the JRXML template. If we had wished to use a different root file name for the compiled report template, we should have used the second version of the JasperCompileManager.compileReportToFile()
method and specified the desired file name as the second parameter.
The net.sf.jasperreports.view.JasperDesignViewer
discussed previously can be used to preview compiled report templates as well as JRXML templates. Again the easiest way to execute this utility is to wrap a call to it into an ANT target. Let us add a second ANT target to our build.xml
file. We will call this new target viewDesign
, as it will let us preview the compiled report.
<project name="FirstReport XML Design Preview" default="viewDesignXML" basedir="."> <description>Previews our First Report Design</description> <property name="file.name" value="FirstReport"/> <!-- Directory where the JasperReports project file was extracted, needs to be changed to match the local environment --> <property name="jasper.dir" value="/usr/local/share/java/jasperreports-1.1.0"/> <property name="classes.dir" value="${jasper.dir}/build/classes"/> <property name="lib.dir" value="${jasper.dir}/lib"/> <path id="classpath"> <pathelement location="./"/> <pathelement location="${classes.dir}"/> <fileset dir="${lib.dir}"> <include name="**/*.jar"/> </fileset> </path> <target name="viewDesignXML" description="Launches the design viewer to preview the XML report design."> <java classname="net.sf.jasperreports.view.JasperDesignViewer" fork="true"> <arg value="-XML"/> <arg value="-F${file.name}.jrxml"/> <classpath refid="classpath"/> </java> </target> <target name="viewDesign" description="Launches the design viewer to preview the compiled report design."> <java classname="net.sf.jasperreports.view.JasperDesignViewer" fork="true"> <arg value="-F${file.name}.jasper"/> <classpath refid="classpath"/> </java> </target> </project>
We can invoke the new target from the command line as follows:
ant viewDesign
After invoking the target, we should see a window very similar to the one we saw when previewing the JRXML template.
JasperReports includes a custom ANT task that can be used to compile report templates. Since we don't have to write code to perform the compilation, compiling reports in this manner is very convenient. However, for certain applications we need to compile a report programmatically, for example, in situations where the JRXML file is created at run time. The custom ANT task included by JasperReports is called JRC. It is defined in the net.sf.jasperreports.ant.JRAntCompileTask
class. Let us add a third target to our build.xml
file to invoke the JRC task.
<project name="FirstReport XML Design Preview" default="viewDesignXML" basedir="."> <description>Previews and compiles our First Report</description> <property name="file.name" value="FirstReport"/> <!-- Directory where the JasperReports project file was extracted, needs to be changed to match the local environment --> <property name="jasper.dir" value="/usr/local/share/java/jasperreports-1.1.0"/> <property name="classes.dir" value="${jasper.dir}/build/classes"/> <property name="lib.dir" value="${jasper.dir}/lib"/> <path id="classpath"> <pathelement location="./"/> <pathelement location="${classes.dir}"/> <fileset dir="${lib.dir}"> <include name="**/*.jar"/> </fileset> </path> <target name="viewDesignXML" description="Launches the design viewer to preview the XML report design."> <java classname="net.sf.jasperreports.view.JasperDesignViewer" fork="true"> <arg value="-XML"/> <arg value="-F${file.name}.jrxml"/> <classpath refid="classpath"/> </java> </target> <target name="viewDesign" description="Launches the design viewer to preview the compiled report design."> <java classname="net.sf.jasperreports.view.JasperDesignViewer" fork="true"> <arg value="-F${file.name}.jasper"/> <classpath refid="classpath"/> </java> </target> <target name="compile" description="Compiles the XML report design and produces the .jasper file."> <taskdef name="jrc" classname="net.sf.jasperreports.ant.JRAntCompileTask"> <classpath refid="classpath"/> </taskdef> <jrc destdir="."> <src> <fileset dir="."> <include name="**/*.jrxml"/> </fileset> </src> <classpath refid="classpath"/> </jrc> </target> </project>
The new target can be invoked from the command line as:
ant compile
The compile target produces the following output:
Buildfile: build.xml compile: [jrc] Compiling 1 report design files. [jrc] log4j:WARN No appenders could be found for logger (org.apache.commons.digester.Digester.sax). [jrc] log4j:WARN Please initialize the log4j system properly. [jrc] File : /home/heffel/personal_workspace/JasperBookExamples/ reports/FirstReport.jrxml ... OK. BUILD SUCCESSFUL Total time: 4 seconds
After successful execution of the compile target, we should have a FirstReport.jasper
file in the file system. This file is identical to the one generated programmatically by calling the net.sf.jasperreports.engine.JasperCompileManager.compileReportToFile()
.
As explained in the previous section, we can preview the generated Jasper file by using the JasperDesign utility included by JasperReports. The output will be identical.