ZetCode

JasperReports 表格

最后修改日期:2024 年 2 月 12 日

在本文中,我们将展示如何使用 JasperReports 库创建的报表中显示表格。

JasperReports 是一个开源报告库。它可以创建各种格式的报告,包括 PDF、HTML、XLS 或 CSV。JasperReports 以简单灵活的方式创建面向页面、可打印的文档。

下面的应用程序从 bean 集合数据源加载数据,并使用 JasperReports 库从中创建报表。该报表是 PDF 文件。数据以表格格式显示。

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>

这是报表模板文件。模板仅包含详情区。在详情区中,每个元素都会为数据源提供的每个记录重复一次。

注意: 由于我们处理的是货币值,因此必须使用 BigDecimal 类型。
<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>

表格将从 subDataset 元素读取数据。在元素内部,我们有三个字段和两个变量。字段映射到数据源的元素。在我们的例子中,字段映射到 bean 的属性。(我们使用的是 JRBeanCollectionDataSource。)变量对字段进行计算;它们计算表格中的单价和总价。

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

参数定义了一个数据源。JRBeanCollectionDataSource 是 Java bean 的集合。参数在填充阶段传递给报表。

<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 是 JasperReports 组件模式中指定的组件。

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

datasetRun 创建数据集的实例。在 dataSourceExpression 中,我们传递数据源参数。

<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>

表格中有四列。每列单独定义。在这一列中,我们有列标题和列单元格。标题包含列标签,单元格包含从 unitPrice 字段检索的单价。字段使用 $F{} 语法引用。box 元素用于创建线条。

<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>

在最后一列中,我们有一个列页脚。它包含订单所有商品的总价。我们使用 $V{} 语法引用变量。

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")

该示例生成报表。

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)

我们将 XML 模板文件编译成一个 JasperReportJasperReport 是一个已编译的模板,可以填充数据。

def ds = new JRBeanCollectionDataSource(orders)

JRBeanCollectionDataSource 是一个数据源实现,它封装了 Java bean 对象集合。我们将四个 Order bean 放入数据源。

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

我们将数据源放入参数映射中,并将映射传递给 JasperFillManager.fillReport 方法。创建了一个 JasperPrint 对象;这是一个可以查看、打印或导出为其他格式的对象。

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

JasperExportManager.exportReportToPdfFile 方法将 JasperPrint 导出为 PDF 文件。

Table
图:表格

这是在 PDF 文件中显示数据的表格对象。

在本文中,我们使用 JasperReports 在报表中创建了一个数据表。报表是 PDF 格式。

作者

我叫 Jan Bodnar,是一位充满激情的程序员,拥有丰富的编程经验。我从 2007 年开始撰写编程文章。迄今为止,我已撰写了 1,400 多篇文章和 8 本电子书。我在编程教学方面拥有超过十年的经验。

列出 所有 JasperReports 教程