ZetCode

JasperReports table

last modified February 12, 2024

In this article we show how to display a table in a report created with JasperReports library.

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 in a simple and flexible manner.

The following application loads data from a bean collection data source and creates a report from it with JasperReports library. The report is a PDF file. The data is shown in a table format.

table.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="report6" pageWidth="595" pageHeight="842" whenNoDataType="AllSectionsNoDetail"
    columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20">

    <style name="TableHeader" vAlign="Middle" hAlign="Center" isBold="true"/>
    <style name="TableCell" hAlign="Center" vAlign="Middle"/>
    <style name="TableFooter" hAlign="Right" vAlign="Middle"/>

    <style name="Table">
        <box>
            <pen lineWidth="0.5"/>
        </box>
    </style>

    <subDataset name="dataset1">
        <field name="item"/>
        <field name="unitPrice" class="java.math.BigDecimal"/>
        <field name="quantity" class="java.lang.Integer"/>

        <variable name="UnitTotalPrice" class="java.math.BigDecimal">
            <variableExpression>
               <![CDATA[$F{unitPrice}.multiply(new BigDecimal($F{quantity}))]]>
            </variableExpression>
        </variable>

        <variable name="TotalPrice" resetType="Report" class="java.math.BigDecimal" calculation="Sum">
            <variableExpression><![CDATA[$V{UnitTotalPrice}]]></variableExpression>
        </variable>

    </subDataset>

    <parameter name="datasource" class="net.sf.jasperreports.engine.data.JRBeanCollectionDataSource"/>

    <detail>

        <band height="250">

            <componentElement>
                <reportElement style="Table" x="0" y="10" width="555" height="150"/>
                <c:table xmlns:c="http://jasperreports.sourceforge.net/jasperreports/components"
                    xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports/components
                    http://jasperreports.sourceforge.net/xsd/components.xsd">

                    <datasetRun subDataset="dataset1">
                        <dataSourceExpression>
                            <![CDATA[$P{datasource}]]>
                        </dataSourceExpression>
                    </datasetRun>

                    <c:column width="60">
                        <c:columnHeader height="30">
                            <box>
                                <pen lineColor="#000000"/>
                                <bottomPen lineWidth="0.5"/>
                            </box>
                            <staticText>
                                <reportElement x="0" y="0" width="60" height="30" style="TableHeader"/>
                                <text><![CDATA[Item]]></text>
                            </staticText>
                        </c:columnHeader>
                        <c:detailCell height="15">
                            <box>
                                <bottomPen lineWidth="0.5"/>
                            </box>
                            <textField isStretchWithOverflow="true">
                                <reportElement x="0" y="0" width="60" height="15" style="TableCell"/>
                                <textFieldExpression>
                                    <![CDATA[$F{item}]]>
                                </textFieldExpression>
                            </textField>
                        </c:detailCell>
                    </c:column>

                    <c:column width="100">
                        <c:columnHeader height="30">
                            <box>
                                <pen lineColor="#000000"/>
                                <leftPen lineWidth="0.5"/>
                                <bottomPen lineWidth="0.5"/>
                            </box>
                            <staticText>
                                <reportElement x="0" y="0" width="90" height="30" style="TableHeader"/>
                                <text><![CDATA[UnitPrice]]></text>
                            </staticText>
                        </c:columnHeader>
                        <c:detailCell height="15">
                            <box>
                                <leftPen lineWidth="0.5"/>
                                <bottomPen lineWidth="0.5"/>
                            </box>
                            <textField>
                                <reportElement x="0" y="0" width="90" height="15" style="TableCell"/>
                                <textFieldExpression>
                                    <![CDATA[$F{unitPrice}]]>
                                </textFieldExpression>
                            </textField>
                        </c:detailCell>
                    </c:column>

                    <c:column width="100">
                        <c:columnHeader height="30">
                            <box>
                                <pen lineColor="#000000"/>
                                <leftPen lineWidth="0.5"/>
                                <bottomPen lineWidth="0.5"/>
                            </box>
                            <staticText>
                                <reportElement x="0" y="0" width="90" height="30" style="TableHeader"/>
                                <text><![CDATA[Quantity]]></text>
                            </staticText>
                        </c:columnHeader>
                        <c:detailCell height="15">
                            <box rightPadding="5">
                                <leftPen lineWidth="0.5"/>
                                <bottomPen lineWidth="0.5"/>
                            </box>
                            <textField>
                                <reportElement x="0" y="0" width="90" height="15"/>
                                <textElement textAlignment="Right" verticalAlignment="Middle"/>
                                <textFieldExpression>
                                  <![CDATA[$F{quantity}]]>
                                </textFieldExpression>
                            </textField>
                        </c:detailCell>
                    </c:column>

                    <c:column width="100">
                        <c:columnHeader height="30">
                            <box>
                                <pen lineColor="#000000"/>
                                <leftPen lineWidth="0.5"/>
                                <bottomPen lineWidth="0.5"/>
                            </box>
                            <staticText>
                                <reportElement x="0" y="0" width="90" height="30" style="TableHeader"/>
                                <text><![CDATA[Total price]]></text>
                            </staticText>
                        </c:columnHeader>
                        <c:columnFooter style="TableFooter" height="15">
                            <box>
                                <pen lineColor="#000000"/>
                                <topPen lineWidth="0.5"/>
                            </box>
                            <textField evaluationTime="Report">
                                <reportElement x="0" y="0" width="90" height="15" style="TableFooter"/>
                                <textFieldExpression>
                                    <![CDATA[$V{TotalPrice}]]>
                                </textFieldExpression>
                            </textField>
                        </c:columnFooter>
                        <c:detailCell height="15">
                            <box rightPadding="5">
                                <leftPen lineWidth="0.5"/>
                                <bottomPen lineWidth="0.5"/>
                            </box>
                            <textField>
                                <reportElement x="0" y="0" width="90" height="15"/>
                                <textElement textAlignment="Right" verticalAlignment="Middle"/>
                                <textFieldExpression>
                                    <![CDATA[$V{UnitTotalPrice}]]>
                                </textFieldExpression>
                            </textField>
                        </c:detailCell>
                    </c:column>

                </c:table>
            </componentElement>
        </band>
    </detail>
</jasperReport>

This is the report template file. The template contains only the detail band. In a detail band, each element is repeated for every record provided by the data source.

Note: Since we work with currency values, we must use the BigDecimal type.
<style name="TableHeader" vAlign="Middle" hAlign="Center" isBold="true"/>
<style name="TableCell"  hAlign="Center" vAlign="Middle"/>
<style name="TableFooter" hAlign="Right" vAlign="Middle"/>

These three styles are used for table header, table footer, and table cell.

<style name="Table">
    <box>
        <pen lineWidth="0.5"/>
    </box>
</style>

This style creates a border around the table.

<subDataset name="dataset1">
    <field name="item"/>
    <field name="unitPrice" class="java.math.BigDecimal"/>
    <field name="quantity" class="java.lang.Integer"/>

    <variable name="UnitTotalPrice" class="java.math.BigDecimal">
        <variableExpression>
           <![CDATA[$F{unitPrice}.multiply(new BigDecimal($F{quantity}))]]>
        </variableExpression>
    </variable>

    <variable name="TotalPrice" resetType="Report" class="java.math.BigDecimal" calculation="Sum">
        <variableExpression><![CDATA[$V{UnitTotalPrice}]]></variableExpression>
    </variable>

</subDataset>

A table will read data from the subDataset element. Inside the element, we have three fields and two variables. The 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.) The variables perform calculations on the fields; they calculate the unit price and the total price in the table.

<parameter name="datasource" class="net.sf.jasperreports.engine.data.JRBeanCollectionDataSource"/>

The parameter defines a datasource. JRBeanCollectionDataSource is a collection of Java beans. The parameter is passed to the report during the filling phase.

<c:table xmlns:c="http://jasperreports.sourceforge.net/jasperreports/components"
    xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports/components
    http://jasperreports.sourceforge.net/xsd/components.xsd">

Table is a component that is specified in the JasperReports components schema.

<datasetRun subDataset="dataset1">
    <dataSourceExpression><![CDATA[$P{datasource}]]></dataSourceExpression>
</datasetRun>

The datasetRun creates an instance of the dataset. In the dataSourceExpression, we pass the datasource parameter.

<c:column width="100">
    <c:columnHeader height="30">
        <box>
            <pen lineColor="#000000"/>
            <leftPen lineWidth="0.5"/>
            <bottomPen lineWidth="0.5"/>
        </box>
        <staticText>
            <reportElement x="0" y="0" width="90" height="30" style="TableHeader"/>
            <text><![CDATA[UnitPrice]]></text>
        </staticText>
    </c:columnHeader>
    <c:detailCell height="15">
        <box>
            <leftPen lineWidth="0.5"/>
            <bottomPen lineWidth="0.5"/>
        </box>
        <textField>
            <reportElement x="0" y="0" width="90" height="15" style="TableCell"/>
            <textFieldExpression>
                <![CDATA[$F{unitPrice}]]>
            </textFieldExpression>
        </textField>
    </c:detailCell>
</c:column>

There are four columns in the table. Each column is defined separately. In this column, we have a column header and a column cell. The header contains the column label and the cell contains the unit price, retrieved from the unitPrice field. The field is referenced with the $F{} syntax. The box elements are used to create lines.

<c:columnFooter style="TableFooter" height="15">
    <box>
        <pen lineColor="#000000"/>
        <topPen lineWidth="0.5"/>
    </box>
    <textField evaluationTime="Report">
        <reportElement x="0" y="0" width="90" height="15" style="TableFooter"/>
        <textFieldExpression>
            <![CDATA[$V{TotalPrice}]]>
        </textFieldExpression>
    </textField>
</c:columnFooter>

In the last fourth column, we have a column footer. It contains the total price of all items of the order. We refer to the variable with the $V{} syntax.

report.gvy
@Grab(group='net.sf.jasperreports', module='jasperreports', version='6.21.0')
@Grab(group='net.sf.jasperreports', module='jasperreports-fonts', 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.JRBeanCollectionDataSource
import groovy.transform.Immutable
import java.math.BigDecimal

@Immutable
class Order {

    String item;
    BigDecimal unitPrice;
    int quantity;
}

def orders = [
    new Order("Item 1", new BigDecimal("5.4"), 4),
    new Order("Item 2", new BigDecimal("2.3"), 3),
    new Order("Item 3", new BigDecimal("1.5"), 8),
    new Order("Item 4", new BigDecimal("4.0"), 2),
]

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

def ds = new JRBeanCollectionDataSource(orders)

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

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

The example generates a report.

def orders = [
    new Order("Item 1", new BigDecimal("5.4"), 4),
    new Order("Item 2", new BigDecimal("2.3"), 3),
    new Order("Item 3", new BigDecimal("1.5"), 8),
    new Order("Item 4", new BigDecimal("4.0"), 2),
]

An list of orders is our data.

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

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

def ds = new JRBeanCollectionDataSource(orders)

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

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

We place the data source into the parameters map and pass the map into the JasperFillManager.fillReport method. A JasperPrint object is created; an object that can be viewed, printed, or exported to other formats.

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

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

Table
Figure: Table

This is the table object displaying data in a PDF file.

In this article we have created a data table in a report with JasperReports. The report was in a PDF format.

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.