ZetCode

JasperReports conditional style tutorial

last modified July 15, 2020

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.