ZetCode

JasperReports group

last modified February 12, 2024

A group in JasperReports helps to build structure in our data. It is defined by an expression containing fields and variables that define the criteria for inclusion in that group.

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.

A report group has three elements:

The header and/or footer is optional.

These are the group attributes:

JasperReports group data example

The example divides cars into two groups: automatic and manual transmissions. For correct output, the data must be sorted. When we create a new group, a new GROUPNAME_COUNT variable is created; in our case am_group_COUNT.

cars.csv
"name","mpg","cyl","disp","hp","drat","wt","qsec","vs","am","gear","carb"
"Mazda RX4",21,6,160,110,3.9,2.62,16.46,0,1,4,4
"Mazda RX4 Wag",21,6,160,110,3.9,2.875,17.02,0,1,4,4
"Datsun 710",22.8,4,108,93,3.85,2.32,18.61,1,1,4,1
"Hornet 4 Drive",21.4,6,258,110,3.08,3.215,19.44,1,0,3,1
"Hornet Sportabout",18.7,8,360,175,3.15,3.44,17.02,0,0,3,2
"Valiant",18.1,6,225,105,2.76,3.46,20.22,1,0,3,1
"Duster 360",14.3,8,360,245,3.21,3.57,15.84,0,0,3,4
"Merc 240D",24.4,4,146.7,62,3.69,3.19,20,1,0,4,2
"Merc 230",22.8,4,140.8,95,3.92,3.15,22.9,1,0,4,2
"Merc 280",19.2,6,167.6,123,3.92,3.44,18.3,1,0,4,4
"Merc 280C",17.8,6,167.6,123,3.92,3.44,18.9,1,0,4,4
"Merc 450SE",16.4,8,275.8,180,3.07,4.07,17.4,0,0,3,3
"Merc 450SL",17.3,8,275.8,180,3.07,3.73,17.6,0,0,3,3
"Merc 450SLC",15.2,8,275.8,180,3.07,3.78,18,0,0,3,3
"Cadillac Fleetwood",10.4,8,472,205,2.93,5.25,17.98,0,0,3,4
"Lincoln Continental",10.4,8,460,215,3,5.424,17.82,0,0,3,4
"Chrysler Imperial",14.7,8,440,230,3.23,5.345,17.42,0,0,3,4
"Fiat 128",32.4,4,78.7,66,4.08,2.2,19.47,1,1,4,1
"Honda Civic",30.4,4,75.7,52,4.93,1.615,18.52,1,1,4,2
"Toyota Corolla",33.9,4,71.1,65,4.22,1.835,19.9,1,1,4,1
"Toyota Corona",21.5,4,120.1,97,3.7,2.465,20.01,1,0,3,1
"Dodge Challenger",15.5,8,318,150,2.76,3.52,16.87,0,0,3,2
"AMC Javelin",15.2,8,304,150,3.15,3.435,17.3,0,0,3,2
"Camaro Z28",13.3,8,350,245,3.73,3.84,15.41,0,0,3,4
"Pontiac Firebird",19.2,8,400,175,3.08,3.845,17.05,0,0,3,2
"Fiat X1-9",27.3,4,79,66,4.08,1.935,18.9,1,1,4,1
"Porsche 914-2",26,4,120.3,91,4.43,2.14,16.7,0,1,5,2
"Lotus Europa",30.4,4,95.1,113,3.77,1.513,16.9,1,1,5,2
"Ford Pantera L",15.8,8,351,264,4.22,3.17,14.5,0,1,5,4
"Ferrari Dino",19.7,6,145,175,3.62,2.77,15.5,0,1,5,6
"Maserati Bora",15,8,301,335,3.54,3.57,14.6,0,1,5,8
"Volvo 142E",21.4,4,121,109,4.11,2.78,18.6,1,1,4,2

This is the cars.csv file.

These are the column names descriptions:

report.xml
<?xml version="1.0" encoding="UTF-8"?>
<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="report" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20"
    topMargin="20" bottomMargin="20">

    <field name="name" class="java.lang.String"/>
    <field name="mpg" class="java.lang.Double"/>
    <field name="cyl" class="java.lang.Integer"/>
    <field name="disp" class="java.lang.Double"/>
    <field name="hp" class="java.lang.Integer"/>
    <field name="drat" class="java.lang.Double"/>
    <field name="wt" class="java.lang.Double"/>
    <field name="qsec" class="java.lang.Double"/>
    <field name="vs" class="java.lang.Integer"/>
    <field name="am" class="java.lang.Integer"/>
    <field name="gear" class="java.lang.Integer"/>
    <field name="carb" class="java.lang.Integer"/>
    <sortField name="am"/>

    <group name="am_group" isStartNewPage="true" isReprintHeaderOnEachPage="true">

        <groupExpression><![CDATA[$F{am}]]></groupExpression>
        <groupHeader>
            <band height="42">

                <textField>
                    <reportElement x="0" y="5" width="100" height="30"/>
                    <textElement>
                        <font isBold="true"/>
                    </textElement>
                    <textFieldExpression><![CDATA[ $F{am} == 0 ? "Automatic" : "Manual" ]]></textFieldExpression>
                </textField>

                <line direction="BottomUp">
                    <reportElement x="0" y="21" width="569" height="1">
                        <printWhenExpression><![CDATA[$V{COLUMN_COUNT} == $V{am_group_COUNT}]]></printWhenExpression>
                    </reportElement>
                </line>
            </band>
        </groupHeader>

        <groupFooter>
            <band height="52">
                <textField>
                    <reportElement x="0" y="11" width="100" height="30"/>
                    <textElement>
                        <font isBold="true"/>
                    </textElement>
                    <textFieldExpression><![CDATA[$V{am_group_COUNT}]]></textFieldExpression>
                </textField>
            </band>
        </groupFooter>

    </group>

    <columnHeader>
        <band height="44" splitType="Stretch">
            <staticText>
                <reportElement x="0" y="0" width="49" height="30"/>
                <text><![CDATA[name]]></text>
            </staticText>
            <staticText>
                <reportElement x="58" y="0" width="40" height="30"/>
                <text><![CDATA[mpg]]></text>
            </staticText>
            <staticText>
                <reportElement x="104" y="0" width="46" height="30"/>
                <text><![CDATA[cyl]]></text>
            </staticText>
            <staticText>
                <reportElement x="150" y="0" width="38" height="30"/>
                <text><![CDATA[disp]]></text>
            </staticText>
            <staticText>
                <reportElement x="198" y="0" width="46" height="30"/>
                <text><![CDATA[hp]]></text>
            </staticText>
            <staticText>
                <reportElement x="244" y="0" width="46" height="30"/>
                <text><![CDATA[drat]]></text>
            </staticText>
            <staticText>
                <reportElement x="290" y="0" width="46" height="30"/>
                <text><![CDATA[wt]]></text>
            </staticText>
            <staticText>
                <reportElement x="340" y="0" width="64" height="30"/>
                <text><![CDATA[qsec]]></text>
            </staticText>
            <staticText>
                <reportElement x="410" y="0" width="20" height="30"/>
                <text><![CDATA[vs]]></text>
            </staticText>
            <staticText>
                <reportElement x="450" y="0" width="26" height="30"/>
                <text><![CDATA[am]]></text>
            </staticText>
            <staticText>
                <reportElement x="490" y="0" width="32" height="30"/>
                <text><![CDATA[gear]]></text>
            </staticText>
            <staticText>
                <reportElement x="530" y="0" width="38" height="30"/>
                <text><![CDATA[carb]]></text>
            </staticText>
        </band>
    </columnHeader>

    <detail>
        <band height="49" splitType="Stretch">
            <textField>
                <reportElement x="0" y="0" width="49" height="30"/>
                <textFieldExpression><![CDATA[$F{name}]]></textFieldExpression>
            </textField>
            <textField>
                <reportElement x="58" y="0" width="46" height="30"/>
                <textFieldExpression><![CDATA[$F{mpg}]]></textFieldExpression>
            </textField>
            <textField>
                <reportElement x="104" y="0" width="46" height="30"/>
                <textFieldExpression><![CDATA[$F{cyl}]]></textFieldExpression>
            </textField>
            <textField>
                <reportElement x="150" y="0" width="38" height="30"/>
                <textFieldExpression><![CDATA[$F{disp}]]></textFieldExpression>
            </textField>
            <textField>
                <reportElement x="198" y="0" width="46" height="30"/>
                <textFieldExpression><![CDATA[$F{hp}]]></textFieldExpression>
            </textField>
            <textField>
                <reportElement x="244" y="0" width="46" height="30"/>
                <textFieldExpression><![CDATA[$F{drat}]]></textFieldExpression>
            </textField>
            <textField>
                <reportElement x="290" y="0" width="46" height="30"/>
                <textFieldExpression><![CDATA[$F{wt}]]></textFieldExpression>
            </textField>
            <textField>
                <reportElement x="340" y="0" width="64" height="30"/>
                <textFieldExpression><![CDATA[$F{qsec}]]></textFieldExpression>
            </textField>
            <textField>
                <reportElement x="410" y="0" width="20" height="30"/>
                <textFieldExpression><![CDATA[$F{vs}]]></textFieldExpression>
            </textField>
            <textField>
                <reportElement x="450" y="0" width="26" height="30"/>
                <textFieldExpression><![CDATA[$F{am}]]></textFieldExpression>
            </textField>
            <textField>
                <reportElement x="490" y="0" width="32" height="30"/>
                <textFieldExpression><![CDATA[$F{gear}]]></textFieldExpression>
            </textField>
            <textField>
                <reportElement x="530" y="0" width="38" height="30"/>
                <textFieldExpression><![CDATA[$F{carb}]]></textFieldExpression>
            </textField>
        </band>
    </detail>

</jasperReport>

This is the report template file.

<group name="am_group" isStartNewPage="true" isReprintHeaderOnEachPage="true"&gr;

The am_group group is defined.

<groupExpression><![CDATA[$F{am}]]></groupExpression>

The data is separated by the $F{am} field into two groups.

<textField>
    <reportElement x="0" y="5" width="100" height="30"/>
    <textElement>
        <font isBold="true"/>
    </textElement>
    <textFieldExpression><![CDATA[ $F{am} == 0 ? "Automatic" : "Manual" ]]></textFieldExpression>
</textField>

<line direction="BottomUp">
    <reportElement x="0" y="21" width="569" height="1">
        <printWhenExpression><![CDATA[$V{COLUMN_COUNT} == $V{am_group_COUNT}]]></printWhenExpression>
    </reportElement>
</line>

In the group header, we have the description and a horizontal line. The line is displayed only when a new group is started; i.e. twice.

<textField>
    <reportElement x="0" y="11" width="100" height="30"/>
    <textElement>
        <font isBold="true"/>
    </textElement>
    <textFieldExpression><![CDATA[$V{am_group_COUNT}]]></textFieldExpression>
</textField>

In the group footer, we display the number of items in that particular group. We utilize the am_group_COUNT variable.

report.gvy
@Grab(group='net.sf.jasperreports', module='jasperreports', version='6.21.0')
@Grab(group='com.github.librepdf', module='openpdf', version='1.3.39')

import net.sf.jasperreports.engine.JasperCompileManager
import net.sf.jasperreports.engine.JasperFillManager
import net.sf.jasperreports.engine.JasperExportManager
import net.sf.jasperreports.engine.data.JRCsvDataSource

def xmlFile = "report.xml"
def jrReport = JasperCompileManager.compileReport(xmlFile)

def fileName = "cars.csv"
def ds = new JRCsvDataSource(fileName)
ds.setUseFirstRowAsHeader(true)

def params = [:]
def jrPrint = JasperFillManager.fillReport(jrReport, params, ds)

JasperExportManager.exportReportToPdfFile(jrPrint, "report.pdf")

We load the data from the CSV file using JRCsvDataSource.

ds.setUseFirstRowAsHeader(true)

With setUseFirstRowAsHeader we tell JasperReports that the first line of the CSV file are headers.

In this article we have created a PDF file report with grouped data.

Author

My name is Jan Bodnar and I am a passionate programmer with many years of programming experience. I have been writing programming articles since 2007. So far, I have written over 1400 articles and 8 e-books. I have over eight years of experience in teaching programming.

List all JasperReports tutorials.