Using Java to create a report with the JasperReport java API

In this blog I will describe how to create a Report with JasperReport in Java. For this purpose I have used the Communitie edition of iReport. This edition contains besides JasperReport also iReport. iReport is a report designer for JasperReport. You can download it from http://jasperforge.org/projects/ireport

After installation I started iReport to design a report. I have design a report to create CD booklets. It contains the name of the artist, an album title, an image, the tracklist and the lyrics of these tracks.

Using Java to create a report with the JasperReport java API CDBooklet design

JasperReport designs are files stored in XML format. The XML tab of iReport show the content of this file.

Using Java to create a report with the JasperReport java API CDBooklet design

 

Now I will come into some more details about the structure of this XML file.
The toplevel tag of this file is ‘JasperReport’. On the next level the detail tags are set:

  • Properties and style like default font, font size, etc.
  • The queryString (important: this is the report entry point)
  • Report background
  • Report title and image
  • Reported fields, positioning, layout, etc.

 

I have created a small program that uses the JasperReport java API to create a CD booklet report and store it as a PDF file on the local file system. The remaining part of this blog explains some code snippets.

To use the JasperReport API for this program the following imports are required:

  • import net.sf.jasperreports.engine.JasperCompileManager;
  • import net.sf.jasperreports.engine.JasperExportManager;
  • import net.sf.jasperreports.engine.JasperFillManager;
  • import net.sf.jasperreports.engine.JasperPrint;
  • import net.sf.jasperreports.engine.JasperReport;
  • import net.sf.jasperreports.engine.design.JasperDesign;
  • import net.sf.jasperreports.engine.xml.JRXmlLoader;
  • import net.sf.jasperreports.engine.JRException;
  • import net.sf.jasperreports.engine.data.JRXmlDataSource;

 

First I created a report request and response type. The request contains the report (template) name, the location of this template, output filename, output location and the xml input datastream (as string). The response also contains the output filename and location. Besides that it contains the output content type and size and finally the report output in base64Binary format.

A Request example:

RunReportRequestType request = new RunReportRequestType();
request.setRapportLocatie("D:\\CDbooklet\\createBooklet\\src\\");
request.setRapportNaam("CDBooklet.jrxml");
request.setOutputLocatie("D:\\CDbooklet\\createBooklet\\src\\");
request.setOutputNaam("CDBooklet.pdf");
request.setXmlData("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<version/>\n" +
"<CDBooklets>\n" +
" <Artist>\n" +
" <ArtistID>1</ArtistID>\n" +
" <ArtistName>Queen</ArtistName>\n" +
" <AlbumID>1</AlbumID>\n" +
" <AlbumTitle> A Night at the Opera</AlbumTitle>\n" +
" <AlbumImage>D:/workspace/queen.jpg</AlbumImage>\n" +
" </Artist>\n" +
" <Track>\n" +
" <TrackID>1</TrackID>\n" +
" <TrackTitle>Bohemian Rhapsody</TrackTitle>\n" +
" <Duration>6.15</Duration>\n" +
" <ArtistID>1</ArtistID>\n" +
" <AlbumID>1</AlbumID>\n" +
" </Track>\n" +
" <Track>\n" +
" <TrackID>2</TrackID>\n" +
" <TrackTitle>Sweet Lady</TrackTitle>\n" +
" <Duration>5.03</Duration>\n" +
" <ArtistID>1</ArtistID>\n" +
" <AlbumID>1</AlbumID>\n" +
" </Track>\n" +
" <Lyric>\n" +
" <TrackID>1</TrackID>\n" +
" <AlbumID>1</AlbumID>\n" +
" <LyricData>\n" +
" Bohemian Rhapsody\n" +
" lyric \n" +
"</LyricData>\n" +
" </Lyric>\n" +
" <Lyric>\n" +
" <TrackID>2</TrackID>\n" +
" <AlbumID>1</AlbumID>\n" +
" <LyricData>\n" +
" Sweet Lady\n" +
" lyric \n" +
"</LyricData>\n" +
" </Lyric>\n" +
"</CDBooklets>\n");

This request is used as the input for the runReport method that does the actual processing. This method contains the following parts:

Create a response object

RunReportResponseType response = new RunReportResponseType();
Read the report design
File file = new File(request.getRapportLocatie() + request.getRapportName());
FileInputStream template = null;
try {
template = new FileInputStream(file);
} catch(FileNotFoundException e) {
System.out.println("File " + file.getAbsolutePath() + " could not be found on filesystem");
} catch(IOException ioe) {
System.out.println("Exception while reading the file" + ioe);
}

Load the report design

JasperDesign design = null;
try {
design = JRXmlLoader.load(template);
} catch (JRException e) {
e.printStackTrace();
}

Compile the design (it is also possible to load the compiled reports directly, but for learning purposes I have chosen to load the template and compile it from here).

JasperReport report = null;

try {
report = JasperCompileManager.compileReport(design);

} catch (JRException e) {
e.printStackTrace();

}

Parse the request XML input stream and convert it into a Document. The JRXmlDataSource method requires two parameters. The first one it the input stream document. The second is the earlier mentioned report entry point. For this report is gets the value ‘/CDBooklets’. For a single level report this is straightforward. In a multi level report (master report with one or more subreports) it becomes a bid more complicated. This because each (sub)reports has it’s own entry point. You have to take care of this in your code. But for now it’s easy:

Document xmlDoc = null;
JRXmlDataSource ds = null;
try {
  xmlDoc = convertStringToDocument(xmlPayload);
  ds = new JRXmlDataSource(xmlDoc,report.getQuery().getText());
} catch (JRException e) {
  e.printStackTrace();
}

Fill the report and create the PDF file.

JasperPrint print = null;
byte[] pdf = null;
try {
  print = JasperFillManager.fillReport(report, null, ds);
  pdf = JasperExportManager.exportReportToPdf(print);
} catch (JRException e) {
  e.printStackTrace();
}

Fill the response object

response.setContentSize(String.valueOf(pdf.length));
response.setContentType("application/pdf");
response.setOutputNaam(request.getOutputNaam());
response.setOutputLocatie(request.getOutputLocatie());
response.setReport(pdf);

Or write the pdf output stream to the filesystem.

OutputStream output = null;
try {
  output = new FileOutputStream(new File(request.getOutputLocatie() + request.getOutputNaam()));
} catch (FileNotFoundException e) {
  e.printStackTrace();
}
try {
  JasperExportManager.exportReportToPdfStream(print, output);
} catch (JRException e) {
  e.printStackTrace();
}

And the final result

Using Java to create a report with the JasperReport java API Rush Roll The Bones 1
Using Java to create a report with the JasperReport java API Rush Roll The Bones 2
Using Java to create a report with the JasperReport java API Rush Roll The Bones 3

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

This brings me to the end of this post.
You can download the source code by clicking on the following link createBooklet

In a next post I wil describe how to use this functionality (as a web-service) from Oracle BPEL.


5 Comments

  1. Antuan March 10, 2014
  2. Jang-Vijay Singh December 27, 2013
  3. Marcel van de Glind February 4, 2012
  4. Renan February 2, 2012