Ebooks

JasperReports conditional style tutorial

In this tutorial, we use conditional styling in JasperReports library. Conditional styles can be set with conditionalStyle and conditionExpression tags.

JasperReports is an open-source reporting library. It can create reports in various formats including PDF, HTML, XLS, or CSV. JasperReports creates page-oriented, ready-to-print documents.

JasperReports conditional style example

The following application uses a gray background colour for every second row in the report.

pom.xml
src
└── main
    ├── java
    │   └── com
    │       └── zetcode
    │           ├── model
    │           │   └── Car.java
    │           └── main
    │               ├── CommandLineRunner.java
    │               └── JasperConditionalStyleEx.java
    └── resources
        └── report2.xml

This is the project structure.

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>org.example</groupId>
    <artifactId>JasperConditionalStyle2</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
        <exec.mainClass>com.zetcode.main.CommandLineRunner</exec.mainClass>
    </properties>

    <dependencies>

        <dependency>
            <groupId>net.sf.jasperreports</groupId>
            <artifactId>jasperreports</artifactId>
            <version>6.9.0</version>
        </dependency>

    </dependencies>

</project>

The Maven pom.xml file contains the jasperreports dependency.

com/zetcode/model/Car.java
package com.zetcode.model;

public class Car {

    private Long id;
    private String name;
    private int price;

    public Car() {}

    public Car(Long id, String name, int price) {
        this.id = id;
        this.name = name;
        this.price = price;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "Car{" + "id=" + id + ", name=" +
                name + ", price=" + price + '}';
    }
}

This is a Car bean class. It contains car id, name, and price attributes.

src/resources/report2.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="report2" topMargin="20" bottomMargin="20">

    <style name="alt">
        <conditionalStyle>
            <conditionExpression>
                <![CDATA[$V{COLUMN_COUNT} % 2 == 0]]>
            </conditionExpression>

            <style backcolor="#eff0f2" />
        </conditionalStyle>
    </style>

    <style name="row" vAlign="Middle" />

    <field name="Id" class="java.lang.Long">
        <fieldDescription><![CDATA[id]]></fieldDescription>
    </field>

    <field name="Name">
        <fieldDescription><![CDATA[name]]></fieldDescription>
    </field>

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

    <detail>
        <band height="20">

            <staticText>
                <reportElement mode="Opaque" x="0" y="0" width="260"
                               height="16" style="alt"/>
                <textElement />
                <text><![CDATA[]]> </text>
            </staticText>

            <textField>
                <reportElement x="10" y="0" width="80" height="16" style="row" />
                <textElement />
                <textFieldExpression class="java.lang.Long"><![CDATA[$F{Id}]]></textFieldExpression>
            </textField>

            <textField>
                <reportElement x="60" y="0" width="80" height="16" style="row" />
                <textElement />
                <textFieldExpression class="java.lang.String"><![CDATA[$F{Name}]]></textFieldExpression>
            </textField>

            <textField>
                <reportElement x="170" y="0" width="80" height="16" style="row" />
                <textElement textAlignment="Right"/>
                <textFieldExpression class="java.lang.Integer"><![CDATA[$F{Price}]]></textFieldExpression>
            </textField>

        </band>
    </detail>

</jasperReport>

This is the report template file. The report contains three columns.

<style name="alt">
    <conditionalStyle>
        <conditionExpression>
            <![CDATA[$V{COLUMN_COUNT} % 2 == 0]]>
        </conditionExpression>

        <style backcolor="#eff0f2" />
    </conditionalStyle>
</style>

The conditionalStyle and conditionExpression tags are used to define a conditional style. The $V{COLUMN_COUNT} % 2 == 0 expression applies the style on every second row. The COLUMN_COUNT is a built-in variable referring to the current row being processed by JasperReports. (The name of the variable is misleading.)

<staticText>
    <reportElement mode="Opaque" x="0" y="0" width="260"
                   height="16" style="alt"/>
    <textElement />
    <text><![CDATA[]]> </text>
</staticText>

The style is specified with the style attribute of the reportElement; the element must be opaque.

<field name="Name"">
    <fieldDescription><![CDATA[name]]></fieldDescription>
</field>

The name attribute of the car bean is mapped to the Name field.

<textField>
    <reportElement x="60" y="0" width="80" height="16" style="row" />
    <textElement />
    <textFieldExpression class="java.lang.String"><![CDATA[$F{Name}]]></textFieldExpression>
</textField>

The value of the Name field is shown in the textField using the $F{} syntax.

com/zetcode/main/JasperConditionalStyleEx.java
package com.zetcode.main;

import com.zetcode.model.Car;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;

import java.util.ArrayList;
import java.util.HashMap;

public class JasperConditionalStyleEx {

    public void start() throws JRException {

        var xmlFile = "src/main/resources/report2.xml";
        var jreport = JasperCompileManager.compileReport(xmlFile);

        var params = new HashMap<String, Object>();
        var jprint = JasperFillManager.fillReport(jreport,
                params, createDataSource());

        JasperExportManager.exportReportToPdfFile(jprint,
                "src/main/resources/report2.pdf");
    }

    private JRBeanCollectionDataSource createDataSource() {

        var cars = new ArrayList<Car>();

        cars.add(new Car(1L, "Audi", 52642));
        cars.add(new Car(2L, "Mercedes", 57127));
        cars.add(new Car(3L, "Skoda", 9000));
        cars.add(new Car(4L, "Volvo", 29000));
        cars.add(new Car(5L, "Bentley", 350000));
        cars.add(new Car(6L, "Citroen", 21000));
        cars.add(new Car(7L, "Hummer", 41400));
        cars.add(new Car(8L, "Volkswagen", 21600));

        var ds = new JRBeanCollectionDataSource(cars);

        return ds;
    }
}

The JasperConditionalStyleEx creates a JasperPrint file from the data source and the report2.xml template. JasperPrint represents a page-oriented document that can be viewed, printed, or exported to other formats.

var xmlFile = "src/main/resources/report2.xml";
var jreport = JasperCompileManager.compileReport(xmlFile);

The XML template file is compiled into a JasperReport. JasperReport is a compiled template ready to be filled with data.

var cars = new ArrayList<Car>();

cars.add(new Car(1L, "Audi", 52642));
cars.add(new Car(2L, "Mercedes", 57127));
cars.add(new Car(3L, "Skoda", 9000));
...

This is a list of car objects.

var ds = new JRBeanCollectionDataSource(cars);

The data source is a JRBeanCollectionDataSource.

var params = new HashMap<String, Object>();
var jprint = JasperFillManager.fillReport(jreport,
        params, createDataSource());

A JasperPrint object is created; an object that can be viewed, printed, or exported to other formats. We pass the data source to the JasperFillManager.fillReport() method. There are no parameters.

JasperExportManager.exportReportToPdfFile(jprint,
        "src/main/resources/report2.pdf");

The JasperExportManager.exportReportToPdfFile() method exports the JasperPrint into a PDF file.

com/zetcode/main/CommandLineRunner.java
package com.zetcode.main;

public class CommandLineRunner {

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

        var app = new JasperConditionalStyleEx();
        app.start();
    }
}

The CommandLineRunner sets up the application.

$ mvn exec:java

We run the application.

In this tutorial, we have applied conditional styling on a report. List all JasperReports tutorials.