Using JasperReports' JRViewer to display report

In this tutorial, we show how display a report created with JasperReports library with JRViewer component.

JasperReports is a open-source reporting library. It can create reports in various formats including PDF, HTML, XLS, or CSV. JRViewer is a component used in Swing-based applications to view the reports generated by JasperReports.

The following application loads data from a bean collection data source and creates a report from it with JasperReports library. The report is displayed in a small Swing application with the help of the JRViewer component.

$ tree
.
├── pom.xml
└── src
    ├── main
    │   ├── java
    │   │   └── com
    │   │       └── zetcode
    │   │           ├── bean
    │   │           │   └── Country.java
    │   │           └── main
    │   │               ├── GuiRunner.java
    │   │               └── PrintFileGenerator.java
    │   └── resources
    │       └── jasper-beans.xml
    └── test
        └── java

This is the project structure.

Country.java
package com.zetcode.bean;

public class Country {

    private String name;
    private int population;

    public Country(String name, int population) {
        this.name = name;
        this.population = population;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getPopulation() {
        return population;
    }

    public void setPopulation(int population) {
        this.population = population;
    }
}

This is a bean class. It contains country name and population attributes.

pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" 
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
                             http://maven.apache.org/xsd/maven-4.0.0.xsd">
    
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.zetcode</groupId>
    <artifactId>JasperViewer</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
    
    <dependencies>
        
        <dependency>
            <groupId>net.sf.jasperreports</groupId>
            <artifactId>jasperreports</artifactId>
            <version>6.4.0</version>
        </dependency>
        
    </dependencies>    
    
</project>

The Maven pom.xml file contains the jasperreports dependency.

jasper-beans.xml
<?xml version = "1.0" encoding = "UTF-8"?>
<!DOCTYPE jasperReport PUBLIC "//JasperReports//DTD Report Design//EN"
   "http://jasperreports.sourceforge.net/dtds/jasperreport.dtd">

<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports
                      http://jasperreports.sourceforge.net/xsd/jasperreport.xsd"
              name="jasper-beans" pageWidth="595" pageHeight="842" 
              columnWidth="555" leftMargin="20" rightMargin="20"
              topMargin="20" bottomMargin="20">
  
    <style name="boldtext" isBold="true"/>
    <style name="background1" mode="Opaque" backcolor="#8DCCE0"/>
    <style name="background2" mode="Opaque" backcolor="#E5ECF9"/>
   
    <field name="CountryName" class="java.lang.String">
        <fieldDescription><![CDATA[name]]></fieldDescription>
    </field>

    <field name="Population" class="java.lang.Integer">
        <fieldDescription><![CDATA[population]]></fieldDescription>
    </field>

    <columnHeader>
        <band height="20">
         
            <staticText>
                <reportElement x="0" y="3" width="300" height="15" style="background1"/>
            
                <box>
                    <bottomPen lineWidth="1.0" lineColor="#CCCCCC"/>
                </box>
            
                <textElement />
                <text><![CDATA[]]></text>
            </staticText>

            <staticText>
                <reportElement x="15" y="5" width="130" height="15" style="boldtext"/>
            
                <textElement textAlignment="Left"/>
            
                <text><![CDATA[Country]]></text>
            </staticText>
         
            <staticText>
                <reportElement x="150" y="5" width="130" height="15" style="boldtext"/>
            
                <textElement textAlignment="Right"/>
            
                <text><![CDATA[Population]]></text>
            </staticText>
  
        </band>
    </columnHeader>
 
    <detail>
        <band height="15">
         
            <staticText>
                <reportElement x="0" y="0" width="300" height="14" style="background2"/>
            
                <box>
                    <bottomPen lineWidth="0.5" lineColor="#CCCCCC"/>
                </box>
            
                <textElement />
                <text><![CDATA[]]> </text>
            </staticText>

            <textField>
                <reportElement x="15" y="0" width="130" height="15"/>
            
                <textElement textAlignment="Left" verticalAlignment="Middle"/>
            
                <textFieldExpression class = "java.lang.String">
                    <![CDATA[$F{CountryName}]]>
                </textFieldExpression>
            </textField>
         
            <textField>
                <reportElement x="150" y="0" width="130" height="15"/>
                <textElement textAlignment="Right" verticalAlignment="Middle"/>
            
                <textFieldExpression class="java.lang.Integer">
                    <![CDATA[$F{Population}]]>
                </textFieldExpression>
            </textField>

        </band>
    </detail>

</jasperReport>

This is the report template file. The template contains two bands: columnHeader and detail.

<style name="boldtext" isBold="true"/>
<style name="background1" mode="Opaque" backcolor="#8DCCE0"/>
<style name="background2" mode="Opaque" backcolor="#E5ECF9"/>

There are three styles used in the template. Styles create modularity and reduce repetition in code.

<field name="CountryName" class="java.lang.String">
    <fieldDescription><![CDATA[name]]></fieldDescription>
</field>

<field name="Population" class="java.lang.Integer">
    <fieldDescription><![CDATA[population]]></fieldDescription>
</field>

There are two fields in the template. Fields are mapped to the elements of the data source. In our case, fields are mapped to the attributes of the beans. (We are using JRBeanCollectionDataSource.)

<staticText>
    <reportElement x="15" y="5" width="130" height="15" style="boldtext"/>

    <textElement textAlignment="Left"/>

    <text><![CDATA[Country]]></text>
</staticText>

<staticText> is used to display labels in the report. This static text shows a column header.

<textField>
    <reportElement x="15" y="0" width="130" height="15"/>

    <textElement textAlignment="Left" verticalAlignment="Middle"/>

    <textFieldExpression class = "java.lang.String">
        <![CDATA[$F{CountryName}]]>
    </textFieldExpression>
</textField>

A text field is an element which contains an associated expression that is evaluated with every iteration in the data source to obtain the text content to be displayed. This text field displays country names. A text field in a detail band is evaluated for each record in the data source. Since we have seven beans in our JRBeanCollectionDataSource, the text field is evaluated seven times.

PrintFileGenerator.java
package com.zetcode.main;

import com.zetcode.bean.Country;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;

public class PrintFileGenerator {

    public static JasperPrint generate() throws JRException {

        String xmlFile = "src/main/resources/jasper-beans.xml";

        JasperReport jreport = JasperCompileManager.compileReport(xmlFile);

        JRBeanCollectionDataSource beanColDataSource
                = new JRBeanCollectionDataSource(getBeans());

        Map params = new HashMap();

        JasperPrint jrprint = JasperFillManager.fillReport(jreport,
                params, beanColDataSource);
        
        return jrprint;
    }

    private static ArrayList<Country> getBeans() {
        
        ArrayList<Country> beans = new ArrayList<>();
           
        beans.add(new Country("China", 1382050000));
        beans.add(new Country("India", 1313210000));
        beans.add(new Country("USA", 324666000));
        beans.add(new Country("Indonesia", 260581000));
        beans.add(new Country("Brazil", 207221000));
        beans.add(new Country("Pakistan", 196626000));
        beans.add(new Country("Nigeria", 186988000));        
        
        return beans;
    }
}

The PrintFileGenerator creates a JasperPrint file from the data source. JasperPrint represents a page-oriented document that can be viewed, printed, or exported to other formats. In our case, it is going to be viewed with JRViewer.

String xmlFile = "src/main/resources/jasper-beans.xml";

JasperReport jreport = JasperCompileManager.compileReport(xmlFile);

We compile the XML template file into a JasperReport. JasperReport is a compiled template ready to be filled with data.

JRBeanCollectionDataSource beanColDataSource
        = new JRBeanCollectionDataSource(getBeans());

JRBeanCollectionDataSource is a data source implementation that wraps a collection of Java bean objects. We put seven Country beans into the data source.

JasperPrint jrprint = JasperFillManager.fillReport(jreport,
        params, beanColDataSource);

With the JasperFillManager.fillReport() method, we create a JasperPrint object; an object that can be viewed, printed or exported to other formats.

return jrprint;

The JasperPrint is returned to the caller.

GuiRunner.java
package com.zetcode.main;

import java.awt.Dimension;
import javax.swing.JFrame;
import net.sf.jasperreports.swing.JRViewer;

public class GuiRunner {

    public static void main(String[] args) throws Exception {

        JFrame frame = new JFrame("Jasper report");

        JRViewer viewer = new JRViewer(PrintFileGenerator.generate());
        
        frame.add(viewer);
        frame.setSize(new Dimension(500, 400));
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
}

The GuiRunner sets up a Java Swing application that displays our report.

JRViewer viewer = new JRViewer(PrintFileGenerator.generate());

We pass the generated JasperPrint to the JRViewer.

frame.add(viewer);

the JRViewer is added to the frame.

Countries
Figure: Countries

The screenshot shows the Jasper viewer displaying the report.

In this tutorial, we have created a report with JasperReports library and displayed it in a Swing application with JRViewer. You might also be interested in these related tutorials: Creating a report with JapserReports API, Creating a table with JasperReports library, Creating a report from CSV with JasperReports, and Java tutorial.