Jasper Reports 简明教程

JasperReports - Quick Guide

JasperReports - Getting Started

What is a Report

报告是有意义、定义明确且经过总结的信息展示。通常,例行活动是自动化的,数据汇总到支持决策的“报告”中。报告将通常混乱的数据表示为图表、图形和其他形式的图形表示。

Report Template

通常,大多数商业报告生成工具采用以下布局来生成报告。

TITLE

PAGEHEADER

COLUMNHEADER

DETAIL

COLUMNFOOTER

PAGEFOOTER

SUMMARY

以下是图表中提到的每个元素的说明 −

S.NO

Element and Description

1

title Title 包含报告的“标题”。它在报告的开头只出现一次,例如“Tutorials Point Report”。

2

pageHeader PageHeader 可能包含日期和时间信息和/或组织名称。它出现在每页的顶部。

3

columnHeader ColumnHeader 列出您希望在报告中显示的那些特定字段的名称,例如“作者姓名”、“开始时间”、“完成时间”、“已用工时”、“日期”等。

4

detail Detail 是列出特定字段(在 columnHeader 中列出)的条目部分,例如,“Manisha”、“9:00”、“18:00”、“9”、“10.02.2013”。

5

columnFooter ColumnFooter 可能显示任何字段的总和,例如“已用总工时:“180”。

6

pageFooter 页脚可能包含页数信息。它出现在每页的底部,例如“1/23”。

7

summary 摘要中包含从“详细信息”部分推断出的信息,例如,在列出各个作者工作的小时数之后,可将各个作者工作的总小时数放入饼状图、图表等可视化图表中,以便进行更好的比较。

JasperReports

以下是报表开发过程中常见的问题 −

  1. Core changes − 通常,反映业务变更或增强功能需要更改报表的核心逻辑。

  2. Results exporting − 可将报表导出到多种格式,例如:HTML、文本、PDF、MS Excel、RTF、ODT、逗号分隔值、XML 或图像。

  3. Complicated reports − 子报表和交叉表报表就是一个好的例子。

  4. Charts reports − 可视化图表,例如,图形、饼图、XY 线图、条形图、计量器和时间序列。

为消除上述各项产生的开销并促进报表流程,引入了大量框架、工具、库和第三方应用程序。 JasperReports 是其中之一。

JasperReports 是一个开源 Java 报表引擎。它基于 Java 并且没有自己的表达式语法。JasperReports 具有将丰富内容传递到屏幕、打印机或 PDF、HTML、XLS、RTF、ODT、CSV、TXT 和 XML 文件的能力。由于它不是一个独立的工具,因此无法单独安装。相反,它可以通过将其库包含在应用程序的 CLASSPATH 中而嵌入到 Java 应用程序中。

JasperReports 是一个 Java 类库,不是针对最终用户,而是针对需要将报表功能添加到其应用程序中的 Java 开发人员。

Features of JasperReports

JasperReports 的一些重要功能 −

  1. 它具有灵活的报表布局。

  2. 它可以以文本或者图形方式呈现数据。

  3. 开发人员可以通过多种方式提供数据。

  4. 它可以接受来自多个数据源的数据。

  5. 它可以生成水印(水印类似于叠加在主图像上的辅助图像)。

  6. 它可以生成子报表。

  7. 它能够以多种格式导出报表。

JasperReports - Environment Setup

JasperReports 是一个纯粹的 Java 库,而不是一个独立的应用程序。它无法自己运行,因此需要将其嵌入另一个客户端或服务器端 Java 应用程序中。由于它基于 Java,因此可以在支持 Java(JDK 1.3 及更高版本)的任何平台上运行。所有 JasperReports 的功能都汇集在单个 JAR 文件 jasperreports-x.x.x.jar 中。此 JAR 文件以及必需和可选库(.ZIP 文件)可以从以下网站下载: JasperReport Library Link 。从该链接下载最新版本。

ZIP 文件包括 JasperReports JAR 文件,以及 JasperReports 源代码、依赖的 JAR 文件和大量用于演示 JasperReport 功能的示例。

JasperReport Environment

为开始创建报告,我们需要设置好环境。将下载的 JasperReport.ZIP 文件解压到任意位置(我们情况下,已将它解压到 C:\tools\jasperreports-5.0.1)。下面是解压的文件的目录结构:

jasper dir structure

这里是对所有目录的详细说明:

  1. 构建 - 包含已编译的 JasperReport 类文件。

  2. 演示 - 包含各种示例,演示了 JasperReports 功能的多方面。

  3. dist - 包含 jasperreports-x.x.x.jar 文件。我们将此 JAR 文件添加到我们的 CLASSPATH 来利用 JasperReports。

  4. 文档 - 包含 JasperReports 文档的本地副本。

  5. lib - 包含生成 JasperReports 和在我们的应用程序中使用它时所需要的所有 JAR。

  6. src - 包含 JasperReports 源代码。

  7. build.xml - 用来构建 JasperReports 源代码的 ANT 构建文件。如果我们不打算修改 JasperReports,则无需使用此文件,因为 JasperReports 以编译的形式进行分发。

  8. changes.txt - 文本文档,说明了当前 JasperReports 类库版本和先前版本之间的区别。

  9. license.txt - 文本文档,包含 LGPL(宽松通用公共许可证)许可证的全文。

  10. readme.txt - 文本文档,包含有关如何构建和执行提供的示例的说明。

基本上,我们仅将 dist 下的 jasperreports-x.x.x.jar 和 lib 目录下的 JAR 用来生成报表。由于 JasperReports 是一个开源工具,如果在 jasperreports-x.x.x.jar 的执行过程中识别到任何缺陷或 bug,我们可以使用 build.xml 文件修复它并再次构建 JAR。

Set the CLASSPATH

为使用 JasperReport,我们需将下列文件设置到我们的 CLASSPATH:

  1. jasperreports-x.x.x.jar,其中 x.x.x 是 JasperReports 版本。它位于目录 C:\tools\jasperreports-x.x.x\dist 下。

  2. lib 子目录下的所有 JAR 文件(C:\tools\jasperreports-x.x.x\lib)。

在安装时,我们使用了 JasperReport 5.0.1 版本。右键单击“我的电脑”,选择“属性”,单击“高级”标签下的“环境变量”按钮。现在使用 C:\tools\jasperreports-5.0.1\dist\jasperreports-5.0.1.jar:C:\tools\jasperreports-5.0.1\lib 更新“路径”变量。现在您已准备好创建您的报表。

在本教程的所有示例中,我们都使用 ANT 任务来生成报表。 build 文件负责导入生成报表所需的所有 JAR。因此,正如前面提到的那样,设置 CLASSPATH 仅将帮助那些希望在不使用 ANT 的情况下生成报表的人。

Build Setup

本教程中的所有示例 −

  1. 都已使用简单的文本编辑器编写。

  2. 都已保存在目录 C:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint 中。

  3. 已使用 Apache ANT 从命令提示符编译和执行。我们将在后续章节中导入 ANT build.xml 文件中的 baseBuild.xml 文件。将这个文件保存到 C:\tools\jasperreports-5.0.1\test。以下是 baseBuild.xml 文件的内容 −

<?xml version = "1.0" encoding = "UTF-8"?>
<project name = "JasperReportExample" basedir = ".">
   <description>Previews our JasperReport XML Design</description>
   <property name = "file.name" value = "jasper_report_template" />

   <!-- Directory where the JasperReports project file was extracted
   needs to be changed to match the local environment -->
   <property name = "jasper.dir" value = "../" />
   <property name = "dist.dir" value = "${jasper.dir}/dist" />
   <property name = "lib.dir" value = "${jasper.dir}/lib" />
   <property name = "src.dir" value = "src" />
   <property name = "classes.dir" value = "classes" />
   <property name = "main-class" value = "com.tutorialspoint.HelpMe" />

   <path id = "classpath">
      <pathelement location = "./" />
      <pathelement location = "${classes.dir}" />

      <fileset dir = "${lib.dir}">
         <include name = "**/*.jar" />
      </fileset>

      <fileset dir = "${dist.dir}">
         <include name = "**/*.jar" />
      </fileset>
   </path>

   <target name = "compile" depends = "clean-sample">
      <mkdir dir = "${classes.dir}"/>

      <javac srcdir = "${src.dir}" destdir = "${classes.dir}"
         classpathref = "classpath" />
   </target>

   <target name = "run" depends = "compile">
      <echo message = "Running class : ${main-class}"/>

      <java fork = "true" classname = "${main-class}">
         <classpath>
            <path refid = "classpath" />
         </classpath>
      </java>
   </target>

   <target name = "clean-sample">
      <delete dir = "${classes.dir}" />
      <delete file = "./${file.name}.jasper" />
      <delete file = "./${file.name}.jrprint" />
   </target>

</project>

此文件包含所有必需的目标,例如清理目录、编译 java 文件以及执行类文件。

以下是对 baseBuild.xml 中提到的各种目录的详细信息。假设当前目录是 C:\tools\jasperreports-5.0.1\test) −

  1. jasper.dir − 是 C:\tools\jasperreports-5.0.1 目录

  2. lib.dir − 是 C:\tools\jasperreports-5.0.1\lib 目录

  3. src.dir − is C:\tools\jasperreports-5.0.1\test\src

  4. classes.dir − is C:\tools\jasperreports-5.0.1\test\classes

  5. main-class − com.tutorialspoint.HelpMe。当未从命令行传递类文件名时,此类一个要执行的简单类。将此文件保存到 C:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint。

package com.tutorialspoint;

public class HelpMe {
   public static void main(String[] args) {
      System.out.println("This is the default class executed."
         + "Please pass the fully qualified class" + " name to be executed as command line"
         + " parameter, for example," + " com.tutorialspoint.HelpMe ");
   }
}

Jasper Managers Classes

有多个类可用于编译 JRXML 报告设计、填充报告、打印报告、导出到 PDF、HTML 和 XML 文件、查看生成的报告以及报告设计。

report manage classes

这些类的列表 −

  1. net.sf.jasperreports.engine.JasperCompileManager − 用于编译 JRXML 报告模板。

  2. net.sf.jasperreports.engine.JasperFillManager − 用于使用来自数据源的数据填充报告。

  3. net.sf.jasperreports.engine.JasperPrintManager − 用于打印由 JasperReports 库生成的文档。

  4. net.sf.jasperreports.engine.JasperExportManager − 用于获取报告填充过程生成的文件的 PDF、HTML 或 XML 内容。

  5. net.sf.jasperreports.view.JasperViewer − 它表示能够加载和显示报告的简单 Java Swing 应用程序。

  6. net.sf.jasperreports.view.JasperDesignViewer − 在设计时用于预览报告模板。

Setting up Apache ANT

我们将使用 Apache ANT 构建所有示例。因此,请检查 ANT - Environment Setup 章节在您的系统上设置 Apache ANT。

JasperReports - Life Cycle

JasperReports 的主要目的是以简单灵活的方式创建页面的、易于打印的文档。下述流程图描述了创建报告时的典型工作流程。

jasperreport lifecycle

如图片所示,生命周期具有以下不同阶段:

  1. Designing the report - 在此步骤中,我们创建 JRXML 文件,该文件是一个包含报表布局定义的 XML 文档。我们可以使用任何文本编辑器或 iReportDesigner 来手动创建它。如果使用 iReportDesigner,则以可视化方式设计布局,因此可以忽略 JRXML 的实际结构。

  2. Compiling the report - 在此步骤中,JRXML 将编译为一个称为 Jasper 文件 (*.jasper) 的二进制对象。此编译出于性能原因而执行。Jasper 文件是应用程序随附以运行报表所需的。

  3. Executing the report (Filling data into the report) - 在此步骤中,从应用程序中填充编译报表中的数据。net.sf.jasperreports.engine.JasperFillManager 类提供了将数据填充到报表中的必要函数。将创建一个 Jasper 打印文件 (*.jrprint),可以用它来打印或导出报表。

  4. Exporting the report to desired format - 在此步骤中,我们可以使用 JasperExportManager 将上一步中创建的 Jasper 打印文件导出为任何格式。由于 Jasper 提供多种导出方式,因此使用相同的输入,我们可以创建数据的多个表示形式。

将在后续章节中详细概述上述每个步骤。

JasperReports - Designs

JasperReport 中的 JRXML 模板(或 JRXML 文件)是标准 XML 文件,具有 .jrxml 扩展名。所有 JRXML 文件都包含标签 <jasperReport> 作为根元素。这反过来又包含许多子元素(所有这些都是可选的)。JasperReport 框架可以处理不同类型的数据源。在本教程中,我们将演示如何通过将 Java 数据对象集合(使用 Java bean)传递到 JasperReport Engine 来生成基本报表。最终报表将显示包含姓名和所在国家/地区的人员列表。

本章中介绍了以下步骤来描述如何设计 JasperReport:

  1. 创建 JRXML 报表模板。

  2. 预览 XML 报表模板。

Creating a JRXML Report Template

创建 JRXML 文件,该文件 jasper_report_template.jrxml 使用文本编辑器,并根据我们的环境设置将其保存为 C:\tools\jasperreports-5.0.1\test。

<?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 = "jasper_report_template" language = "groovy" pageWidth = "595"
   pageHeight = "842" columnWidth = "555" leftMargin = "20" rightMargin = "20"
   topMargin = "20" bottomMargin = "20">

   <queryString>
      <![CDATA[]]>
   </queryString>

   <field name = "country" class = "java.lang.String">
      <fieldDescription><![CDATA[country]]></fieldDescription>
   </field>

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

   <columnHeader>
      <band height = "23">

         <staticText>
            <reportElement mode = "Opaque" x = "0" y = "3" width = "535"
               height = "15" backcolor = "#70A9A9" />

            <box>
               <bottomPen lineWidth = "1.0" lineColor = "#CCCCCC" />
            </box>

            <textElement />
            <text><![CDATA[]]> </text>
         </staticText>

         <staticText>
            <reportElement x = "414" y = "3" width = "121" height = "15" />

            <textElement textAlignment = "Center" verticalAlignment = "Middle">
               <font isBold = "true" />
            </textElement>

            <text><![CDATA[Country]]></text>
         </staticText>

         <staticText>
            <reportElement x = "0" y = "3" width = "136" height = "15" />

            <textElement textAlignment = "Center" verticalAlignment = "Middle">
               <font isBold = "true" />
            </textElement>

            <text><![CDATA[Name]]></text>
         </staticText>

      </band>
   </columnHeader>

    <detail>
      <band height = "16">

         <staticText>
            <reportElement mode = "Opaque" x = "0" y = "0" width = "535"
               height = "14" backcolor = "#E5ECF9" />

            <box>
               <bottomPen lineWidth = "0.25" lineColor = "#CCCCCC" />
            </box>

            <textElement />
            <text><![CDATA[]]> </text>
         </staticText>

         <textField>
            <reportElement x = "414" y = "0" width = "121" height = "15" />

            <textElement textAlignment = "Center" verticalAlignment = "Middle">
               <font size = "9" />
            </textElement>

            <textFieldExpression class = "java.lang.String">
               <![CDATA[$F{country}]]>
            </textFieldExpression>
         </textField>

         <textField>
            <reportElement x = "0" y = "0" width = "136" height = "15" />
            <textElement textAlignment = "Center" verticalAlignment = "Middle" />

            <textFieldExpression class = "java.lang.String">
               <![CDATA[$F{name}]]>
            </textFieldExpression>
         </textField>

      </band>
   </detail>

</jasperReport>

以下是上述报表模板中主要字段的详细信息:

  1. <queryString> - 此项为空(因为我们通过 Java Bean 传递数据)。通常包含检索报表结果的 SQL 语句。

  2. <field name> - 此元素用于将数据从数据源或查询映射到报表模板中。 name 在报表正文中重复使用,并区分大小写。

  3. <fieldDescription> - 此元素将字段名称与 XML 文件中的相应元素映射。

  4. <staticText> - 此项定义不依赖于任何数据源、变量、参数或报表表达式的静态文本。

  5. <textFieldExpression> - 此项定义结果字段的外观。

  6. $F{country} - 此项是一个变量,其中包含标签 <field name> 中预定义字段结果的值。

  7. <band> - 带区包含报表中显示的数据。

一旦报告设计准备就绪,将其保存到 C:\ 目录。

Previewing the XML Report Template

JasperReports JAR 文件中提供了一个实用工具类 net.sf.jasperreports.view.JasperDesignViewer,它有助于在无需编译或填充的情况下预览报告设计。此实用工具是一个独立的 Java 应用程序,因此可以使用 ANT 执行。

让我们编写 ANT 目标 viewDesignXML 来查看 JRXML。因此,让我们在 C:\tools\jasperreports-5.0.1\test 目录下创建并保存 build.xml (应放置在放置 JRXML 的同一目录中)。以下是 build.xml 文件−

<?xml version = "1.0" encoding = "UTF-8"?>
<project name = "JasperReportTest" default = "viewDesignXML" basedir = ".">

   <import file = "baseBuild.xml" />
   <target name = "viewDesignXML" description = "Design viewer is
      launched to preview the JXML report design.">

      <java classname = "net.sf.jasperreports.view.JasperDesignViewer" fork = "true">
         <arg value = "-XML" />
         <arg value = "-F${file.name}.jrxml" />
         <classpath refid = "classpath" />
      </java>
   </target>

</project>

接下来,让我们打开命令提示符并转到放置 build.xml 的目录。执行命令 ant (因为 viewDesignXML 是默认目标)。输出如下所示−

C:\tools\jasperreports-5.0.1\test>ant
Buildfile: C:\tools\jasperreports-5.0.1\test\build.xml

viewDesignXML:
[java] log4j:WARN No appenders could be found for logger
(net.sf.jasperreports.engine.xml.JRXmlDigesterFactory).
[java] log4j:WARN Please initialize the log4j system properly.

可以忽略 Log4j 警告,并且作为上述执行的结果,“JasperDesignViewer” 窗口打开,显示我们的报告模板预览。

jasper design viewer

正如我们所看到的,仅显示用于获取数据的报告表达式,因为 JasperDesignViewer 无法访问实际数据源或报告参数。通过关闭窗口或在命令行窗口中按 Ctrl-c 终止 JasperDesignViewer。

JasperReports - Compiling Report Design

我们在前一章中生成了 JasperReport 模板(JRXML 文件)。该文件无法直接用于生成报表。必须将它编译成 JasperReport 的原生二进制格式,称为 Jasper 文件。在编译时,我们将 JasperDesign 对象转换为 JasperReport 对象 −

jasper report compiling

接口 net.sf.jasperreports.engine.design.JRCompiler 在编译期间起到了核心作用。此接口具有多个实现,具体取决于用于报表表达式的语言,后者可以用 Java、Groovy、JavaScript 或任何其他脚本语言编写,只要编译器实现能够在运行时评估它们即可。

我们可以通过以下两种方式编译 JRXML 文件 −

  1. Programmatic compilation.

  2. Compilation through ANT task.

Programmatic Compilation of JRXML

JasperReports API 提供了一个外观类 net.sf.jasperreports.engine.JasperCompileManager 用于编译 JasperReport。此类包含用于编译报表模板的多个公共静态方法。模板的源可以是文件、输入流和/或内存对象。

JRXML 文件(jasper_report_template.jrxml)的内容如下。它被保存在目录 C:\tools\jasperreports-5.0.1\test 中 −

<?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 = "jasper_report_template" language = "groovy" pageWidth = "595"
   pageHeight = "842" columnWidth = "555" leftMargin = "20" rightMargin = "20"
   topMargin = "20" bottomMargin = "20">

   <queryString>
      <![CDATA[]]>
   </queryString>

   <field name = "country" class = "java.lang.String">
      <fieldDescription><![CDATA[country]]></fieldDescription>
   </field>

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

   <columnHeader>
      <band height = "23">

         <staticText>
            <reportElement mode = "Opaque" x = "0" y = "3"
               width = "535" height = "15" backcolor = "#70A9A9" />

            <box>
               <bottomPen lineWidth = "1.0" lineColor = "#CCCCCC" />
            </box>

            <textElement />
            <text><![CDATA[]]> </text>
         </staticText>

         <staticText>
            <reportElement x = "414" y = "3" width = "121" height = "15" />

            <textElement textAlignment = "Center" verticalAlignment = "Middle">
               <font isBold = "true" />
            </textElement>

            <text><![CDATA[Country]]></text>
         </staticText>

         <staticText>
            <reportElement x = "0" y = "3" width = "136" height = "15" />

            <textElement textAlignment = "Center" verticalAlignment = "Middle">
               <font isBold = "true" />
            </textElement>

            <text><![CDATA[Name]]></text>
         </staticText>

      </band>
   </columnHeader>

   <detail>
      <band height = "16">

         <staticText>
            <reportElement mode = "Opaque" x = "0" y = "0"
               width = "535" height = "14" backcolor = "#E5ECF9" />

            <box>
               <bottomPen lineWidth = "0.25" lineColor = "#CCCCCC" />
            </box>

            <textElement />
            <text><![CDATA[]]> </text>
         </staticText>

         <textField>
            <reportElement x = "414" y = "0" width = "121" height = "15" />

            <textElement textAlignment = "Center" verticalAlignment = "Middle">
               <font size = "9" />
            </textElement>

            <textFieldExpression class = "java.lang.String">
               <![CDATA[$F{country}]]>
            </textFieldExpression>
         </textField>

         <textField>
            <reportElement x = "0" y = "0" width = "136" height = "15" />
            <textElement textAlignment = "Center" verticalAlignment = "Middle" />

            <textFieldExpression class = "java.lang.String">
               <![CDATA[$F{name}]]>
            </textFieldExpression>
         </textField>

      </band>
   </detail>

</jasperReport>

以下代码展示了上述 jasper_report_template.jrxml 文件的编译。

package com.tutorialspoint;

import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperCompileManager;

public class JasperReportCompile {

   public static void main(String[] args) {
      String sourceFileName = "C://tools/jasperreports-5.0.1/test" +
         "/jasper_report_template.jrxml";

      System.out.println("Compiling Report Design ...");
      try {
          /**
          * Compile the report to a file name same as
          * the JRXML file name
          */
         JasperCompileManager.compileReportToFile(sourceFileName);
      } catch (JRException e) {
         e.printStackTrace();
      }
      System.out.println("Done compiling!!! ...");
   }
}

Template Compilation

作为下一步,我们将在 C:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint\JasperReportCompile.java 文件中保存上述内容,并在 build.xml 文件中导入 baseBuild.xml,如下所示。baseBuild.xml 已具有 compilerun 目标 −

<?xml version = "1.0" encoding = "UTF-8"?>
<project name = "JasperReportTest" default = "run" basedir = ".">

   <import file = "baseBuild.xml"/>

</project>

接下来,我们打开命令行窗口,然后转到放置 build.xml 的目录中。最后,执行命令 ant -Dmain-class = com.tutorialspoint.JasperReportCompile ,如下所示 −

C:\tools\jasperreports-5.0.1\test>ant -Dmain-class = com.tutorialspoint.JasperReportCompile
Buildfile: C:\tools\jasperreports-5.0.1\test\build.xml
compile:
   [javac] C:\tools\jasperreports-5.0.1\test\baseBuild.xml:27:
   warning: 'includeantruntime' was not set, defaulting to
   build.sysclasspath=last;set to false for repeatable builds
   [javac] Compiling 1 source file to C:\tools\jasperreports-5.0.1\test\classes

run:
   [echo] Runnin class : com.tutorialspoint.JasperReportCompile
   [java] Compiling Report Design ...
   [java] log4j:WARN No appenders could be found for logger
   (net.sf.jasperreports.engine.xml.JRXmlDigesterFactory).
   [java] log4j:WARN Please initialize the log4j system properly.
   [java] Done compiling!!! ...

BUILD SUCCESSFUL
Total time: 8 seconds

由于上述编译,您会看到模板文件 jasper_report_template.jasper 已在 C:\tools\jasperreports-5.0.1\test 目录中生成。

Preview Compiled Report Template

net.sf.jasperreports.view.JasperDesignViewer 可用于预览已编译的报表模板和 JRXML 模板。

要进一步操作,我们向上面的 build.xml 文件添加一个新目标 viewDesign ,这将允许我们预览已编译的报表。以下是经过修改的 build.xml −

导入文件 - baseBuild.xml 从第 Environment Setup 章节中选取,且应放置在与 build.xml 相同的目录中。

<?xml version = "1.0" encoding = "UTF-8"?>
<project name = "JasperReportTest" default = "viewDesign" basedir = ".">

   <import file = "baseBuild.xml" />
   <target name = "viewDesign" description="Design viewer is launched
      to preview the compiled report design.">

      <java classname = "net.sf.jasperreports.view.JasperDesignViewer" fork = "true">
         <arg value = "-F${file.name}.jasper" />
         <classpath refid = "classpath" />
      </java>
   </target>

</project>

让我们在命令提示符下执行命令 ant (viewDesign 是默认目标)。JasperDesignViewer 窗口打开,显示如下所示的 Jasper 文件 −

jasper design viewer

Compilation through ANT Task

由于报表模板编译更像是设计时间作业而不是运行时作业,因此 JasperReport 库有一个自定义 ANT 任务。在某些情况下,当 JRXML 文件在运行时创建时,我们就无法使用此 ANT 任务。自定义 ANT 任务称为 JRC,并通过类 net.sf.jasperreports.ant.JRAntCompileTask 实现。它的语法和行为与内置 <javac> ANT 任务非常相似。

Template Compilation

让我们向现有 build.xml 添加新目标 compilereportdesing 。此处,使用嵌套 <src> 标记通过文件集指定源文件夹。嵌套源标记允许编译散布在许多不同位置的且未分组在单个根报告源文件夹下的报表模板。以下是经过修改的 build.xml −

<?xml version = "1.0" encoding = "UTF-8"?>
<project name = "JasperReportTest" default = "compilereportdesing" basedir = ".">

   <import file = "baseBuild.xml" />
   <target name = "viewDesign" description = "Design viewer is
      launched to preview the compiled report design.">

      <java classname = "net.sf.jasperreports.view.JasperDesignViewer" fork = "true">
         <arg value = "-F${file.name}.jasper" />
         <classpath refid = "classpath" />
      </java>

   </target>

   <target name = "compilereportdesing" description = "Compiles the
      JXML file and produces the .jasper file.">

      <taskdef name = "jrc" classname = "net.sf.jasperreports.ant.JRAntCompileTask">
         <classpath refid = "classpath" />
      </taskdef>

      <jrc destdir = ".">
         <src>
            <fileset dir = ".">
               <include name = "*.jrxml" />
            </fileset>
         </src>
         <classpath refid = "classpath" />
      </jrc>
   </target>

</project>

接下来,我们打开命令提示符,并转到放置 build.xml 的目录。执行命令 ant (compilereportdesing 是默认目标);输出如下所示 −

C:\tools\jasperreports-5.0.1\test>ant
Buildfile: C:\tools\jasperreports-5.0.1\test\build.xml

compilereportdesing:
   [jrc] Compiling 1 report design files.
   [jrc] log4j:WARN No appenders could be found for logger
   (net.sf.jasperreports.engine.xml.JRXmlDigesterFactory).
   [jrc] log4j:WARN Please initialize the log4j system properly.
   [jrc] log4j:WARN See
   http://logging.apache.org/log4j/1.2/faq.html#noconfig
   for more info.
   [jrc] File :
   C:\tools\jasperreports-5.0.1\test\jasper_report_template.jrxml ... OK.

BUILD SUCCESSFUL
Total time: 5 seconds

File jasper_report_template.jasper 在文件系统中生成(在我们的案例中是 C:\tools\jasperreports-5.0.1\test 目录)。此文件与通过调用 net.sf.jasperreports.engine.JasperCompileManager.compileReportToFile() 以编程方式生成的文件相同。我们可以执行 ant viewDesign 以预览此 Jasper 文件。

JasperReports - Filling Reports

任何报告工具的主要目的是生成高质量的文档。报告填充过程通过处理数据集来帮助报告工具实现此目的。

报告填充过程所需的主要输入如下:

  1. Report Template −这是实际的JasperReport文件。

  2. Report Parameters −这些基本上是在报告填充时传递给引擎的命名值。我们将在 Report Parameter 章节中讨论它们。

  3. Data Source −我们可以从一系列数据源填充Jasper文件,如SQL查询、XML文件、csv文件、HQL(Hibernate查询语言)查询、Java Bean集合等。这将在 Report Data Sources 章节中详细讨论。

此过程生成的输出是一个*.jrprint*文档,可以查看、打印或导出为其他格式。外观类net.sf.jasperreports.engine.JasperFillManager通常用于使用数据填充报告模板。此类有各种fillReportXXX()方法,用于填充报告模板(模板可以位于磁盘上、从输入流中选取或直接作为内存中提供)。

此外观类中有两类fillReportXXX()方法:

  1. 第一种类型接收java.sql.Connection对象作为第三个参数。大多数情况下,报告使用关系数据库中的数据进行填充。这是通过以下方式实现的:通过JDBC连接到数据库。在报告模板中包含一个SQL查询。JasperReports引擎使用传入的连接并执行SQL查询。因此生成了用于填充报告的报告数据源。

  2. 第二种类型接收net.sf.jasperreports.engine.JRDataSource对象,而需要填充的数据以其他形式存在时。

Filling Report Templates

我们来编写一个报告模板。JRXML文件(C:\tools\jasperreports-5.0.1\test\jasper_report_template.jrxml)的内容如下:

<?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 = "jasper_report_template" language = "groovy" pageWidth = "595"
   pageHeight = "842" columnWidth = "555" leftMargin = "20" rightMargin = "20"
   topMargin = "20" bottomMargin = "20">

   <queryString>
      <![CDATA[]]>
   </queryString>

   <field name = "country" class = "java.lang.String">
      <fieldDescription><![CDATA[country]]></fieldDescription>
   </field>

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

   <columnHeader>
      <band height = "23">

         <staticText>
            <reportElement mode = "Opaque" x = "0" y = "3"
               width = "535" height = "15" backcolor = "#70A9A9" />

            <box>
               <bottomPen lineWidth = "1.0" lineColor = "#CCCCCC" />
            </box>

            <textElement />
            <text><![CDATA[]]> </text>
         </staticText>

         <staticText>
            <reportElement x = "414" y = "3" width = "121" height = "15" />

            <textElement textAlignment = "Center" verticalAlignment = "Middle">
               <font isBold = "true" />
            </textElement>

            <text><![CDATA[Country]]></text>
         </staticText>

         <staticText>
            <reportElement x = "0" y = "3" width = "136" height = "15" />

            <textElement textAlignment = "Center" verticalAlignment = "Middle">
               <font isBold = "true" />
            </textElement>

            <text><![CDATA[Name]]></text>
         </staticText>

      </band>
   </columnHeader>

   <detail>
      <band height = "16">

         <staticText>
            <reportElement mode = "Opaque" x = "0" y = "0"
               width = "535" height = "14" backcolor = "#E5ECF9" />

            <box>
               <bottomPen lineWidth = "0.25" lineColor = "#CCCCCC" />
            </box>

            <textElement />
            <text><![CDATA[]]> </text>
         </staticText>

         <textField>
            <reportElement x = "414" y = "0" width = "121" height = "15" />

            <textElement textAlignment = "Center" verticalAlignment = "Middle">
               <font size = "9" />
            </textElement>

            <textFieldExpression class = "java.lang.String">
               <![CDATA[$F{country}]]>
            </textFieldExpression>
         </textField>

         <textField>
            <reportElement x = "0" y = "0" width = "136" height = "15" />
            <textElement textAlignment = "Center" verticalAlignment = "Middle" />

            <textFieldExpression class = "java.lang.String">
               <![CDATA[$F{name}]]>
            </textFieldExpression>
         </textField>

      </band>
   </detail>

</jasperReport>

接下来,我们向JasperReport引擎传递Java数据对象(Java bean)集合,以填充此已编译的报告。

编写POJO DataBean.java,它表示数据对象(Java bean)。此类定义了两个字符串对象,即“name”和“country”。将其保存到目录 C:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint

package com.tutorialspoint;

public class DataBean {
   private String name;
   private String country;

   public String getName() {
      return name;
   }

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

   public String getCountry() {
      return country;
   }

   public void setCountry(String country) {
      this.country = country;
   }
}

编写类DataBeanList.java,它具有生成Java bean对象集合的业务逻辑。将其进一步传递给JasperReports引擎以生成报告。这里我们在列表中添加了4个DataBean对象。将其保存到目录 C:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint

package com.tutorialspoint;

import java.util.ArrayList;

public class DataBeanList {
   public ArrayList<DataBean> getDataBeanList() {
      ArrayList<DataBean> dataBeanList = new ArrayList<DataBean>();

      dataBeanList.add(produce("Manisha", "India"));
      dataBeanList.add(produce("Dennis Ritchie", "USA"));
      dataBeanList.add(produce("V.Anand", "India"));
      dataBeanList.add(produce("Shrinath", "California"));

      return dataBeanList;
   }

   /**
    * This method returns a DataBean object,
    * with name and country set in it.
    */
   private DataBean produce(String name, String country) {
      DataBean dataBean = new DataBean();
      dataBean.setName(name);
      dataBean.setCountry(country);

      return dataBean;
   }
}

写一个 JasperReportFill.java 主类文件,从类 (DataBeanList) 中获取 Java Bean 集合,并将其传递给 JasperReports 引擎以填充报告模板。将其保存到 C:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint 目录。

package com.tutorialspoint;

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

import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;

public class JasperReportFill {
   @SuppressWarnings("unchecked")
   public static void main(String[] args) {
      String sourceFileName =
         "c://tools/jasperreports-5.0.1/test/jasper_report_template.jasper";
      DataBeanList DataBeanList = new DataBeanList();
      ArrayList<DataBean> dataList = DataBeanList.getDataBeanList();

      JRBeanCollectionDataSource beanColDataSource = new
         JRBeanCollectionDataSource(dataList);
      Map parameters = new HashMap();
      try {
         JasperFillManager.fillReportToFile(
            sourceFileName, parameters, beanColDataSource);
      } catch (JRException e) {
         e.printStackTrace();
      }
   }
}

Generating Reports

现在,我们将使用常规 ANT 构建过程编译并执行这些文件。build.xml 文件如下所示 -

导入文件 - baseBuild.xml 从第 Environment Setup 章节中选取,且应放置在与 build.xml 相同的目录中。

<?xml version = "1.0" encoding = "UTF-8"?>
<project name = "JasperReportTest" default = "executereport" basedir = ".">
   <import file = "baseBuild.xml"/>

   <target name = "executereport" depends = "compile,compilereportdesing,run">
      <echo message = "Im here"/>
   </target>

   <target name = "compilereportdesing" description = "Compiles the JXML file and
      produces the .jasper file.">

      <taskdef name = "jrc" classname = "net.sf.jasperreports.ant.JRAntCompileTask">
         <classpath refid = "classpath" />
      </taskdef>

      <jrc destdir = ".">
         <src>

            <fileset dir = ".">
               <include name = "*.jrxml" />
            </fileset>
         </src>
         <classpath refid = "classpath" />
      </jrc>

   </target>

</project>

接下来,让我们打开命令行窗口并转到放置 build.xml 的目录。最后,执行以下命令 * ant -Dmain-class = com.tutorialspoint.JasperReportFill* ( executereport 是默认目标) -

C:\tools\jasperreports-5.0.1\test>ant -Dmain-class = com.tutorialspoint.JasperReportFill
Buildfile: C:\tools\jasperreports-5.0.1\test\build.xml

compile:
   [javac] C:\tools\jasperreports-5.0.1\test\baseBuild.xml:27:
   warning: 'includeantruntime' was not set, defaulting to
   build.sysclasspath=last; set to false for repeatable builds
   [javac] Compiling 1 source file to
   C:\tools\jasperreports-5.0.1\test\classes

run:
   [echo] Runnin class : com.tutorialspoint.JasperReportFill
   [java] log4j:WARN No appenders could be found for logger
   (net.sf.jasperreports.extensions.ExtensionsEnvironment).
   [java] log4j:WARN Please initialize the log4j system properly.

BUILD SUCCESSFUL
Total time: 8 seconds

通过上述执行操作,可生成 jasper_report_template.jrprint 文件,且该文件与 .jasper 文件放在同一目录中(在此例中,该文件生成在 C:\tools\jasperreports-5.0.1\test 中)。

Jasper Report - View & Print Reports

报告填充过程 JasperPrint 对象的输出可以使用内置查看器组件查看,或打印,或导出为更流行的文档格式,如 PDF、HTML、RTF、XLS、ODT、CSV 或 XML。本章将讨论 Jasper 文档的查看和打印,下一章(即 'Export Reports.' )将讨论导出。

Viewing Reports

JasperReport 提供了一个内置查看器,用于以其原始格式查看生成的报告。它是一个基于 swing 的组件,其他 Java 应用程序可以集成此组件,而无需将文档导出为其他格式以便查看或打印。net.sf.jasperreports.view.JRViewer 类表示此可视组件。此类也可以通过对其进行子类化根据应用程序需要进行定制。

JasperReports 还具有一个 Swing 应用程序,它使用可视组件来查看报告。此应用程序有助于以 *.jrprint 生成的相同格式查看报告。此 Swing 应用程序在类 net.sf.jasperreports.view.JasperViewer 中实现。要使用此类查看报告,我们需要将其包装到 ANT 目标中。

Viewing the generated Report

以下示例演示了如何使用 JasperViewer 类查看报告 -

我们来编写一个报告模板。JRXML 文件(C:\tools\jasperreports-5.0.1\test\jasper_report_template.jrxml)的内容如下 -

<?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 = "jasper_report_template" language = "groovy" pageWidth = "595"
   pageHeight = "842" columnWidth = "555" leftMargin = "20" rightMargin = "20"
   topMargin = "20" bottomMargin = "20">

   <queryString>
      <![CDATA[]]>
   </queryString>

   <field name = "country" class = "java.lang.String">
      <fieldDescription><![CDATA[country]]></fieldDescription>
   </field>

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

   <columnHeader>
      <band height = "23">

         <staticText>
            <reportElement mode = "Opaque" x = "0" y = "3"
               width = "535" height = "15" backcolor = "#70A9A9" />

            <box>
               <bottomPen lineWidth = "1.0" lineColor = "#CCCCCC" />
            </box>

            <textElement />
            <text><![CDATA[]]> </text>
         </staticText>

         <staticText>
            <reportElement x = "414" y = "3" width = "121" height = "15" />

            <textElement textAlignment = "Center" verticalAlignment = "Middle">
               <font isBold = "true" />
            </textElement>
            <text><![CDATA[Country]]></text>
         </staticText>

         <staticText>
            <reportElement x = "0" y = "3" width = "136" height = "15" />

            <textElement textAlignment = "Center" verticalAlignment = "Middle">
               <font isBold = "true" />
            </textElement>
            <text><![CDATA[Name]]></text>
         </staticText>

      </band>
   </columnHeader>

   <detail>
      <band height = "16">

         <staticText>
            <reportElement mode = "Opaque" x = "0" y = "0"
               width = "535" height = "14" backcolor = "#E5ECF9" />

            <box>
               <bottomPen lineWidth = "0.25" lineColor = "#CCCCCC" />
            </box>

            <textElement />
            <text><![CDATA[]]> </text>
         </staticText>

         <textField>
            <reportElement x = "414" y = "0" width = "121" height = "15" />

            <textElement textAlignment = "Center" verticalAlignment = "Middle">
               <font size = "9" />
            </textElement>

            <textFieldExpression class = "java.lang.String">
               <![CDATA[$F{country}]]>
            </textFieldExpression>
         </textField>

         <textField>
            <reportElement x = "0" y = "0" width = "136" height = "15" />
            <textElement textAlignment = "Center" verticalAlignment = "Middle" />

            <textFieldExpression class = "java.lang.String">
               <![CDATA[$F{name}]]>
            </textFieldExpression>
         </textField>

      </band>
   </detail>

</jasperReport>

接下来,让我们将 Java 数据对象(Java Bean)集合传递给 JasperReports 引擎,以填充此已编译的报告。

编写一个代表数据对象(Java bean)的 POJO DataBean.java。此类定义两个字符串对象,即“name”和“country”。将其保存到 C:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint 目录。

package com.tutorialspoint;

public class DataBean {
   private String name;
   private String country;

   public String getName() {
      return name;
   }

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

   public String getCountry() {
      return country;
   }

   public void setCountry(String country) {
      this.country = country;
   }
}

编写一个具有业务逻辑以生成 Java bean 对象集合的类 DataBeanList.java。将其进一步传递到 JasperReports 引擎以生成报告。在此,我们正在 List 中添加 4 个 DataBean 对象。将其保存到 C:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint 目录。

package com.tutorialspoint;

import java.util.ArrayList;

public class DataBeanList {
   public ArrayList<DataBean> getDataBeanList() {
      ArrayList<DataBean> dataBeanList = new ArrayList<DataBean>();

      dataBeanList.add(produce("Manisha", "India"));
      dataBeanList.add(produce("Dennis Ritchie", "USA"));
      dataBeanList.add(produce("V.Anand", "India"));
      dataBeanList.add(produce("Shrinath", "California"));

      return dataBeanList;
   }

   /**
    * This method returns a DataBean object,
    * with name and country set in it.
    */
   private DataBean produce(String name, String country) {
      DataBean dataBean = new DataBean();
      dataBean.setName(name);
      dataBean.setCountry(country);

      return dataBean;
   }
}

写一个 JasperReportFill.java 主类文件,从类 (DataBeanList) 中获取 Java Bean 集合,并将其传递给 JasperReports 引擎以填充报告模板。将其保存到 C:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint 目录。

package com.tutorialspoint;

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

import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;

public class JasperReportFill {
   @SuppressWarnings("unchecked")
   public static void main(String[] args) {
      String sourceFileName =
         "c://tools/jasperreports-5.0.1/test/jasper_report_template.jasper";
      DataBeanList DataBeanList = new DataBeanList();
      ArrayList<DataBean> dataList = DataBeanList.getDataBeanList();

      JRBeanCollectionDataSource beanColDataSource = new
         JRBeanCollectionDataSource(dataList);

      Map parameters = new HashMap();
      try {
         JasperFillManager.fillReportToFile(
            sourceFileName, parameters, beanColDataSource);
      } catch (JRException e) {
         e.printStackTrace();
      }
   }
}

让我们向 build.xml 文件编写一个目标 viewFillReport 。build.xml 文件如下 -

导入文件 - baseBuild.xml 从第 Environment Setup 章节中选取,且应放置在与 build.xml 相同的目录中。

<?xml version = "1.0" encoding = "UTF-8"?>
<project name = "JasperReportTest" default = "viewFillReport" basedir = ".">
   <import file = "baseBuild.xml"/>

   <target name = "viewFillReport" depends = "compile,compilereportdesing,run"
      description = "Launches the report viewer
      to preview the report stored in the .JRprint file.">

      <java classname = "net.sf.jasperreports.view.JasperViewer" fork = "true">
         <arg value = "-F${file.name}.JRprint" />
         <classpath refid = "classpath" />
      </java>
   </target>

   <target name = "compilereportdesing" description = "Compiles the JXML file and
      produces the .jasper file.">

      <taskdef name = "jrc"
         classname = "net.sf.jasperreports.ant.JRAntCompileTask">
         <classpath refid = "classpath" />
      </taskdef>

      <jrc destdir = ".">
         <src>
            <fileset dir = ".">
               <include name = "*.jrxml" />
            </fileset>
         </src>
         <classpath refid = "classpath" />
      </jrc>

   </target>

</project>

接下来,让我们打开命令行窗口,并转到放置 build.xml 的目录。最后,执行命令 * ant -Dmain-class=com.tutorialspoint.JasperReportFill*(viewFillReport 是默认目标)。结果,我们看到一个 JasperViewer 窗口,如下面的屏幕截图所示 -

jasper report viewer

Printing Reports

我们可以使用 net.sf.jasperreports.engine.JasperPrintManager 类打印由 JasperReports 库生成的文档(以其专有格式即 JasperPrint 对象)。这是一个依赖 Java 2 Printing API 的外壳类。一旦 JasperReport 文档导出到其他格式(如 HTML 或 PDF),我们还可以打印文档。

Printing the Generated Report

以下代码演示了打印报告。让我们更新我们现有的类 JasperReportFill。我们将使用 JasperPrintManager.printReport()方法。该方法将源文件名(在此,我们传递.jrprint 文件,这是我们使用 JasperFillManager.fillReportToFile() 方法在上一步中生成的)作为第一个参数。第二个参数是用于显示标准打印对话框的布尔值(我们在此将其设置为 true )。

package com.tutorialspoint;

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

import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrintManager;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;

public class JasperReportFill {
   @SuppressWarnings("unchecked")
   public static void main(String[] args) {
      String sourceFileName = "c://tools/jasperreports-5.0.1/" +
         "test/jasper_report_template.jasper";
      String printFileName = null;
      DataBeanList DataBeanList = new DataBeanList();
      ArrayList<DataBean> dataList = DataBeanList.getDataBeanList();

      JRBeanCollectionDataSource beanColDataSource = new
         JRBeanCollectionDataSource(dataList);

      Map parameters = new HashMap();
      try {
    	   printFileName = JasperFillManager.fillReportToFile(
            sourceFileName, parameters, beanColDataSource);
         if(printFileName != null){
            JasperPrintManager.printReport( printFileName, true);
         }
      } catch (JRException e) {
         e.printStackTrace();
      }
   }
}

现在,让我们将此文件保存到目录 C:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint 。我们将使用 ANT 编译并执行此文件。build.xml 的内容如下 -

<?xml version = "1.0" encoding = "UTF-8"?>
<project name = "JasperReportTest" default = "executereport" basedir = ".">
   <import file = "baseBuild.xml"/>

   <target name = "executereport" depends = "compile,compilereportdesing,run">
      <echo message = "Im here"/>
   </target>

   <target name = "compilereportdesing" description = "Compiles the JXML file and
      produces the .jasper file.">

      <taskdef name = "jrc"
         classname = "net.sf.jasperreports.ant.JRAntCompileTask">
         <classpath refid = "classpath" />
      </taskdef>

      <jrc destdir = ".">
         <src>
            <fileset dir = ".">
               <include name = "*.jrxml" />
            </fileset>
         </src>
         <classpath refid = "classpath" />
      </jrc>

   </target>

</project>

接下来,让我们打开命令提示符并转到放置 build.xml 的目录。最后,执行命令 ant -Dmain-class=com.tutorialspoint.JasperReportPrint 。结果,会出现一个打印对话框。单击确定以打印文档。

JasperReports - Exporting Reports

我们在上一章中看到了如何打印和查看 JasperReport 生成的文档。在这里,我们将看到如何将这些报告转换为 PDF、HTML 和 XLS 等其他格式或导出到这些格式。提供了 Facade 类 net.sf.jasperreports.engine.JasperExportManager 以实现此功能。导出是指将 JasperPrint 对象(.jrprint 文件)转换为不同的格式。

以下代码(JasperReportExport.java)演示了 JasperReport 文档的导出过程。JasperExportManager 仅提供将报告导出到 PDF、HTML 和 XML 的方法。为了导出到 XLS 格式,我们使用了类 net.sf.jasperreports.engine.export.JRXlsExporter。此代码生成以下三个文件−

  1. sample_report.pdf

  2. sample_report.html

  3. sample_report.xls

Exporting to Other Formats

我们来编写一个报告模板。JRXML文件(C:\tools\jasperreports-5.0.1\test\jasper_report_template.jrxml)的内容如下:

<?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 = "jasper_report_template" language = "groovy" pageWidth = "595"
   pageHeight = "842" columnWidth = "555" leftMargin = "20" rightMargin = "20"
   topMargin = "20" bottomMargin = "20">

   <queryString>
      <![CDATA[]]>
   </queryString>

   <field name = "country" class = "java.lang.String">
      <fieldDescription><![CDATA[country]]></fieldDescription>
   </field>

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

   <columnHeader>
      <band height = "23">

         <staticText>
            <reportElement mode = "Opaque" x = "0" y = "3"
               width = "535" height = "15" backcolor = "#70A9A9" />

            <box>
               <bottomPen lineWidth = "1.0" lineColor = "#CCCCCC" />
            </box>

            <textElement />
            <text><![CDATA[]]> </text>
         </staticText>

         <staticText>
            <reportElement x = "414" y = "3" width = "121" height = "15" />

            <textElement textAlignment = "Center" verticalAlignment = "Middle">
               <font isBold = "true" />
            </textElement>

            <text><![CDATA[Country]]></text>
         </staticText>

         <staticText>
            <reportElement x = "0" y = "3" width = "136" height = "15" />

            <textElement textAlignment = "Center" verticalAlignment = "Middle">
               <font isBold = "true" />
            </textElement>

            <text><![CDATA[Name]]></text>
         </staticText>

      </band>
   </columnHeader>

   <detail>
      <band height = "16">

         <staticText>
            <reportElement mode = "Opaque" x = "0" y = "0"
               width = "535" height = "14" backcolor = "#E5ECF9" />

            <box>
               <bottomPen lineWidth = "0.25" lineColor = "#CCCCCC" />
            </box>

            <textElement />
            <text><![CDATA[]]> </text>
         </staticText>

         <textField>
            <reportElement x = "414" y = "0" width = "121" height = "15" />

            <textElement textAlignment = "Center" verticalAlignment = "Middle">
               <font size = "9" />
            </textElement>

            <textFieldExpression class = "java.lang.String">
               <![CDATA[$F{country}]]>
            </textFieldExpression>
         </textField>

         <textField>
            <reportElement x = "0" y = "0" width = "136" height = "15" />
            <textElement textAlignment = "Center" verticalAlignment = "Middle" />

            <textFieldExpression class = "java.lang.String">
               <![CDATA[$F{name}]]>
            </textFieldExpression>
         </textField>

      </band>
   </detail>

</jasperReport>

接下来, C:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint\DataBean.java POJO 文件内容如下所示−

package com.tutorialspoint;

public class DataBean {
   private String name;
   private String country;

   public String getName() {
      return name;
   }

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

   public String getCountry() {
      return country;
   }

   public void setCountry(String country) {
      this.country = country;
   }
}

文件 *C:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint\DataBeanList.java * 的内容如下所示−

package com.tutorialspoint;

import java.util.ArrayList;

public class DataBeanList {
   public ArrayList<DataBean> getDataBeanList() {
      ArrayList<DataBean> dataBeanList = new ArrayList<DataBean>();

      dataBeanList.add(produce("Manisha", "India"));
      dataBeanList.add(produce("Dennis Ritchie", "USA"));
      dataBeanList.add(produce("V.Anand", "India"));
      dataBeanList.add(produce("Shrinath", "California"));

      return dataBeanList;
   }

   /**
    * This method returns a DataBean object,
    * with name and country set in it.
    */
   private DataBean produce(String name, String country) {
      DataBean dataBean = new DataBean();
      dataBean.setName(name);
      dataBean.setCountry(country);

      return dataBean;
   }
}

写一个 JasperReportFill.java 主类文件,从类 (DataBeanList) 中获取 Java Bean 集合,并将其传递给 JasperReports 引擎以填充报告模板。将其保存到 C:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint 目录。

package com.tutorialspoint;

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

import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRExporterParameter;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import net.sf.jasperreports.engine.export.JRXlsExporter;

public class JasperReportFill {
   @SuppressWarnings("unchecked")
   public static void main(String[] args) {
      String sourceFileName = "c://tools/jasperreports-5.0.1/"
         + "test/jasper_report_template.jasper";
      String printFileName = null;
      DataBeanList DataBeanList = new DataBeanList();
      ArrayList<DataBean> dataList = DataBeanList.getDataBeanList();
      JRBeanCollectionDataSource beanColDataSource =
         new JRBeanCollectionDataSource(dataList);

      Map parameters = new HashMap();
      try {
         printFileName = JasperFillManager.fillReportToFile(sourceFileName,
            parameters, beanColDataSource);
         if (printFileName != null) {
            /**
             * 1- export to PDF
             */
            JasperExportManager.exportReportToPdfFile(printFileName,
               "C://sample_report.pdf");

            /**
             * 2- export to HTML
             */
            JasperExportManager.exportReportToHtmlFile(printFileName,
               "C://sample_report.html");

            /**
             * 3- export to Excel sheet
             */
            JRXlsExporter exporter = new JRXlsExporter();

            exporter.setParameter(JRExporterParameter.INPUT_FILE_NAME,
               printFileName);
            exporter.setParameter(JRExporterParameter.OUTPUT_FILE_NAME,
               "C://sample_report.xls");

            exporter.exportReport();
         }
      } catch (JRException e) {
         e.printStackTrace();
      }
   }
}

在这里,我们包含了将 jasper 打印文件导出到 pdf、html 和 xls 格式的逻辑。

Generating Reports

让我们使用常规 ANT 构建过程编译并执行上述文件。build.xml 文件如下所示−

<?xml version = "1.0" encoding = "UTF-8"?>
<project name = "JasperReportTest" default = "executereport" basedir = ".">
   <import file = "baseBuild.xml"/>

   <target name = "executereport" depends = "compile,compilereportdesing,run">
      <echo message = "Im here"/>
   </target>

   <target name = "compilereportdesing" description = "Compiles the JXML file and
      produces the .jasper file.">

      <taskdef name = "jrc"
         classname = "net.sf.jasperreports.ant.JRAntCompileTask">
         <classpath refid = "classpath" />
      </taskdef>

      <jrc destdir = ".">
         <src>
            <fileset dir = ".">
               <include name = "*.jrxml" />
            </fileset>
         </src>
         <classpath refid = "classpath" />
      </jrc>

   </target>

</project>

转到命令提示符,然后转到放置 build.xml 的目录 C:\tools\jasperreports-5.0.1\test。最后,执行命令 ant -Dmain-class=com.tutorialspoint.JasperReportFill 。输出如下所示−

C:\tools\jasperreports-5.0.1\test>ant -Dmain-class=com.tutorialspoint.JasperReportFill
Buildfile: C:\tools\jasperreports-5.0.1\test\build.xml

clean-sample:
   [delete] Deleting directory C:\tools\jasperreports-5.0.1\test\classes
   [delete] Deleting: C:\tools\jasperreports-5.0.1\test\jasper_report_template.jasper
   [delete] Deleting: C:\tools\jasperreports-5.0.1\test\jasper_report_template.jrprint

compile:
   [mkdir] Created dir: C:\tools\jasperreports-5.0.1\test\classes
   [javac] C:\tools\jasperreports-5.0.1\test\baseBuild.xml:28:
   warning: 'includeantruntime' was not set, defaulting t
   [javac] Compiling 4 source files to C:\tools\jasperreports-5.0.1\test\classes

compilereportdesing:
   [jrc] Compiling 1 report design files.
   [jrc] log4j:WARN No appenders could be found for logger
   (net.sf.jasperreports.engine.xml.JRXmlDigesterFactory).
   [jrc] log4j:WARN Please initialize the log4j system properly.
   [jrc] log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
   [jrc] File : C:\tools\jasperreports-5.0.1\test\jasper_report_template.jrxml ... OK.

run:
   [echo] Runnin class : com.tutorialspoint.JasperReportFill
   [java] log4j:WARN No appenders could be found for logger
   (net.sf.jasperreports.extensions.ExtensionsEnvironment).
   [java] log4j:WARN Please initialize the log4j system properly.

executereport:
   [echo] Im here

BUILD SUCCESSFUL
Total time: 32 seconds

作为上述执行的结果,你将在 C:\ 目录中找到三个文件 sample_report.pdf、sample_report.html、sample_report.xls。

Reports Parameters

填充报告的主要输入是− 报告模板、参数和数据源。本章将介绍参数,在下一章中我们将讨论数据源。

参数是对象引用,在报告填充操作期间传递给报告引擎。无法通过数据源传递的数据可以通过使用参数传递。可以通过参数传递诸如作者姓名、报告标题等数据。JasperReports 模板或 JRXML 模板可以具有零个或多个参数元素。

Parameter Declaration

参数声明如下−

<parameter name = "exampleParameter" class = "java.lang.String" />

The Name Attribute

<parameter> 元素的 name 属性是必需的。它通过名称引用报告表达式中的参数。参数名称应为一个单词。它不应包含任何特殊字符,例如句点或逗号。

The Class Attribute

class 属性也是必需的,它为参数值指定类名。它的默认值为 java.lang.String。这可以更改为运行时可用的任何类。无论报告参数的类型如何,引擎都会负责强制转换报告表达式中使用 $P{} 令牌的内容,从而使手动强制转换变得不必要。

报表参数值始终打包在一个 java.util.Map 对象中,其具有参数名称作为其键。报表参数可以用在报表的查询字符串中,以进一步定制从数据库中检索出的数据集。它们的作用就像查询中的动态过滤器,向报表提供数据。

Built-in Parameters

以下是预定义的报表参数,可随时用于表达式中:

S.NO

Parameter Name and Description

1

REPORT_PARAMETERS_MAP 包含一个映射,其中具有所有用户定义和内置参数。

2

REPORT_CONNECTION 指向用户提供的类 java.sql.Connection,用于 JDBC 数据源。

3

REPORT_DATA_SOURCE 这是由用户提供的 JRDataSource 实例,它表示内置数据源类型或用户自定义类型中的一个。

4

REPORT_MAX_COUNT 这是一个 java.lang.Integer 值,允许用户限制来自数据源的记录。

5

REPORT_SCRIPTLET 指向 net.sf.jasperreports.engine.JRAbstractScriptlet,并包含由用户提供的报表小脚本的实例。

6

REPORT_LOCALE 这是一个 java.util.Locale 实例,包含所需的资源包语言环境。

7

REPORT_RESOURCE_BUNDLE 指向 java.util.ResourceBundle 对象,并包含本地化消息。

8

REPORT_TIME_ZONE 这是一个 java.util.TimeZone 实例,用于日期格式化。

9

REPORT_VIRTUALIZER 这是一个 net.sf.jasperreports.engine.JRVirtualizer 对象,用于页面虚拟化(优化内存消耗)。

10

REPORT_CLASS_LOADER 这是一个 java.lang.ClassLoader 实例,在报表填充过程中使用以加载资源,例如图像、字体和子报表模板

11

IS_IGNORE_PAGINATION 如果设置为 java.lang.Boolean.TRUE,则报表将生成在一个长页面上,并且不会出现分页符。

Example

让我们将 ReportTitle 和 Author 传递给报表(由 JasperReportFill.java 生成)。修改后的文件 C:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint\JasperReportFill.java 如下:

package com.tutorialspoint;

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

import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;

public class JasperReportFill {
   @SuppressWarnings("unchecked")
   public static void main(String[] args) {
      String sourceFileName =
         "C://tools/jasperreports-5.0.1/test/jasper_report_template.jasper";

      DataBeanList DataBeanList = new DataBeanList();
      ArrayList<DataBean> dataList = DataBeanList.getDataBeanList();

      JRBeanCollectionDataSource beanColDataSource =
      new JRBeanCollectionDataSource(dataList);

      Map parameters = new HashMap();
      /**
       * Passing ReportTitle and Author as parameters
       */
      parameters.put("ReportTitle", "List of Contacts");
      parameters.put("Author", "Prepared By Manisha");

      try {
         JasperFillManager.fillReportToFile(
         sourceFileName, parameters, beanColDataSource);
      } catch (JRException e) {
         e.printStackTrace();
      }
   }
}

POJO 文件 C:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint\DataBean.java 的内容如下:

package com.tutorialspoint;

public class DataBean {
   private String name;
   private String country;

   public String getName() {
      return name;
   }

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

   public String getCountry() {
      return country;
   }

   public void setCountry(String country) {
      this.country = country;
   }
}

C:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint\DataBeanList.java 文件的内容如下 −

package com.tutorialspoint;

import java.util.ArrayList;

public class DataBeanList {
   public ArrayList<DataBean> getDataBeanList() {
      ArrayList<DataBean> dataBeanList = new ArrayList<DataBean>();

      dataBeanList.add(produce("Manisha", "India"));
      dataBeanList.add(produce("Dennis Ritchie", "USA"));
      dataBeanList.add(produce("V.Anand", "India"));
      dataBeanList.add(produce("Shrinath", "California"));

      return dataBeanList;
   }

   /**
    * This method returns a DataBean object,
    * with name and country set in it.
    */
   private DataBean produce(String name, String country) {
      DataBean dataBean = new DataBean();
      dataBean.setName(name);
      dataBean.setCountry(country);

      return dataBean;
   }
}

让我们将参数 <*ReportTitle*> 和 <*Author*> 添加到我们的现有报表模板(第 Report Designs 章)。报表标题和作者将显示在报表开头。修改后的报表模板(jasper_report_template.jrxml)如下。将其保存到 C:\tools\jasperreports-5.0.1\test 目录中:

<?xml version = "1.0"?>
<!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 = "jasper_report_template" pageWidth = "595"
   pageHeight = "842" columnWidth = "515"
   leftMargin = "40" rightMargin = "40" topMargin = "50" bottomMargin = "50">

   <parameter name = "ReportTitle" class = "java.lang.String"/>
   <parameter name = "Author" class = "java.lang.String"/>

   <queryString>
      <![CDATA[]]>
   </queryString>

   <field name = "country" class = "java.lang.String">
      <fieldDescription><![CDATA[country]]></fieldDescription>
   </field>

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

   <title>
      <band height = "70">

         <line>
            <reportElement x = "0" y = "0" width = "515" height = "1"/>
         </line>

         <textField isBlankWhenNull = "true" bookmarkLevel = "1">
            <reportElement x = "0" y = "10" width = "515" height = "30"/>

            <textElement textAlignment = "Center">
               <font size = "22"/>
            </textElement>

            <textFieldExpression class = "java.lang.String">
               <![CDATA[$P{ReportTitle}]]>
            </textFieldExpression>

            <anchorNameExpression>
               <![CDATA["Title"]]>
            </anchorNameExpression>
         </textField>

         <textField isBlankWhenNull = "true">
            <reportElement  x = "0" y = "40" width = "515" height = "20"/>

            <textElement textAlignment = "Center">
               <font size = "10"/>
            </textElement>

            <textFieldExpression class = "java.lang.String">
               <![CDATA[$P{Author}]]>
            </textFieldExpression>
         </textField>

      </band>
   </title>

   <columnHeader>
      <band height = "23">

         <staticText>
            <reportElement mode = "Opaque" x = "0" y = "3" width = "535" height = "15"
               backcolor = "#70A9A9" />

            <box>
               <bottomPen lineWidth = "1.0" lineColor = "#CCCCCC" />
            </box>

            <textElement />

            <text>
               <![CDATA[]]>
            </text>
         </staticText>

         <staticText>
            <reportElement x = "414" y = "3" width = "121" height = "15" />

            <textElement textAlignment = "Center" verticalAlignment = "Middle">
               <font isBold = "true" />
            </textElement>

            <text><![CDATA[Country]]></text>
         </staticText>

         <staticText>
            <reportElement x = "0" y = "3" width = "136" height = "15" />

            <textElement textAlignment = "Center" verticalAlignment = "Middle">
               <font isBold = "true" />
            </textElement>

            <text><![CDATA[Name]]></text>
         </staticText>

      </band>
   </columnHeader>

   <detail>
      <band height = "16">

         <staticText>
            <reportElement mode = "Opaque" x = "0" y = "0" width = "535" height = "14"
               backcolor = "#E5ECF9" />

            <box>
               <bottomPen lineWidth = "0.25" lineColor = "#CCCCCC" />
            </box>

            <textElement />

            <text>
               <![CDATA[]]>
            </text>
         </staticText>

         <textField>
            <reportElement x = "414" y = "0" width = "121" height = "15" />

            <textElement textAlignment = "Center" verticalAlignment = "Middle">
               <font size = "9" />
            </textElement>

            <textFieldExpression class = "java.lang.String">
               <![CDATA[$F{country}]]>
            </textFieldExpression>
         </textField>

         <textField>
            <reportElement x = "0" y = "0" width = "136" height = "15" />
            <textElement textAlignment = "Center" verticalAlignment = "Middle" />

            <textFieldExpression class = "java.lang.String">
               <![CDATA[$F{name}]]>
            </textFieldExpression>
         </textField>

      </band>
   </detail>

</jasperReport>

Report Generation

我们将使用常规的 ANT 构建过程编译并执行以上文件。文件 build.xml(保存在 C:\tools\jasperreports-5.0.1\test 目录下)的内容如下。

导入文件 - baseBuild.xml 从第 Environment Setup 章选取并应该放置在与 build.xml 相同的目录中。

<?xml version = "1.0" encoding = "UTF-8"?>
<project name = "JasperReportTest" default = "viewFillReport" basedir = ".">
   <import file = "baseBuild.xml" />

   <target name = "viewFillReport" depends = "compile,compilereportdesing,run"
      description = "Launches the report viewer to preview
      the report stored in the .JRprint file.">


      <java classname = "net.sf.jasperreports.view.JasperViewer" fork = "true">
         <arg value = "-F${file.name}.JRprint" />
         <classpath refid = "classpath" />
      </java>
   </target>

   <target name = "compilereportdesing" description = "Compiles the JXML file and
      produces the .jasper file.">

      <taskdef name = "jrc" classname = "net.sf.jasperreports.ant.JRAntCompileTask">
         <classpath refid = "classpath" />
      </taskdef>

      <jrc destdir = ".">
         <src>
            <fileset dir = ".">
               <include name = "*.jrxml" />
            </fileset>
         </src>
         <classpath refid = "classpath" />
      </jrc>

   </target>

</project>

接下来,让我们打开命令行窗口并转到放置 build.xml 的目录。最后,执行以下命令 ant -Dmain-class=com.tutorialspoint.JasperReportFill (viewFullReport 是默认目标) -

C:\tools\jasperreports-5.0.1\test>ant -Dmain-class=com.tutorialspoint.JasperReportFill
Buildfile: C:\tools\jasperreports-5.0.1\test\build.xml

clean-sample:
   [delete] Deleting directory C:\tools\jasperreports-5.0.1\test\classes
   [delete] Deleting: C:\tools\jasperreports-5.0.1\test\jasper_report_template.jasper
   [delete] Deleting: C:\tools\jasperreports-5.0.1\test\jasper_report_template.jrprint

compile:
   [mkdir] Created dir: C:\tools\jasperreports-5.0.1\test\classes
   [javac] C:\tools\jasperreports-5.0.1\test\baseBuild.xml:28: warning:
   'includeantruntime' was not set, defaulting to build.sysclasspath=last;
   set to false for repeatable builds
   [javac] Compiling 7 source files to C:\tools\jasperreports-5.0.1\test\classes

compilereportdesing:
   [jrc] Compiling 1 report design files.
   [jrc] log4j:WARN No appenders could be found for logger
   (net.sf.jasperreports.engine.xml.JRXmlDigesterFactory).
   [jrc] log4j:WARN Please initialize the log4j system properly.
   [jrc] log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig
   for more info.
   [jrc] File : C:\tools\jasperreports-5.0.1\test\jasper_report_template.jrxml ... OK.

run:
   [echo] Runnin class : com.tutorialspoint.JasperReportFill
   [java] log4j:WARN No appenders could be found for logger
   (net.sf.jasperreports.extensions.ExtensionsEnvironment).
   [java] log4j:WARN Please initialize the log4j system properly.

viewFillReport:
   [java] log4j:WARN No appenders could be found for logger
   (net.sf.jasperreports.extensions.ExtensionsEnvironment).
   [java] log4j:WARN Please initialize the log4j system properly.

BUILD SUCCESSFUL
Total time: 18 seconds

由于以上编译,JasperViewer 窗口会如以下屏幕所示打开:

report param example

在这里,我们看到,报表标题“联系人列表”和作者“由 Manisha 准备”显示在报表的开头。

Report Data Sources

数据源是结构化的数据容器。在生成报表时,JasperReports 引擎从数据源获取数据。可以从数据库、XML 文件、对象数组以及对象集合获取数据。我们已经在 Filling Reports 章中看到,fillReportXXX() 方法期望接收报表的数据源,它必须以 net.sf.jasperreports.engine.JRDataSource 对象或 java.sql.Connection 的形式进行填充(如果报表数据位于关系数据库中)。

JRDataSource 接口只有两个方法,应该实现以下内容 −

  1. public boolean next() throws JRException;在报表填充时,报告引擎在遍历数据时对数据源对象调用此方法。

  2. public Object getFieldValue(JRField jrField) throws JRException;此方法为当前数据源记录中的每个报表字段提供值。

检索数据源中数据的唯一方法是使用报表字段。JRDataSource 接口有多个默认实现,具体取决于获取数据源中记录的方式。

Datasource Implementations

下表总结了数据源及其实现类 −

Datasource

Implementation Class

JDBC

net.sf.jasperreports.engine.JRResultSetDataSource

JavaBean

net.sf.jasperreports.engine.data.JRBeanCollectionDataSource, net.sf.jasperreports.engine.data.JRBeanArrayDataSource

Map-based

net.sf.jasperreports.engine.data.JRMapArrayDataSource, net.sf.jasperreports.engine.data.JRMapCollectionDataSource

TableModel

net.sf.jasperreports.engine.data.JRTableModelDataSource

XML

net.sf.jasperreports.engine.data.JRXmlDataSource

CSV

net.sf.jasperreports.engine.data.JRCsvDataSource

XLS

net.sf.jasperreports.engine.data.JRXlsDataSource

Empty

net.sf.jasperreports.engine.JREmptyDataSource

JDBC Data Sources

JRResultSetDataSource 会包装 java.sql.ResultSet 对象。当报表数据从关系数据库中提取时,这是最常用的数据源实现。如果 java.sql.Connection 传递到引擎,它将首先执行相关查询并将返回的 java.sql.ResultSet 对象存储在 JRResultSetDataSource 实例中。

JavaBean Data Sources

JRBeanArrayDataSourceJRBeanCollectionDataSource 表示可以包装 JavaBean 对象数组和集合的实现。数组或集合中的每个对象都将被视为此类型数据源中的一条记录。特定 JavaBean 属性和相应报表字段之间的映射是通过命名约定进行的。报表字段的名称必须与 JavaBean 规范中指定的 JavaBean 属性的名称相同。

在本教程的所有示例中,我们都使用了 JRBeanCollectionDataSource。

Map-based Data Sources

如果父应用程序已将报告数据存储在内存中,类 JRMapArrayDataSourceJRMapCollectionDataSource 的实现非常有用。包装的数组或集合中的每个 Map 对象都被视为数据源中的一个虚拟记录,报表字段的值是从使用报告字段(指定为键)的 map 中提取的。

TableModel Data Sources

在许多客户端应用程序中,数据以表格格式显示。许多应用程序中一个常见的需求是允许用户将此表格格式打印为报表。实现类 JRTableModelDataSource 使得从表格格式为 Swing 应用程序生成报表变得轻而易举。此类包装一个 javax.swing.table.TableModel 对象。可以通过它们的名称或它们的以 0 为基准的索引来访问包装的 TableModel 对象中的列。

XML Data Sources

JRXmlDataSource 是一种基于 DOM 的数据源实现,它使用 XPath 表达式从 XML 文档中选择数据。XML 数据源中的记录由通过 XPath 表达式选择的节点元素表示。使用字段说明(JRXML 中的 <fieldDescription> 元素)提供的 XPath 表达式从每个记录中检索字段值。

XPath 是一种用于导航 XML 文档的属性和元素的语言。在 http://www.w3.org/TR/xpath. 中可以找到有关 XPath 的更多信息

CSV Data Sources

JRCsvDataSource 表示一种用于数据源的实现,它从结构化文本文件(通常是 CSV)中检索其数据。使用它们的列索引检索字段值。

XLS Data Sources

JRXlsDataSource 表示一种用于数据源的实现,它从 Excel 文档中检索其数据。此数据源实现的报表字段映射也基于字段列索引。

Empty Data Sources

JREmptyDataSource 模拟了一个数据源,其内部具有给定数量的虚拟空记录。UI 工具使用它来提供基本的报表预览功能,或在特殊报表模板中,或用于测试和调试目的。

Rewindable Data Sources

net.sf.jasperreports.engine.JRRewindableDataSource 扩展了基本的 JRDataSource 接口。它只会将一个方法 moveFirst() 添加到接口中。该方法旨在将光标移动到数据源中的第一个元素。

当使用不允许拆分(因为 isSplitAllowed="false" 设置而产生)的频带中放置的子报表进行操作时,可回绕数据源非常有用,且当前页面上没有足够空间来渲染子报表。

以上所有数据源实现都是可回绕的,除了 JRResultSetDataSource ,因为它不支持将记录指针移回。仅当此数据源被手动用于包装一个 java.sql.ResultSet 并将其传递到子报表中时,才会出现问题。如果 SQL 查询位于子报表模板中,则不存在问题,因为引擎会在下个页面重新启动子报表时再次执行它。

Data Source Providers

JasperReports 库具有一个接口 net.sf.jasperreports.engine.JRDataSourceProvider 。它有助于创建和销毁数据源对象。在使用 GUI 工具创建报表模板时,需要一个用于定制报表数据源的特殊工具。JRDataSourceProvider 是将定制数据源插入设计工具中的标准方法。此接口的定制实现应实现以下方法,这些方法允许创建和销毁数据源对象,还允许(如果可能)列出数据源中可用的报表字段 −

public boolean supportsGetFieldsOperation();

public JRField[] getFields(JasperReport report)
   throws JRException, UnsupportedOperationException;

public JRDataSource create(JasperReport report) throws JRException;

public void dispose(JRDataSource dataSource) throws JRException;

Reports Fields

报表字段是元素,表示数据源和报表模板之间的数据映射。可以将字段组合在报表表达式中以获得所需输出。报表模板可以包含零个或多个 <field> 元素。声明报表字段时,数据源应提供与报表模板中定义的所有字段相对应的数据。

Field Declaration

字段声明如下所示 -

<field name = "FieldName" class = "java.lang.String"/>

The Name Attribute

<field> 元素的 name 属性是必需的。它通过名称引用报表表达式中的字段。

The Class Attribute

class 属性指定字段值类的名称。它的默认值为 java.lang.String。这可以在运行时更改为任何类。无论报表字段的类型如何,引擎都会负责将使用 $F{} 标记的报表表达式强制为适当的类型,因此无需手动强制类型转换。

Field Description

<fieldDesciption> 元素是可选元素。在实现自定义数据源时,这非常有用。例如,我们可以存储键或某些信息,通过这些信息,我们可以从自定义数据源中检索字段值。通过使用 <fieldDesciption> 元素代替字段名称,可以在从数据源中检索字段值时轻松克服字段命名约定的限制。

下面是我们现有 JRXML 文件(第 Report Designs 章)中的一段代码。在这里,我们可以看到 nameclassfieldDescription 元素的用法。

<field name = "country" class = "java.lang.String">
   <fieldDescription><![CDATA[country]]></fieldDescription>
</field>

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

Sort Fields

在需要对数据排序而数据源实现不支持的情况下(例如,CSV 数据源),JasperReports 支持基于字段的内存数据源排序。可以使用报表模板中的一个或多个 <sortField> 元素进行排序。

如果指定了至少一个排序字段,则在报告填充过程中,数据源将传递给 JRSortableDataSource 实例。这会反过来从数据源获取所有记录,根据指定字段在内存中执行排序,并替换原始数据源。

排序字段名称应与报表字段名称相同。用于排序的字段应具有实现 java.util.Comparable 的类型。除 java.lang.String 类型的字段之外,对所有字段执行自然顺序排序(对于 String 类型,使用与报表填充区域设置对应的收集器)。当指定多个排序字段时,将使用字段作为排序键按它们在报表模板中出现的顺序执行排序。以下示例演示了排序功能。

Sorted Report Example

让我们将 <*sortField*> 元素添加到我们现有的报表模板(第 Report designs 章)。让我们按降序对 country 字段进行排序。修改后的报表模板(jasper_report_template.jrxml)如下。将其保存到 C:\tools\jasperreports-5.0.1\test 目录 -

<?xml version = "1.0"?>
<!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 = "jasper_report_template" pageWidth = "595" pageHeight = "842"
   columnWidth = "515" leftMargin = "40" rightMargin = "40"
   topMargin = "50" bottomMargin = "50">

   <parameter name = "ReportTitle" class = "java.lang.String"/>
   <parameter name = "Author" class = "java.lang.String"/>

   <queryString>
      <![CDATA[]]>
   </queryString>

   <field name = "country" class = "java.lang.String">
      <fieldDescription><![CDATA[country]]></fieldDescription>
   </field>

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

   <sortField name = "country" order = "Descending"/>
   <sortField name = "name"/>

   <title>
      <band height = "70">

         <line>
            <reportElement x = "0" y = "0" width = "515" height = "1"/>
         </line>

         <textField isBlankWhenNull = "true" bookmarkLevel = "1">
            <reportElement x = "0" y = "10" width = "515" height = "30"/>

            <textElement textAlignment = "Center">
               <font size = "22"/>
            </textElement>

            <textFieldExpression class = "java.lang.String">
               <![CDATA[$P{ReportTitle}]]>
            </textFieldExpression>

            <anchorNameExpression>
               <![CDATA["Title"]]>
            </anchorNameExpression>
         </textField>

         <textField isBlankWhenNull = "true">
            <reportElement  x = "0" y = "40" width = "515" height = "20"/>

            <textElement textAlignment = "Center">
               <font size = "10"/>
            </textElement>

            <textFieldExpression class = "java.lang.String">
               <![CDATA[$P{Author}]]>
            </textFieldExpression>

         </textField>

      </band>
   </title>

   <columnHeader>
      <band height = "23">

         <staticText>
            <reportElement mode = "Opaque" x = "0" y = "3" width = "535" height = "15"
               backcolor = "#70A9A9" />

            <box>
               <bottomPen lineWidth = "1.0" lineColor = "#CCCCCC" />
            </box>

            <textElement />

            <text>
               <![CDATA[]]>
            </text>
         </staticText>

         <staticText>
            <reportElement x = "414" y = "3" width = "121" height = "15" />

            <textElement textAlignment = "Center" verticalAlignment = "Middle">
               <font isBold = "true" />
            </textElement>

            <text><![CDATA[Country]]></text>
         </staticText>

         <staticText>
            <reportElement x = "0" y = "3" width = "136" height = "15" />

            <textElement textAlignment = "Center" verticalAlignment = "Middle">
               <font isBold = "true" />
            </textElement>

            <text><![CDATA[Name]]></text>
         </staticText>

      </band>
   </columnHeader>

   <detail>
      <band height = "16">

         <staticText>
            <reportElement mode = "Opaque" x = "0" y = "0" width = "535" height = "14"
               backcolor = "#E5ECF9" />

            <box>
               <bottomPen lineWidth = "0.25" lineColor = "#CCCCCC" />
            </box>

            <textElement />
            <text>
               <![CDATA[]]>
            </text>
         </staticText>

         <textField>
            <reportElement x = "414" y = "0" width = "121" height = "15" />

            <textElement textAlignment = "Center" verticalAlignment = "Middle">
               <font size = "9" />
            </textElement>

            <textFieldExpression class = "java.lang.String">
               <![CDATA[$F{country}]]>
            </textFieldExpression>
         </textField>

         <textField>
            <reportElement x = "0" y = "0" width = "136" height = "15" />
            <textElement textAlignment = "Center" verticalAlignment = "Middle" />

            <textFieldExpression class = "java.lang.String">
               <![CDATA[$F{name}]]>
            </textFieldExpression>
         </textField>

      </band>
   </detail>

</jasperReport>

用于填充报告的 Java 代码保持不变。文件 C:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint\JasperReportFill.java 的内容如下 -

package com.tutorialspoint;

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

import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;

public class JasperReportFill {
   @SuppressWarnings("unchecked")
   public static void main(String[] args) {
      String sourceFileName =
      "C://tools/jasperreports-5.0.1/test/jasper_report_template.jasper";

      DataBeanList DataBeanList = new DataBeanList();
      ArrayList<DataBean> dataList = DataBeanList.getDataBeanList();

      JRBeanCollectionDataSource beanColDataSource =
      new JRBeanCollectionDataSource(dataList);

      Map parameters = new HashMap();
      /**
       * Passing ReportTitle and Author as parameters
       */
      parameters.put("ReportTitle", "List of Contacts");
      parameters.put("Author", "Prepared By Manisha");

      try {
         JasperFillManager.fillReportToFile(
         sourceFileName, parameters, beanColDataSource);
      } catch (JRException e) {
         e.printStackTrace();
      }
   }
}

C:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint\DataBean.java POJO 文件的内容如下 −

package com.tutorialspoint;

public class DataBean {
   private String name;
   private String country;

   public String getName() {
      return name;
   }

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

   public String getCountry() {
      return country;
   }

   public void setCountry(String country) {
      this.country = country;
   }
}

C:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint\DataBeanList.java 文件的内容如下 −

package com.tutorialspoint;

import java.util.ArrayList;

public class DataBeanList {
   public ArrayList<DataBean> getDataBeanList() {
      ArrayList<DataBean> dataBeanList = new ArrayList<DataBean>();

      dataBeanList.add(produce("Manisha", "India"));
      dataBeanList.add(produce("Dennis Ritchie", "USA"));
      dataBeanList.add(produce("V.Anand", "India"));
      dataBeanList.add(produce("Shrinath", "California"));

      return dataBeanList;
   }

   /**
    * This method returns a DataBean object,
    * with name and country set in it.
    */
   private DataBean produce(String name, String country) {
      DataBean dataBean = new DataBean();
      dataBean.setName(name);
      dataBean.setCountry(country);

      return dataBean;
   }
}

Report generation

我们将使用常规 ANT 构建流程编译并执行上述文件。build.xml 文件(保存在 C:\tools\jasperreports-5.0.1\test 目录下)的内容如下。

导入文件 - baseBuild.xml 从第 Environment Setup 章节中选取,且应放置在与 build.xml 相同的目录中。

<?xml version = "1.0" encoding = "UTF-8"?>
<project name = "JasperReportTest" default = "viewFillReport" basedir = ".">
   <import file = "baseBuild.xml" />

   <target name = "viewFillReport" depends = "compile,compilereportdesing,run"
      description = "Launches the report viewer to preview
      the report stored in the .JRprint file.">

      <java classname = "net.sf.jasperreports.view.JasperViewer" fork = "true">
         <arg value = "-F${file.name}.JRprint" />
         <classpath refid = "classpath" />
      </java>
   </target>

   <target name = "compilereportdesing" description = "Compiles the JXML file and
      produces the .jasper file.">

      <taskdef name = "jrc" classname = "net.sf.jasperreports.ant.JRAntCompileTask">
         <classpath refid = "classpath" />
      </taskdef>

      <jrc destdir = ".">
         <src>
            <fileset dir = ".">
               <include name = "*.jrxml" />
            </fileset>
         </src>
         <classpath refid = "classpath" />
      </jrc>

   </target>

</project>

接下来,让我们打开命令行窗口并转到放置 build.xml 的目录。最后,执行以下命令 ant -Dmain-class=com.tutorialspoint.JasperReportFill (viewFullReport 是默认目标) -

C:\tools\jasperreports-5.0.1\test>ant -Dmain-class=com.tutorialspoint.JasperReportFill
Buildfile: C:\tools\jasperreports-5.0.1\test\build.xml

clean-sample:
   [delete] Deleting directory C:\tools\jasperreports-5.0.1\test\classes
   [delete] Deleting: C:\tools\jasperreports-5.0.1\test\jasper_report_template.jasper
   [delete] Deleting: C:\tools\jasperreports-5.0.1\test\jasper_report_template.jrprint

compile:
   [mkdir] Created dir: C:\tools\jasperreports-5.0.1\test\classes
   [javac] C:\tools\jasperreports-5.0.1\test\baseBuild.xml:28: warning:
   'includeantruntime' was not set, defaulting to build.sysclasspath=last;
   set to false for repeatable builds
   [javac] Compiling 7 source files to C:\tools\jasperreports-5.0.1\test\classes

compilereportdesing:
   [jrc] Compiling 1 report design files.
   [jrc] log4j:WARN No appenders could be found for logger
   (net.sf.jasperreports.engine.xml.JRXmlDigesterFactory).
   [jrc] log4j:WARN Please initialize the log4j system properly.
   [jrc] log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig
   for more info.
   [jrc] File : C:\tools\jasperreports-5.0.1\test\jasper_report_template.jrxml ... OK.

run:
   [echo] Runnin class : com.tutorialspoint.JasperReportFill
   [java] log4j:WARN No appenders could be found for logger
   (net.sf.jasperreports.extensions.ExtensionsEnvironment).
   [java] log4j:WARN Please initialize the log4j system properly.

viewFillReport:
   [java] log4j:WARN No appenders could be found for logger
   (net.sf.jasperreports.extensions.ExtensionsEnvironment).
   [java] log4j:WARN Please initialize the log4j system properly.

BUILD SUCCESSFUL
Total time: 18 seconds

作为上述编译的结果,一个 JasperViewer 窗口会打开,如以下给出的屏幕截图所示 -

report field sort example

在此,我们可以看到,国家名称按字母顺序降序排列。

Report Expression

报表表达式是 JasperReports 的强大功能,它允许我们在报表上显示计算数据。计算数据不是静态数据,也没有特别作为报表参数或数据源字段传递。报表表达式由报表参数、字段和静态数据组合而成。默认情况下,Java 语言用于编写报表表达式。JasperReports 编译器支持用于报表表达式的其他脚本语言,如 Groovy 脚本语言、JavaScript 或 BeanShell 脚本。

本章将为您解释报表表达式如何工作,假设报表表达式仅使用 Java 语言编写。在一个 JRXML 报表模板中,有若干元素定义表达式,如下 −

  1. <variableExpression>

  2. <initialValueExpression>

  3. <groupExpression>

  4. <printWhenExpression>

  5. <imageExpression>

  6. <textFieldExpression>

Expression Declaration

基本上,所有报表表达式都是 Java 表达式,可以引用报表字段、报表变量和报表参数。

Field Reference in Expression

要在表达式中使用报表字段引用,必须将字段的名称放在 $F{*and }* 字符序列之间,如下所示 −

<textfieldexpression>
   $F{Name}
</textfieldexpression>

以下是现有 JRXML 文件中的一段代码(第 Report Designs) 章 −

<textFieldExpression class = "java.lang.String">
   <![CDATA[$F{country}]]>
</textFieldExpression>

Variable Reference in Expression

要在表达式中引用变量,必须将变量名称放在 $V{*and }* 之间,如下面给出的示例所示 −

<textfieldexpression>
   "Total height : " + $V{SumOfHeight} + " ft."
</textfieldexpression>

Parameter Reference in Expression

要在表达式中引用参数,应该将参数名称放在 $P{*and }* 之间,如下面给出的示例所示 −

<textfieldexpression>
   "ReportTitle : " + $P{Title}
</textfieldexpression>

以下是现有 JRXML 文件中的一段代码,它说明了如何在表达式中引用参数。(第 Report Designs 章的 JRXML) −

<textField isBlankWhenNull = "true" bookmarkLevel = "1">
   <reportElement x = "0" y = "10" width = "515" height = "30"/>

   <textElement textAlignment = "Center">
      <font size = "22"/>
   </textElement>

   <textFieldExpression class = "java.lang.String">
      <![CDATA[$P{ReportTitle}]]>
   </textFieldExpression>

   <anchorNameExpression>
      <![CDATA["Title"]]>
   </anchorNameExpression>
</textField>

<textField isBlankWhenNull = "true">
   <reportElement  x = "0" y = "40" width = "515" height = "20"/>

   <textElement textAlignment = "Center">
      <font size = "10"/>
   </textElement>

   <textFieldExpression class = "java.lang.String">
      <![CDATA[$P{Author}]]>
   </textFieldExpression>
</textField>

如您在上面看到的那样,参数、字段和变量引用实际上是真正的 Java 对象。通过在报表模板中进行参数、字段或变量声明了解它们的类,我们甚至可以在表达式中对那些对象引用调用方法。

以下示例显示了如何从 java.lang.String 报表字段“Name”中提取并显示第一个字母 −

<textFieldExpression>
   $F{Name}.substring(0, 1)
</textFieldExpression>

Resource Bundle Reference in Expression

要在表达式中引用资源,应将键放在 $R{*and }* 之间,如下面给出的示例所示 −

<textfieldexpression>
   $R{report.title}
</textfieldexpression>

基于运行时提供的语言环境和 report.title 键,加载与报表模板关联的资源包。因此,通过从资源包中提取 String 值来显示报表标题。关于国际化的更多信息可以在第 Internationalization 章中找到。

Calculator

计算器是 JasperReports 中的一个实体,它在报告填充时评估表达式并增加变量或数据集。在编译过程中,编译器将生成信息并将其存储在编译报告中。在报告填充时,使用此信息来构建 net.sf.jasperreports.engine.fill.JRCalculator 类的实例。

Java 源文件由基于 Java 的报告编译器动态生成和编译。这个生成的类是 JRCalculator 的子类,编译生成字节码存储在 JasperReport 对象中。在报告填充时加载这个字节码,并实例化结果类以获取表达式评估所需的计算器对象。

Conditional Expressions

定义变量表达式时,JasperReports 不支持 if-else 语句。相反,可以使用三元运算符 {cond} ? {statement 1} : {statement 2} 。此运算符可以嵌套在 Java 表达式中,以根据多种条件获取所需输出。

Example of conditional Expression in Report

让我们修改现有的报告模板(第 Report Designs 章),并为 country 字段添加条件表达式。修改后的报告模板 (jasper_report_template.jrxml) 如下。将其保存到 C:\tools\jasperreports-5.0.1\test 目录中−

<?xml version = "1.0"?>
<!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 = "jasper_report_template" pageWidth = "595" pageHeight = "842"
   columnWidth = "515" leftMargin = "40" rightMargin = "40"
   topMargin = "50" bottomMargin = "50">

   <parameter name = "ReportTitle" class = "java.lang.String"/>
   <parameter name = "Author" class = "java.lang.String"/>

   <queryString>
      <![CDATA[]]>
   </queryString>

   <field name = "country" class = "java.lang.String">
      <fieldDescription><![CDATA[country]]></fieldDescription>
   </field>

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

   <sortField name = "country" order = "Descending"/>
   <sortField name = "name"/>

   <title>
      <band height = "70">

         <line>
            <reportElement x = "0" y = "0" width = "515" height = "1"/>
         </line>

         <textField isBlankWhenNull = "true" bookmarkLevel = "1">
            <reportElement x = "0" y = "10" width = "515" height = "30"/>

            <textElement textAlignment = "Center">
               <font size = "22"/>
            </textElement>

            <textFieldExpression class = "java.lang.String">
               <![CDATA[$P{ReportTitle}]]>
            </textFieldExpression>

            <anchorNameExpression>
               <![CDATA["Title"]]>
            </anchorNameExpression>
         </textField>

         <textField isBlankWhenNull = "true">
            <reportElement  x = "0" y = "40" width = "515" height = "20"/>

            <textElement textAlignment = "Center">
               <font size = "10"/>
            </textElement>

            <textFieldExpression class = "java.lang.String">
               <![CDATA[$P{Author}]]>
            </textFieldExpression>
         </textField>

      </band>
   </title>

   <columnHeader>
      <band height = "23">

         <staticText>
            <reportElement mode = "Opaque" x = "0" y = "3" width = "535" height = "15"
               backcolor = "#70A9A9" />

            <box>
               <bottomPen lineWidth = "1.0" lineColor = "#CCCCCC" />
            </box>

            <textElement />

            <text>
               <![CDATA[]]>
            </text>
         </staticText>

         <staticText>
            <reportElement x = "414" y = "3" width = "121" height = "15" />

            <textElement textAlignment = "Center" verticalAlignment = "Middle">
               <font isBold = "true" />
            </textElement>

            <text><![CDATA[Country]]></text>
         </staticText>

         <staticText>
            <reportElement x = "0" y = "3" width = "136" height = "15" />

            <textElement textAlignment = "Center" verticalAlignment = "Middle">
               <font isBold = "true" />
            </textElement>

            <text><![CDATA[Name]]></text>
         </staticText>

      </band>
   </columnHeader>

   <detail>
      <band height = "16">

         <staticText>
            <reportElement mode = "Opaque" x = "0" y = "0" width = "535" height = "14"
               backcolor = "#E5ECF9" />

            <box>
               <bottomPen lineWidth = "0.25" lineColor = "#CCCCCC" />
            </box>

            <textElement />

            <text>
               <![CDATA[]]>
            </text>
         </staticText>

         <textField>
            <reportElement x = "414" y = "0" width = "121" height = "15" />

            <textElement textAlignment = "Center" verticalAlignment = "Middle">
               <font size = "9" />
            </textElement>

            <textFieldExpression class = "java.lang.String">
               <![CDATA[$F{country}.isEmpty() ? "NO COUNTRY" : $F{country}]]>
            </textFieldExpression>
         </textField>

         <textField>
            <reportElement x = "0" y = "0" width = "136" height = "15" />
            <textElement textAlignment = "Center" verticalAlignment = "Middle" />

            <textFieldExpression class = "java.lang.String">
               <![CDATA[$F{name}]]>
            </textFieldExpression>
         </textField>

      </band>
   </detail>

</jasperReport>

报告填充的 Java 代码如下。文件 C:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint\JasperReportFill.java 的内容为 −

package com.tutorialspoint;

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

import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;

public class JasperReportFill {
   @SuppressWarnings("unchecked")
   public static void main(String[] args) {
      String sourceFileName =
      "C://tools/jasperreports-5.0.1/test/jasper_report_template.jasper";

      DataBeanList DataBeanList = new DataBeanList();
      ArrayList<DataBean> dataList = DataBeanList.getDataBeanList();

      JRBeanCollectionDataSource beanColDataSource =
      new JRBeanCollectionDataSource(dataList);

      Map parameters = new HashMap();
      /**
       * Passing ReportTitle and Author as parameters
       */
      parameters.put("ReportTitle", "List of Contacts");
      parameters.put("Author", "Prepared By Manisha");

      try {
         JasperFillManager.fillReportToFile(
         sourceFileName, parameters, beanColDataSource);
      } catch (JRException e) {
         e.printStackTrace();
      }
   }
}

POJO 文件 C:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint\DataBean.java 的内容为 -

package com.tutorialspoint;

public class DataBean {
   private String name;
   private String country;

   public String getName() {
      return name;
   }

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

   public String getCountry() {
      return country;
   }

   public void setCountry(String country) {
      this.country = country;
   }
}

我们会在 Java Bean List 中添加一条新记录,country 字段为空。文件 C:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint\DataBeanList.java 的内容为 −

package com.tutorialspoint;

import java.util.ArrayList;

public class DataBeanList {
   public ArrayList<DataBean> getDataBeanList() {
      ArrayList<DataBean> dataBeanList = new ArrayList<DataBean>();

      dataBeanList.add(produce("Manisha", "India"));
      dataBeanList.add(produce("Dennis Ritchie", "USA"));
      dataBeanList.add(produce("V.Anand", "India"));
      dataBeanList.add(produce("Shrinath", "California"));
      dataBeanList.add(produce("Tanmay", ""));

      return dataBeanList;
   }

   /**
    * This method returns a DataBean object,
    * with name and country set in it.
    */
   private DataBean produce(String name, String country) {
      DataBean dataBean = new DataBean();
      dataBean.setName(name);
      dataBean.setCountry(country);

      return dataBean;
   }
}

Report Generation

我们使用常规 ANT 构建进程编译并执行上述文件。build.xml 文件(保存在目录 C:\tools\jasperreports-5.0.1\test 下)的内容如下。

导入文件 - baseBuild.xml 取自第 Environment Setup ,应放在与 build.xml 相同的目录中。

<?xml version = "1.0" encoding = "UTF-8"?>
<project name = "JasperReportTest" default = "viewFillReport" basedir = ".">
   <import file = "baseBuild.xml" />

   <target name = "viewFillReport" depends = "compile,compilereportdesing,run"
      description = "Launches the report viewer to preview
      the report stored in the .JRprint file.">

      <java classname = "net.sf.jasperreports.view.JasperViewer" fork = "true">
         <arg value = "-F${file.name}.JRprint" />
         <classpath refid = "classpath" />
      </java>
   </target>

   <target name = "compilereportdesing" description = "Compiles the JXML file and
      produces the .jasper file.">

      <taskdef name = "jrc" classname = "net.sf.jasperreports.ant.JRAntCompileTask">
         <classpath refid = "classpath" />
      </taskdef>

      <jrc destdir = ".">
         <src>
            <fileset dir = ".">
               <include name = "*.jrxml" />
            </fileset>
         </src>
         <classpath refid = "classpath" />
      </jrc>

   </target>

</project>

接下来,打开命令行窗口,并转到放置 build.xml 的目录。最后,执行命令 ant -Dmain-class = com.tutorialspoint.JasperReportFill (viewFullReport 是默认目标),如下所示:

C:\tools\jasperreports-5.0.1\test>ant -Dmain-class=com.tutorialspoint.JasperReportFill
Buildfile: C:\tools\jasperreports-5.0.1\test\build.xml

clean-sample:
   [delete] Deleting directory C:\tools\jasperreports-5.0.1\test\classes
   [delete] Deleting: C:\tools\jasperreports-5.0.1\test\jasper_report_template.jasper
   [delete] Deleting: C:\tools\jasperreports-5.0.1\test\jasper_report_template.jrprint

compile:
   [mkdir] Created dir: C:\tools\jasperreports-5.0.1\test\classes
   [javac] C:\tools\jasperreports-5.0.1\test\baseBuild.xml:28:
   warning: 'includeantruntime' was not set, defaulting to build.sysclasspath=last;
   set to false for repeatable builds
   [javac] Compiling 3 source files to C:\tools\jasperreports-5.0.1\test\classes

compilereportdesing:
   [jrc] Compiling 1 report design files.
   [jrc] log4j:WARN No appenders could be found for logger
   (net.sf.jasperreports.engine.xml.JRXmlDigesterFactory).
   [jrc] log4j:WARN Please initialize the log4j system properly.
   [jrc] log4j:WARN See
   http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
   [jrc] File : C:\tools\jasperreports-5.0.1\test\jasper_report_template.jrxml ... OK.

run:
   [echo] Runnin class : com.tutorialspoint.JasperReportFill
   [java] log4j:WARN No appenders could be found for logger
   (net.sf.jasperreports.extensions.ExtensionsEnvironment).
   [java] log4j:WARN Please initialize the log4j system properly.

viewFillReport:
    [java] log4j:WARN No appenders could be found for logger
    (net.sf.jasperreports.extensions.ExtensionsEnvironment).
    [java] log4j:WARN Please initialize the log4j system properly.

BUILD SUCCESSFUL
Total time: 5 minutes 5 seconds

C:\tools\jasperreports-5.0.1\test>

作为上述编译的结果,一个 JasperViewer 窗口会打开,如以下给出的屏幕截图所示 -

report expression example

在这里,我们可以看到,对于最后一条记录,我们没有传递 country 字段的任何数据,“NO COUNTRY” 正在打印。

Report Variables

报表变量是建立在报表表达式之上的特殊对象。

报表变量简化了以下任务:

  1. 报表表达式,在整个报表模板中大量使用。这些表达式可以使用报表变量仅声明一次。

  2. 报表变量可以基于相应的表达式值(例如计数、求和、平均值、最低值、最高值、方差等)执行各种计算。

如果在报表设计中定义了变量,则表达式中的新变量可以引用这些变量。因此,在报表设计中声明变量的顺序很重要。

Variable Declaration

变量声明如下:

<variable name = "CityNumber" class = "java.lang.Integer" incrementType = "Group"
   incrementGroup = "CityGroup" calculation = "Count">
   <variableExpression>
      <![CDATA[Boolean.TRUE]]>
   </variableExpression>
</variable>

如上所见,<variable> 元素包含许多属性。这些属性总结如下:

The Name Attribute

与参数和字段类似,</variable> 元素的 name 属性是必需的。它允许通过其在报表表达式中声明的名称引用变量。

The Class Attribute

class 属性也是必需的,它为变量值指定类名。其默认值为 java.lang.String。可以在报表编译时间和报表填充时间将其更改为在类路径中可用的任何类。引擎负责在报表表达式中使用 $V{} 令牌的类型转换,因此不需要手动类型转换。

Calculation

此属性确定——在填充报表时对变量执行什么计算。以下小节描述了 <variable> 元素的 calculation 属性的所有可能值。

  1. Average——变量值是变量表达式的每个非空值的平均值。仅对数字变量有效。

  2. Count——变量值是变量表达式的非空实例的计数。

  3. First——变量值是变量表达式的第一个实例的值。忽略后续值。

  4. Highest——变量值是报表中变量表达式的最高值。

  5. Lowest——变量值是报表中变量表达式的最低值。

  6. Nothing——不对变量执行任何计算。

  7. StandardDeviation——变量值是与报表表达式匹配的所有非空值的标准偏差。仅对数字变量有效。

  8. Sum——变量值是报表表达式返回的所有非空值的总和。

  9. 系统 − 可变量值为自定义计算(使用 JasperReports 的小脚本功能自行计算该变量的值)。

  10. 差异 − 可变量值为报表变量表达式计算后返回的所有非空值的差异。

Incrementer FactoryClass

此属性决定在报表上填写当前记录时用于计算变量值所用的类。默认值应为实施 net.sf.jasperreports.engine.fill.JRIncrementerFactory 的任何类。引擎将在运行时使用工厂类来根据变量所设置的计算属性实例化增量对象。

IncrementType

这决定何时重新计算变量值。此属性使用值,如下 −

  1. 列 − 可变量值在每列结束时重新计算。

  2. 组 − 当 incrementGroup 指定的组更改时,可变量值重新计算。

  3. 无 − 可变量值随每条记录重新计算。

  4. 页面 − 可变量值在每页结束时重新计算。

  5. 报表 − 可变量值重新计算一次,在报表结束时。

IncrementGroup

当 incrementType 为组时,这决定在哪个组名称处重新计算变量值。此处为 JRXML 报表模板中声明的任何组之名称。

ResetType

这决定何时重置变量值。此属性使用值,如下 −

  1. 列 − 可变量值在每列开头时重置。

  2. 组 − 当 incrementGroup 指定的组更改时,可变量值重置。

  3. 无 − 可变量值从不重置。

  4. 页面 − 可变量值在每页开头时重置。

  5. 报表 − 可变量值仅重置一次,在报表开头时。

ResetGroup

当 resetType 为组时,这决定在哪个组名称处重置变量值。此属性的值为 JRXML 报表模板中声明的任何组的名称。

Built-In Report Variables

有些内置系统变量随时可用于表达式中,如下 −

S.NO

Variable Name and Description

1

PAGE_NUMBER 此变量的值为其当前页码。可使用 JasperReports 文本字段元素的特殊功能 evaluationTime 属性来显示当前页码和总页数。

2

COLUMN_NUMBER 此变量包含当前列号。

3

REPORT_COUNT 此报表变量包含处理的总记录数。

4

PAGE_COUNT 此变量包含生成当前页面时处理的记录数

5

COLUMN_COUNT 此变量包含生成当前列时处理的记录数

6

GroupName_COUNT 此变量的名称源于其对应的组的名称,并以 _COUNT 序列为后缀。此变量包含当前组中的记录数。

Example

让我们向现有报表模板(第 Report Designs 章)添加一个变量( countNumber )。我们将在每个记录之前添加计数。经修订的报表模板(jasper_report_template.jrxml)如下。将其保存到 C:\tools\jasperreports-5.0.1\test 目录中−

<?xml version = "1.0"?>
<!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 = "jasper_report_template" pageWidth = "595"
   pageHeight = "842" columnWidth = "515"
   leftMargin = "40" rightMargin = "40" topMargin = "50" bottomMargin = "50">

   <parameter name = "ReportTitle" class = "java.lang.String"/>
   <parameter name = "Author" class = "java.lang.String"/>

   <queryString>
      <![CDATA[]]>
   </queryString>

   <field name = "country" class = "java.lang.String">
      <fieldDescription>
         <![CDATA[country]]>
      </fieldDescription>
   </field>

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

   <variable name = "countNumber" class = "java.lang.Integer" calculation = "Count">
      <variableExpression>
         <![CDATA[Boolean.TRUE]]>
      </variableExpression>
   </variable>

   <title>
      <band height = "70">

         <line>
            <reportElement x = "0" y = "0" width = "515" height = "1"/>
         </line>

         <textField isBlankWhenNull = "true" bookmarkLevel = "1">
            <reportElement x = "0" y = "10" width = "515" height = "30"/>

            <textElement textAlignment = "Center">
               <font size = "22"/>
            </textElement>

            <textFieldExpression class = "java.lang.String">
               <![CDATA[$P{ReportTitle}]]>
            </textFieldExpression>

            <anchorNameExpression>
               <![CDATA["Title"]]>
            </anchorNameExpression>
         </textField>

         <textField isBlankWhenNull = "true">
            <reportElement  x = "0" y = "40" width = "515" height = "20"/>

            <textElement textAlignment = "Center">
               <font size = "10"/>
            </textElement>

            <textFieldExpression class = "java.lang.String">
               <![CDATA[$P{Author}]]>
            </textFieldExpression>
         </textField>

      </band>
   </title>

   <columnHeader>
      <band height = "23">

         <staticText>
            <reportElement mode = "Opaque" x = "0" y = "3" width = "535"	height = "15"
               backcolor = "#70A9A9" />

            <box>
               <bottomPen lineWidth = "1.0" lineColor = "#CCCCCC" />
            </box>

            <textElement />

            <text>
               <![CDATA[]]>
            </text>
         </staticText>

         <staticText>
            <reportElement x = "414" y = "3" width = "121" height = "15" />

            <textElement textAlignment = "Center" verticalAlignment = "Middle">
               <font isBold = "true" />
            </textElement>

            <text><![CDATA[Country]]></text>
         </staticText>

         <staticText>
            <reportElement x = "0" y = "3" width = "136" height = "15" />

            <textElement textAlignment = "Center" verticalAlignment = "Middle">
               <font isBold = "true" />
            </textElement>

            <text><![CDATA[Name]]></text>
         </staticText>

      </band>
   </columnHeader>

   <detail>
      <band height = "16">

         <staticText>
            <reportElement mode = "Opaque" x = "0" y = "0" width = "535" height = "14"
               backcolor = "#E5ECF9" />

            <box>
               <bottomPen lineWidth = "0.25" lineColor = "#CCCCCC" />
            </box>

            <textElement />

            <text>
               <![CDATA[]]>
            </text>
         </staticText>

         <textField>
            <reportElement x = "414" y = "0" width = "121" height = "15" />

            <textElement textAlignment = "Center" verticalAlignment = "Middle">
               <font size = "9" />
            </textElement>

            <textFieldExpression class = "java.lang.String">
               <![CDATA[$F{country}]]>
            </textFieldExpression>
         </textField>

         <textField>
            <reportElement x = "0" y = "0" width = "136" height = "15" />
            <textElement textAlignment = "Center" verticalAlignment = "Middle" />

            <textFieldExpression class = "java.lang.String">
               <![CDATA["  " + String.valueOf($V{countNumber}) +"."+$F{name}]]>
            </textFieldExpression>
         </textField>

      </band>
   </detail>

</jasperReport>

用于填充报告的 Java 代码保持不变。文件 C:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint\JasperReportFill.java 的内容如下 -

package com.tutorialspoint;

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

import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;

public class JasperReportFill {
   @SuppressWarnings("unchecked")
   public static void main(String[] args) {
      String sourceFileName =
      "C://tools/jasperreports-5.0.1/test/jasper_report_template.jasper";

      DataBeanList DataBeanList = new DataBeanList();
      ArrayList<DataBean> dataList = DataBeanList.getDataBeanList();

      JRBeanCollectionDataSource beanColDataSource =
      new JRBeanCollectionDataSource(dataList);

      Map parameters = new HashMap();
      /**
       * Passing ReportTitle and Author as parameters
       */
      parameters.put("ReportTitle", "List of Contacts");
      parameters.put("Author", "Prepared By Manisha");

      try {
         JasperFillManager.fillReportToFile(
         sourceFileName, parameters, beanColDataSource);
      } catch (JRException e) {
         e.printStackTrace();
      }
   }
}

C:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint\DataBean.java POJO 文件的内容如下 −

package com.tutorialspoint;

public class DataBean {
   private String name;
   private String country;

   public String getName() {
      return name;
   }

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

   public String getCountry() {
      return country;
   }

   public void setCountry(String country) {
      this.country = country;
   }
}

C:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint\DataBeanList.java 文件的内容如下 −

package com.tutorialspoint;

import java.util.ArrayList;

public class DataBeanList {
   public ArrayList<DataBean> getDataBeanList() {
      ArrayList<DataBean> dataBeanList = new ArrayList<DataBean>();

      dataBeanList.add(produce("Manisha", "India"));
      dataBeanList.add(produce("Dennis Ritchie", "USA"));
      dataBeanList.add(produce("V.Anand", "India"));
      dataBeanList.add(produce("Shrinath", "California"));

      return dataBeanList;
   }

   /**
    * This method returns a DataBean object,
    * with name and country set in it.
    */
   private DataBean produce(String name, String country) {
      DataBean dataBean = new DataBean();
      dataBean.setName(name);
      dataBean.setCountry(country);

      return dataBean;
   }
}

Report Generation

我们将使用常规 ANT 构建流程编译并执行上述文件。build.xml 文件(保存在 C:\tools\jasperreports-5.0.1\test 目录下)的内容如下。

导入文件 - baseBuild.xml 从第 Environment Setup 章选取并应该放置在与 build.xml 相同的目录中。

<?xml version = "1.0" encoding = "UTF-8"?>
<project name = "JasperReportTest" default = "viewFillReport" basedir = ".">

   <import file = "baseBuild.xml" />
   <target name = "viewFillReport" depends = "compile,compilereportdesing,run"
      description = "Launches the report viewer to preview
      the report stored in the .JRprint file.">

      <java classname = "net.sf.jasperreports.view.JasperViewer" fork = "true">
         <arg value = "-F${file.name}.JRprint" />
         <classpath refid = "classpath" />
      </java>
   </target>

   <target name = "compilereportdesing" description = "Compiles the JXML file and
      produces the .jasper file.">

      <taskdef name = "jrc"
         classname = "net.sf.jasperreports.ant.JRAntCompileTask">
         <classpath refid = "classpath" />
      </taskdef>

      <jrc destdir = ".">
         <src>
            <fileset dir = ".">
               <include name = "*.jrxml" />
            </fileset>
         </src>
         <classpath refid = "classpath" />
      </jrc>

   </target>

</project>

接下来,让我们打开命令行窗口并进入放置 build.xml 的目录。最后,执行命令 ant -Dmain-class=com.tutorialspoint.JasperReportFill (viewFullReport 是默认目标),如下所示 −

C:\tools\jasperreports-5.0.1\test>ant -Dmain-class=com.tutorialspoint.JasperReportFill
Buildfile: C:\tools\jasperreports-5.0.1\test\build.xml

clean-sample:
   [delete] Deleting directory C:\tools\jasperreports-5.0.1\test\classes
   [delete] Deleting: C:\tools\jasperreports-5.0.1\test\jasper_report_template.jasper
   [delete] Deleting: C:\tools\jasperreports-5.0.1\test\jasper_report_template.jrprint

compile:
   [mkdir] Created dir: C:\tools\jasperreports-5.0.1\test\classes
   [javac] C:\tools\jasperreports-5.0.1\test\baseBuild.xml:28: warning:
   'includeantruntime' was not set, defaulting to build.sysclasspath=last;
   set to false for repeatable builds
   [javac] Compiling 7 source files to C:\tools\jasperreports-5.0.1\test\classes

compilereportdesing:
   [jrc] Compiling 1 report design files.
   [jrc] log4j:WARN No appenders could be found for logger
   (net.sf.jasperreports.engine.xml.JRXmlDigesterFactory).
   [jrc] log4j:WARN Please initialize the log4j system properly.
   [jrc] log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig
   for more info.
   [jrc] File : C:\tools\jasperreports-5.0.1\test\jasper_report_template.jrxml ... OK.

run:
   [echo] Runnin class : com.tutorialspoint.JasperReportFill
   [java] log4j:WARN No appenders could be found for logger
   (net.sf.jasperreports.extensions.ExtensionsEnvironment).
   [java] log4j:WARN Please initialize the log4j system properly.

viewFillReport:
   [java] log4j:WARN No appenders could be found for logger
   (net.sf.jasperreports.extensions.ExtensionsEnvironment).
   [java] log4j:WARN Please initialize the log4j system properly.

BUILD SUCCESSFUL
Total time: 18 seconds

以上编译的结果是在屏幕下方打开一个 JasperViewer 窗口−

report variable example

此处,我们看到每个记录前加了计数。

Report Sections

我们在第 Getting Started 章讨论了一个简单报表模板的结构。JasperReports 根据类似的方法,将报表模板构建为多个部分。部分是具有指定高度的报表部分,可包含报表对象,如线条、矩形、图像或文本字段。

报表引擎在报表填充时遍历所提供的报表数据源的虚拟记录。然后,根据每个部分定义的行为,引擎在适当的时候呈现每个报表部分。例如,针对数据源中的每个记录呈现详细信息部分。发生分页时,按需呈现页眉和页脚部分。

在 JasperReports 中,术语和报表部分也称为 report bands 。部分由一个或多个波段组成。这些部分在报表生成时重复填充,并准备最终的文档。

Main Sections

JasperReports 中的报表模板包含以下主要部分:−

<title></title>

<pageheader></pageheader>

<columnheader></columnheader>

<groupheader></groupheader>

<detail></detail>

<groupfooter></groupfooter>

<columnfooter></columnfooter>

<pagefooter></pagefooter>

<lastpagefooter></lastpagefooter>

<summary></summary>

<nodata></nodata>

<background></background>

下表总结了各个部分 −

S.NO

Section and Description

1

Title 此部分仅出现在报表的开头一次。

2

Page Header 此部分出现在生成文档中每页的开头。

3

Column Header 此部分出现在生成文档中每列的开头。如果报表仅定义一列,则会忽略列头和列脚部分。

4

Group Header 此部分由报表组(第 Groups 章)引入。每次分组表达式更改其值时,分组头部分都会打印在详细信息部分上方。如果定义了多个组,则会按照组定义的顺序打印组头。

5

Detail 此部分会针对报表数据源提供的每行数据重复。详细信息部分可以由多个波段组成。

6

Group Footer 本节由报表组(章节 Groups )引入。当分组表达式的值改变前,组页脚节打印在明细节下方。组页脚始终打印在数据源中的最后一行数据中。如果定义了多个组,则按相反的组定义顺序打印组页脚。

7

Column Footer 本节显示在每列底部。如果报表的列数为 1,则将忽略列头和页脚节。

8

Page Footer 本节显示在每页底部。

9

Last Page Footer 本节在报告的最后一页替换常规的页脚。如果摘要节也存在,则这可能不是文档的最后一页。当摘要信息必须显示在最后一页的底部时,本节有时很有用。

10

Summary 本节仅在报告的末尾出现一次。

11

No Data 当“没有数据打印”报表属性设置为“无数据节”时,将打印本节。如果在报表模板中定义了 <noData> 节,并且数据源为空,则 <noData> 节将是填充时唯一考虑的节,其内容将生成报表输出。

12

Background 背景部分显示在每一页上,且不能溢出至下一页。放置在本节上的元素在页面初始化时间进行评估,并在背景中显示。所有其他页面对象都会显示在背景对象之上。本节对于创建页面水印而言非常有用。

Section, Elements and Attribute Relation

下图显示报表节中元素和属性之间的关系。

report sections

Section Elements

上述所有报表节都是可选的。但是,任何报表模板至少都有一个此类节。每个此类节都包含一个单一的 <*band*> 元素作为其唯一子元素。<*band*> 可以包含零个或多个以下子元素 -

<line>, <rectangle>, <ellipse>, <image>, <staticText>, <textField>, <subReport> 或 <elementGroup>

除了元素组外,每个此类元素都必须包含一个单一的 <*reportElement*> 作为其第一个元素。<*reportElement*> 确定为该特定元素布局数据的方式。与变量和参数不同,报表元素不需要具有名称,因为通常无需在报表模板中获取任何单个元素。

下表汇总了 <*reportElement*> 的属性 -

Attribute

Description

Valid Values

x

指定波段元素的 x 坐标。

一个整数,表示元素的像素 x 坐标。该属性为必需属性。

y

指定波段元素的 y 坐标。

一个整数,表示元素的像素 y 坐标。该属性为必需属性。

width

指定波段元素的宽度。

一个整数,表示元素的像素宽度。该属性为必需属性。

height

指定波段元素的高度。

一个表示元素高度的整型值(像素)。此属性是必需的。

key

条状元素的唯一标识符。

A unique string value.

stretchType

指定当包含条状元素的条状元素拉伸时,该元素如何拉伸

NoStretch (default) - 该元素不会拉伸。 RelativeToTallestObject - 该元素将拉伸以适合其组中最高的对象。 RelativeToBand - 该元素将拉伸以适合条状元素的高度。

positionType

指定当条状元素拉伸时,元素的位置。

Float - 该元素将根据周围元素的大小移动。 FixRelativeToTop (default) - 该元素将保持相对于条状元素顶部处于固定位置。 FixRelativeToBottom - 该元素将保持相对于条状元素底部处于固定位置。

isPrintRepeatedValues

指定是否打印重复值。

true (default) - 将打印重复值。 false - 将不打印重复值。

mode

指定元素的背景模式

Opaque, Transparent

isRemoveLineWhenBlank

指定当元素为空并且在同一水平空间中没有其他元素时,是否应删除该元素。

true, false

isPrintInFirstWholeBand

指定是否必须在整个条状元素中打印该元素,即不会在报表页或栏之间分割的条状元素。

true, false

isPrintWhenDetailOverFlows

指定当条状元素溢出到新页或新栏时是否打印该元素。

true, false

printWhenGroupChanges

指定当指定组更改时将打印该元素。

A string value.

forecolor

指定元素的前景色。

十六进制 RGB 值(前面有 # 字符),或以下预定义值之一:黑色、蓝色、青色、深灰色、灰色、绿色、浅灰色、紫色、橙色、粉红色、红色、黄色、白色。

backcolor

指定元素的背景色。

与前景色有效值相同

Section Attributes

下面是报表部分的属性 -

Height

指定部分的高度(像素)对于特定部分非常重要,在整体报表设计中非常重要。

Print When Expression

布尔表达式,用于确定是否打印节。

Split Allowed

用于指示是否允许节在当前页无法容纳时拆分。如果为 true,则将节转移到下一页。请注意,如果节不适应下一页,则无论标志值如何,都会拆分节。splitType 可采用以下值:

  1. splitType=“Stretch:”拆分拉伸内容。如果节在当前页上拉伸(如果可用空间小于已声明的高度),则将添加到原始高度的区域允许拆分为下一页。

  2. splitType=“Prevent:”阻止在首次尝试时拆分。如果节不适应下一页,则拆分正常进行,因为分隔带拆分预防仅在首次拆分尝试时有效。

  3. splitType=“Immediate:”立即拆分。允许在除了其最顶层元素上方任何位置拆分分隔带。

Example

为了演示每个节,让我们编写报表模板(jasper_report_template.jrxml)。将此文件保存到 C:\tools\jasperreports-5.0.1\test 目录。在此文件中,我们在每个节中显示一个文本(我们上面讨论)。文件内容如下:

<?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 = "jasper_report_template" pageWidth = "300" pageHeight = "300"
   columnWidth = "300" leftMargin = "0" rightMargin = "0"
   topMargin = "0" bottomMargin = "0" >

   <title>
      <band height = "50">

         <textField>
            <reportElement x = "100" y = "16" width = "100" height = "20"/>
            <textElement/>

            <textFieldExpression>
               <![CDATA["Title"]]>
            </textFieldExpression>

         </textField>

      </band>
   </title>

   <pageHeader>
      <band height = "40">

         <textField>
            <reportElement  mode = "Opaque" x = "100" y = "10"
               width = "90" height = "20"/>

            <textElement>
               <font isBold = "true"/>
            </textElement>

            <textFieldExpression>
               <![CDATA["Page Header"]]>
            </textFieldExpression>
         </textField>

      </band>
   </pageHeader>

   <columnHeader>
      <band height = "40">

         <textField>
            <reportElement  x = "100" y = "10" width = "90" height = "20"/>

            <textElement>
               <font isItalic = "true"/>
            </textElement>

            <textFieldExpression>
               <![CDATA["Column Header"]]>
            </textFieldExpression>
         </textField>

      </band>
   </columnHeader>

   <detail>
      <band height ="40">

         <textField>
            <reportElement mode = "Opaque" x = "100" y = "10"
               width = "90" height = "20" backcolor = "#99CCFF"/>
            <textElement/>

            <textFieldExpression>
               <![CDATA["Report Details"]]>
            </textFieldExpression>
         </textField>

      </band>
   </detail>

   <columnFooter>
      <band height = "40">

         <textField>
            <reportElement  x = "100" y = "10" width = "90" height = "20"/>
            <textElement/>

            <textFieldExpression>
               <![CDATA["Column Footer"]]>
            </textFieldExpression>
         </textField>

      </band>
   </columnFooter>

   <pageFooter>
      <band height = "40">

         <textField>
            <reportElement  x = "100" y = "10" width = "90" height = "20"/>
            <textElement/>

            <textFieldExpression>
               <![CDATA["Page Footer"]]>
            </textFieldExpression>
         </textField>

      </band>
   </pageFooter>

   <lastPageFooter>
      <band height = "40">

         <textField>
            <reportElement  x = "100" y = "10" width = "90" height = "20"/>
            <textElement/>

            <textFieldExpression>
               <![CDATA["Last Page Footer"]]>
            </textFieldExpression>
         </textField>

      </band>
   </lastPageFooter>

   <summary>
      <band height = "40">

         <textField>
            <reportElement  x = "100" y = "10" width = "90" height = "20"/>
            <textElement/>

            <textFieldExpression>
               <![CDATA["Summary"]]>
            </textFieldExpression>
         </textField>

      </band>
   </summary>

</jasperReport>

填充和生成报表的 Java 代码如下。让我们将此文件 JasperReportFill.java 保存到 C:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint 目录。

package com.tutorialspoint;

import net.sf.jasperreports.engine.JREmptyDataSource;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperFillManager;

public class JasperReportFill {
   public static void main(String[] args) {
      String sourceFileName = "C://tools/jasperreports-5.0.1/test/" +
         "jasper_report_template.jasper";

      try {
         JasperFillManager.fillReportToFile(sourceFileName, null,
            new JREmptyDataSource());
      } catch (JRException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
      }

   }
}

在此,我们在填充报表时使用 JREmptyDataSource 的一个实例来模拟具有一个记录的数据源,但此单个记录中的所有字段均为 null。

Report Generation

我们将使用常规的 ANT 构建过程编译并执行以上文件。文件 build.xml(保存在 C:\tools\jasperreports-5.0.1\test 目录下)的内容如下。

导入文件 - baseBuild.xml 从第 Environment Setup 章中获取,并应放置在与 build.xml 相同的目录中。

<?xml version = "1.0" encoding = "UTF-8"?>
<project name = "JasperReportTest" default = "viewFillReport" basedir = ".">

   <import file = "baseBuild.xml" />
   <target name = "viewFillReport" depends = "compile,compilereportdesing,run"
      description = "Launches the report viewer to preview
      the report stored in the .JRprint file.">

      <java classname = "net.sf.jasperreports.view.JasperViewer" fork = "true">
         <arg value = "-F${file.name}.JRprint" />
         <classpath refid = "classpath" />
      </java>

   </target>

   <target name = "compilereportdesing" description = "Compiles the JXML file and
      produces the .jasper file.">

      <taskdef name = "jrc"
         classname = "net.sf.jasperreports.ant.JRAntCompileTask">
         <classpath refid = "classpath" />
      </taskdef>

      <jrc destdir = ".">
         <src>
            <fileset dir = ".">
               <include name = "*.jrxml" />
            </fileset>
         </src>
         <classpath refid = "classpath" />
      </jrc>

   </target>

</project>

接下来,让我们打开命令行窗口并转到放置 build.xml 的目录。最后,执行以下命令 ant -Dmain-class=com.tutorialspoint.JasperReportFill (viewFullReport 是默认目标) -

C:\tools\jasperreports-5.0.1\test>ant -Dmain-class=com.tutorialspoint.JasperReportFill
Buildfile: C:\tools\jasperreports-5.0.1\test\build.xml

clean-sample:
   [delete] Deleting directory C:\tools\jasperreports-5.0.1\test\classes
   [delete] Deleting: C:\tools\jasperreports-5.0.1\test\jasper_report_template.jasper
   [delete] Deleting: C:\tools\jasperreports-5.0.1\test\jasper_report_template.jrprint

compile:
   [mkdir] Created dir: C:\tools\jasperreports-5.0.1\test\classes
   [javac] C:\tools\jasperreports-5.0.1\test\baseBuild.xml:28:
   warning: 'includeantruntime' was not set, defau
   [javac] Compiling 1 source file to C:\tools\jasperreports-5.0.1\test\classes

compilereportdesing:
   [jrc] Compiling 1 report design files.
   [jrc] log4j:WARN No appenders could be found for logger
   (net.sf.jasperreports.engine.xml.JRXmlDigesterFac
   [jrc] log4j:WARN Please initialize the log4j system properly.
   [jrc] log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
   [jrc] File : C:\tools\jasperreports-5.0.1\test\jasper_report_template.jrxml ... OK.

run:
   [echo] Runnin class : com.tutorialspoint.JasperReportFill
   [java] log4j:WARN No appenders could be found for logger
   (net.sf.jasperreports.extensions.ExtensionsEnviro
   [java] log4j:WARN Please initialize the log4j system properly.

viewFillReport:
   [java] log4j:WARN No appenders could be found for logger
   (net.sf.jasperreports.extensions.ExtensionsEnviro
   [java] log4j:WARN Please initialize the log4j system properly.

BUILD SUCCESSFUL
Total time: 18 minutes 22 seconds

以上编译的结果是在屏幕下方打开一个 JasperViewer 窗口−

report sections example

在这里,我们可以在每个节中看到打印了一个文本。需要注意的是,由于 JRXML 包含一个 <lastPageFooter> 元素,它将显示在报表的最后一页,而不是显示 <pageFooter> 元素。如果报表有多个列,则只会在报表上显示 <columnHeader> 和 <columnFooter> 元素。

Report Groups

JasperReports 中的组有助于以一种合乎逻辑的方式整理报表上的数据。报表组表示数据源中连续记录的序列,这些记录具有一些共同点,例如某个报表字段的值。报表组由 <group> 元素定义。报表可以有任意数量的组。声明后,可以在整个报表中引用组。

报表组有三个元素:

  1. 组表达式:这表示必须更改的数据以启动一个新的数据组。

  2. 组头节:有助于在分组数据的开头放置标签。

  3. 组尾节:有助于在分组数据的末尾放置标签。

如果在报表填充时迭代遍历数据源时组表达式的值发生更改,则组会中断,并且在结果文档中插入相应的 <groupFooter> 和 <groupHeader> 节。

报表组机制不对数据源提供的的数据执行任何排序。仅当数据源中的记录已经按照报表中使用的组表达式进行排序时,数据分组才会按预期工作。

Group Attributes

<group> 元素包含允许我们控制分组数据如何布局的属性。这些属性总结在下面的表格中:

S.NO

Attribute and Description

1

name 这是强制性的。它通过名称引用报表表达式中的组。它遵循我们为报表参数、字段和报表变量提到的相同命名约定。当您希望引用特定报表组时,它可以在其他 JRXML 属性中使用。

2

isStartNewColumn 当设置为 true 时,每个数据组将从一个新列开始。默认值为 false。

3

isStartNewPage 设定为真时,每组数据将从新页开始,默认值为假。

4

isResetPageNumber 设定为真时,每当新组开始时,报表页码将重置,默认值为假。

5

isReprintHeaderOnEachPage 设定为真时,组头的每一页都将被重新打印,默认值为假。

6

minHeightToStartNewPage 确定为了在当前列放置组头而需要的垂直空间最小量,该量按报告单位指定。

7

footerPosition 呈现组尾在页面中的位置,以及它与后面报表的各节的关系,其值可以是:Normal、StackAtBottom、ForceAtBottom和CollateAtBottom,默认值为Normal。

8

keepTogether 设定为真时,将防止小组在其第一次中断尝试中分离。

Example

让我们在现有的报表模板中添加一个组 ( CountryGroup ),(第 Report Designs 章),统计每个国家的出现次数,并将其显示为小组页脚。组头中,每个记录的计数作为前缀,经过修订的报表模板 (jasper_report_template.jrxml) 如下。将其保存到 C:\tools\jasperreports-5.0.1\test 目录中−

<?xml version = "1.0"?>
<!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 = "jasper_report_template" pageWidth = "595"
   pageHeight = "842" columnWidth = "515"
   leftMargin = "40" rightMargin = "40" topMargin = "50" bottomMargin = "50">

   <parameter name = "ReportTitle" class = "java.lang.String"/>
   <parameter name = "Author" class = "java.lang.String"/>

   <queryString>
      <![CDATA[]]>
   </queryString>

   <field name = "country" class = "java.lang.String">
      <fieldDescription><![CDATA[country]]></fieldDescription>
   </field>

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

   <sortField name = "country" order = "Descending"/>
   <sortField name = "name"/>

   <variable name = "CountryNumber" class = "java.lang.Integer"
      incrementType = "Group" incrementGroup = "CountryGroup"
      calculation = "Count">
      <variableExpression><![CDATA[Boolean.TRUE]]></variableExpression>
   </variable>

   <group name = "CountryGroup" minHeightToStartNewPage = "60">
      <groupExpression><![CDATA[$F{country}]]></groupExpression>

      <groupHeader>
         <band height = "20">

            <textField evaluationTime = "Group" evaluationGroup = "CountryGroup"
               bookmarkLevel = "1">
               <reportElement mode = "Opaque" x = "0" y = "5" width = "515"
                  height = "15" backcolor = "#C0C0C0"/>

               <box leftPadding = "10">
                  <bottomPen lineWidth = "1.0"/>
               </box>
               <textElement/>

               <textFieldExpression class = "java.lang.String">
                  <![CDATA["  " + String.valueOf($V{CountryNumber}) + ". "
                  + String.valueOf($F{country})]]>
               </textFieldExpression>

               <anchorNameExpression>
                  <![CDATA[String.valueOf($F{country})]]>
               </anchorNameExpression>
            </textField>

         </band>
      </groupHeader>

      <groupFooter>
         <band height = "20">

            <staticText>
               <reportElement x = "400" y = "1" width = "60" height = "15"/>
               <textElement textAlignment = "Right"/>
               <text><![CDATA[Count :]]></text>
            </staticText>

            <textField>
               <reportElement x = "460" y = "1" width = "30" height = "15"/>
               <textElement textAlignment = "Right"/>

               <textFieldExpression class = "java.lang.Integer">
                  <![CDATA[$V{CountryGroup_COUNT}]]>
               </textFieldExpression>
            </textField>

         </band>
      </groupFooter>

   </group>

   <title>
      <band height = "70">

         <line>
            <reportElement x = "0" y = "0" width = "515" height = "1"/>
         </line>

         <textField isBlankWhenNull = "true" bookmarkLevel = "1">
            <reportElement x = "0" y = "10" width = "515" height = "30"/>

            <textElement textAlignment = "Center">
               <font size = "22"/>
            </textElement>

            <textFieldExpression class = "java.lang.String">
               <![CDATA[$P{ReportTitle}]]>
            </textFieldExpression>

            <anchorNameExpression>
               <![CDATA["Title"]]>
            </anchorNameExpression>
         </textField>

         <textField isBlankWhenNull = "true">
            <reportElement  x = "0" y = "40" width = "515" height = "20"/>

            <textElement textAlignment = "Center">
               <font size = "10"/>
            </textElement>

            <textFieldExpression class = "java.lang.String">
               <![CDATA[$P{Author}]]>
            </textFieldExpression>
         </textField>

      </band>
   </title>

   <columnHeader>
      <band height = "23">

         <staticText>
            <reportElement mode = "Opaque" x = "0" y = "3" width = "535" height = "15"
               backcolor = "#70A9A9" />

            <box>
               <bottomPen lineWidth = "1.0" lineColor = "#CCCCCC" />
            </box>

            <textElement />
               <text><![CDATA[]]>
            </text>
         </staticText>

         <staticText>
            <reportElement x = "414" y = "3" width = "121" height = "15" />

            <textElement textAlignment = "Center" verticalAlignment = "Middle">
               <font isBold = "true" />
            </textElement>

            <text><![CDATA[Country]]></text>
         </staticText>

         <staticText>
            <reportElement x = "0" y = "3" width = "136" height = "15" />

            <textElement textAlignment = "Center" verticalAlignment = "Middle">
               <font isBold = "true" />
            </textElement>

            <text><![CDATA[Name]]></text>
         </staticText>

      </band>
   </columnHeader>

   <detail>
      <band height = "16">

         <staticText>
            <reportElement mode = "Opaque" x = "0" y = "0" width = "535" height = "14"
               backcolor = "#E5ECF9" />

            <box>
               <bottomPen lineWidth = "0.25" lineColor = "#CCCCCC" />
            </box>

            <textElement />

            <text>
               <![CDATA[]]>
            </text>
         </staticText>

         <textField>
            <reportElement x = "414" y = "0" width = "121" height = "15" />

            <textElement textAlignment = "Center" verticalAlignment = "Middle">
               <font size = "9" />
            </textElement>

            <textFieldExpression class = "java.lang.String">
               <![CDATA[$F{country}]]>
            </textFieldExpression>
         </textField>

         <textField>
            <reportElement x = "0" y = "0" width = "136" height = "15" />
            <textElement textAlignment = "Center" verticalAlignment = "Middle" />

            <textFieldExpression class = "java.lang.String">
               <![CDATA[$F{name}]]>
            </textFieldExpression>
         </textField>

      </band>
   </detail>

</jasperReport>

用于填充报告的 Java 代码保持不变。文件 C:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint\JasperReportFill.java 的内容如下 -

package com.tutorialspoint;

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

import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;

public class JasperReportFill {
   @SuppressWarnings("unchecked")
   public static void main(String[] args) {
      String sourceFileName =
      "C://tools/jasperreports-5.0.1/test/jasper_report_template.jasper";

      DataBeanList DataBeanList = new DataBeanList();
      ArrayList<DataBean> dataList = DataBeanList.getDataBeanList();

      JRBeanCollectionDataSource beanColDataSource =
      new JRBeanCollectionDataSource(dataList);

      Map parameters = new HashMap();
      /**
       * Passing ReportTitle and Author as parameters
       */
      parameters.put("ReportTitle", "List of Contacts");
      parameters.put("Author", "Prepared By Manisha");

      try {
         JasperFillManager.fillReportToFile(
         sourceFileName, parameters, beanColDataSource);
      } catch (JRException e) {
         e.printStackTrace();
      }
   }
}

POJO 文件 C:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint\DataBean.java 的内容如下:

package com.tutorialspoint;

public class DataBean {
   private String name;
   private String country;

   public String getName() {
      return name;
   }

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

   public String getCountry() {
      return country;
   }

   public void setCountry(String country) {
      this.country = country;
   }
}

C:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint\DataBeanList.java 文件的内容如下 −

package com.tutorialspoint;

import java.util.ArrayList;

public class DataBeanList {
   public ArrayList<DataBean> getDataBeanList() {
      ArrayList<DataBean> dataBeanList = new ArrayList<DataBean>();

      dataBeanList.add(produce("Manisha", "India"));
      dataBeanList.add(produce("Dennis Ritchie", "USA"));
      dataBeanList.add(produce("V.Anand", "India"));
      dataBeanList.add(produce("Shrinath", "California"));

      return dataBeanList;
   }

   /**
    * This method returns a DataBean object,
    * with name and country set in it.
    */
   private DataBean produce(String name, String country) {
      DataBean dataBean = new DataBean();
      dataBean.setName(name);
      dataBean.setCountry(country);

      return dataBean;
   }
}

Report Generation

我们将使用常规的 ANT 构建过程编译并执行以上文件。文件 build.xml(保存在 C:\tools\jasperreports-5.0.1\test 目录下)的内容如下。

从第 Environment Setup 章中选取导入文件-baseBuild.xml,并将其放置在与 build.xml 相同的目录中。

<?xml version = "1.0" encoding = "UTF-8"?>
<project name = "JasperReportTest" default = "viewFillReport" basedir = ".">
   <import file = "baseBuild.xml" />

   <target name = "viewFillReport" depends = "compile,compilereportdesing,run"
      description = "Launches the report viewer to preview
      the report stored in the .JRprint file.">

      <java classname = "net.sf.jasperreports.view.JasperViewer" fork = "true">
         <arg value = "-F${file.name}.JRprint" />
         <classpath refid = "classpath" />
      </java>
   </target>

   <target name = "compilereportdesing" description = "Compiles the JXML file and
      produces the .jasper file.">

      <taskdef name = "jrc" classname = "net.sf.jasperreports.ant.JRAntCompileTask">
         <classpath refid = "classpath" />
      </taskdef>

      <jrc destdir = ".">
         <src>
            <fileset dir = ".">
               <include name = "*.jrxml" />
            </fileset>
         </src>
         <classpath refid = "classpath" />
      </jrc>

   </target>

</project>

接下来,让我们打开命令行窗口并进入放置 build.xml 的目录。最后,执行命令 ant -Dmain-class=com.tutorialspoint.JasperReportFill (viewFullReport 是默认目标),如下所示 −

C:\tools\jasperreports-5.0.1\test>ant -Dmain-class=com.tutorialspoint.JasperReportFill
Buildfile: C:\tools\jasperreports-5.0.1\test\build.xml

clean-sample:
   [delete] Deleting directory C:\tools\jasperreports-5.0.1\test\classes
   [delete] Deleting: C:\tools\jasperreports-5.0.1\test\jasper_report_template.jasper
   [delete] Deleting: C:\tools\jasperreports-5.0.1\test\jasper_report_template.jrprint

compile:
   [mkdir] Created dir: C:\tools\jasperreports-5.0.1\test\classes
   [javac] C:\tools\jasperreports-5.0.1\test\baseBuild.xml:28: warning:
   'includeantruntime' was not set, defaulting to build.sysclasspath=last;
   set to false for repeatable builds
   [javac] Compiling 7 source files to C:\tools\jasperreports-5.0.1\test\classes

compilereportdesing:
   [jrc] Compiling 1 report design files.
   [jrc] log4j:WARN No appenders could be found for logger
   (net.sf.jasperreports.engine.xml.JRXmlDigesterFactory).
   [jrc] log4j:WARN Please initialize the log4j system properly.
   [jrc] log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig
   for more info.
   [jrc] File : C:\tools\jasperreports-5.0.1\test\jasper_report_template.jrxml ... OK.

run:
   [echo] Runnin class : com.tutorialspoint.JasperReportFill
   [java] log4j:WARN No appenders could be found for logger
   (net.sf.jasperreports.extensions.ExtensionsEnvironment).
   [java] log4j:WARN Please initialize the log4j system properly.

viewFillReport:
   [java] log4j:WARN No appenders could be found for logger
   (net.sf.jasperreports.extensions.ExtensionsEnvironment).
   [java] log4j:WARN Please initialize the log4j system properly.

BUILD SUCCESSFUL
Total time: 18 seconds

以上编译的结果是在屏幕下方打开一个 JasperViewer 窗口−

report groups example

在此,我们看到每个国家分组,每个国家的出现次数统计显示在每个组的页脚中。

Report Fonts

报表含文本元素,而这些元素各自可具有其单独的字体设定,可使用 <textElement> 标签内的 <*font*> 标签来指定这些设定,报表能够定义许多字体,一旦定义后,它们可作为整个报表其他字体定义的默认字体或基本字体设定来使用。

Report Fonts

报表字体是字体设定的集合,在报表级别声明,在设置文本元素的字体属性时,报表字体可以在整个报表模板中重复使用。

报表字体现已被弃用,请勿使用在文档自身中声明的 <reportFont/> 元素,而应改用 <style/> 元素。

Font Attributes

下表概述了 <*font*> 元素的主要属性−

S.NO

Attribute and Description

1

fontName 字体名称,可以是物理字体、逻辑字体或者来自已注册的 JasperReports 字体扩展的字体家族的名称。

2

size 以磅为单位度量的字体大小,其默认为 10。

3

isBold 指定是否需要粗体字的标志,其默认为 false。

4

isItalic 指定是否需要斜体字的标志,其默认为 false。

5

isUnderline 指定是否需要下划线文字修饰的标志,其默认为 false。

6

isStrikeThrough 指定是否需要删除线文字修饰的标志,其默认为 false。

7

pdfFontName 将文档导出为 PDF 格式时,iText 库所需的同等 PDF 字体的名称。

8

pdfEncoding 同等的 PDF 字符编码,iText 库也需要它。

9

isPdfEmbedded 指定是否将字体嵌入文档本身的标志。其默认为 false。如果设置为 true,则有助于毫无问题地查看 PDF 文档。

Font Types

在 JasperReports 中,字体可分类为:

  1. Logical Fonts −自 Java 平台 1.0 版本以来就已获得认可的五种字体类型称为逻辑字体。这些字体为: Serif, SansSerif, Monospaced, Dialog, and DialogInput 。这些逻辑字体不是安装在系统上的实际字体库。它们只是 Java 运行时认可的字体类型名称。这些字体必须映射到安装在系统上的某些物理字体。

  2. Physical Fonts −这些字体是实际字体库,例如,由 TrueType 或 PostScript 1 型字体组成。物理字体可能是 Arial、Time、Helvetica、Courier 或任何数量的其他字体,包括国际字体。

  3. Font Extensions −借助于对字体扩展的内置支持,JasperReports 库可以在运行时利用通过动态注册的字体。可以使用字体扩展,向 JasperReports 提供字体系列列表。这些列表由相似外观的字体效果和支持特定的区域构成。

如上表所述,我们需要在 fontName 属性中指定物理字体的名称、逻辑字体的名称或注册的 JasperReports 字体扩展中字体系列的名称。

PDF Font Name

当导出报表为 PDF(便携式文档格式)时,JasperReports 库使用 iText 库。可在各种平台上查看 PDF 文件,并且始终外观相同。这部分是因为在此格式中,有一种处理字体的特殊方式。向 PDF 导出时,fontName 属性没有任何作用。存在 pdfFontName 属性,我们需要在此属性中指定字体设置。

iText 库知道如何处理内置字体和 TTF 文件,并且识别以下内置字体名称:

  1. Courier

  2. Courier-Bold

  3. Courier-BoldOblique

  4. Courier-Oblique

  5. Helvetica

  6. Helvetica-Bold

  7. Helvetica-BoldOblique

  8. Helvetica-Oblique

  9. Symbol

  10. Times-Roman

  11. Times-Bold

  12. Times-BoldItalic

  13. Times-Italic

  14. ZapfDingbats

根据 iText 库的先决条件,要使用字体,我们需要将以下内容之一指定为字体名称:

  1. 从上述列表中指定一个内置字体名称。

  2. 一个 TTF(True Type 字体)文件的名称,它可在磁盘上进行定位。

  3. 字体的真实名称,前提是包含该字体的 TTF 文件已经向 iText 注册,或者在注册字体时定义了别名。

基于上述先决条件,pdfFontName 属性可包含以下值之一:

  1. 以上列表中某个内置 PDF 字体的名称。

  2. 导出到 PDF 时可在运行时位于磁盘上的 TTF 文件的名称。

  3. 已注册字体的实际名称。

  4. 对于 iText 作为字体文件注册的字体的键的后缀(net.sf.jasperreports.export.pdf.font 之后的)。

Default Fonts and Inheritance

每个文本元素从其父元素继承字体和样式属性,而其父元素反过来又从其父元素继承这些属性。如果未为元素定义样式和/或字体,那么将在 <jasperReport/> 根元素中声明的默认样式(和/或字体,但现在这不赞扬)被应用。

在 JasperReports 中定义默认样式或字体不是强制性的。如果没有为给定元素定义字体,引擎会查找继承的字体属性,或者如果没有通过这种方式找到属性,则会在 /src/default.jasperreports.properties 文件中查找 net.sf.jasperreports.default.font.name 属性。其值定义了在未为文本元素显式定义字体属性或从其父元素继承字体属性时要使用的字体系列名称。

在 /src/default.jasperreports.properties 文件中定义的主默认字体属性及其值在下表中 -

Property

Description

net.sf.jasperreports.default.font.name=SansSerif

The default font name.

net.sf.jasperreports.default.font.size=10

The default font size.

net.sf.jasperreports.default.pdf.font.name=Helvetica

The default PDF font.

net.sf.jasperreports.default.pdf.encoding=Cp1252

默认 PDF 字符编码。

net.sf.jasperreports.default.pdf.embedded=false

默认情况下不嵌入 PDF 字体。

Example

为了演示如何使用字体和字体属性以获得特定文本外观,我们编写新的报表模板 (jasper_report_template.jrxml)。JRXML 的内容如下。将其保存到 C:\tools\jasperreports-5.0.1\test 目录中。在这里,我们在报表的标题中以各种字体格式显示文本。

<?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 = "jasper_report_template" pageWidth = "595" pageHeight = "842"
   columnWidth = "555" leftMargin = "20" rightMargin = "20" topMargin = "30"
   bottomMargin = "30">

   <title>
      <band height = "682">

      <staticText>
         <reportElement x = "0" y = "50" width = "150" height = "40"/>
         <textElement/>

         <text>
            <![CDATA[Welcome to TutorialsPoint!]]>
         </text>
      </staticText>

      <staticText>
         <reportElement x = "160" y = "50" width = "390" height = "40"/>
         <textElement/>

         <text>
           <![CDATA[<staticText>
           <reportElement x = "0" y = "50" width = "150" height = "40"/>
           <text>Welcome to TutorialsPoint!</text></staticText>]]>
         </text>
      </staticText>

      <staticText>
         <reportElement x = "0" y = "100" width = "150" height = "40"/>

         <textElement>
            <font size = "12"/>
         </textElement>

         <text><![CDATA[Welcome to TutorialsPoint!]]></text>
      </staticText>

      <staticText>
         <reportElement x = "160" y = "100" width = "390" height = "40"/>
         <textElement/>

         <text>
            <![CDATA[<staticText>
            <reportElement x = "0" y = "100" width = "150" height = "40"/>

            <textElement>
               <font size = "14"/>
            </textElement>

            <text> Welcome to TutorialsPoint!</text></staticText>]]>
         </text>
      </staticText>

      <staticText>
         <reportElement x = "0" y = "150" width = "150" height = "40"/>

         <textElement>
            <font fontName = "DejaVu Serif" size = "12" isBold = "false"/>
         </textElement>

         <text><![CDATA[Welcome to TutorialsPoint!]]></text>
      </staticText>

      <staticText>
         <reportElement x = "160" y = "150" width = "390" height = "40"/>
         <textElement/>

         <text>
            <![CDATA[<staticText>
            <reportElement x = "0" y = "250" width = "150" height = "40"/>

            <textElement>
               <font fontName = "DejaVu Serif" size = "12" isBold = "false"/>
            </textElement>

            <text>Welcome to TutorialsPoint!</text></staticText>]]>
         </text>
      </staticText>

      <staticText>
         <reportElement x = "0" y = "200" width = "150" height = "40"/>

         <textElement>
            <font fontName = "DejaVu Serif" size = "12" isBold = "true"/>
         </textElement>

         <text><![CDATA[Welcome to TutorialsPoint!]]></text>
      </staticText>

      <staticText>
         <reportElement x = "160" y = "200" width = "390" height = "40"/>
         <textElement/>

         <text>
            <![CDATA[<staticText>
            <reportElement x = "0" y = "300" width = "150" height = "40"/>

            <textElement>
               <font fontName = "DejaVu Serif" size = "12" isBold = "true"/>
            </textElement>

            <text>Welcome to TutorialsPoint!</text></staticText>]]>
         </text>
      </staticText>

      <staticText>
         <reportElement x = "0" y = "250" width = "150" height = "40"/>

         <textElement>
            <font fontName = "Monospaced" size = "12" isItalic = "true"
               isUnderline = "true" pdfFontName = "Courier-Oblique"/>
         </textElement>

         <text><![CDATA[Welcome to TutorialsPoint!]]></text>
      </staticText>

      <staticText>
         <reportElement x = "160" y = "250" width = "390" height = "40"/>
         <textElement/>

         <text>
            <![CDATA[<staticText>
            <reportElement x = "0" y = "350" width = "150" height = "40"/>

            <textElement>
               <font fontName = "Monospaced" size = "12" isItalic = "true"
                  isUnderline = "true" pdfFontName = "Courier-Oblique"/>
            </textElement>

            <text>Welcome to TutorialsPoint!</text></staticText>]]>
         </text>
      </staticText>

      <staticText>
         <reportElement x = "0" y = "300" width = "150" height = "40"/>

         <textElement>
            <font fontName = "Monospaced" size = "12" isBold = "true"
               isStrikeThrough = "true" pdfFontName = "Courier-Bold"/>
         </textElement>
         <text><![CDATA[Welcome to TutorialsPoint!]]></text>
      </staticText>

      <staticText>
         <reportElement x = "160" y = "300" width = "390" height = "40"/>
         <textElement/>

         <text>
            <![CDATA[<staticText>
            <reportElement x = "0" y = "400" width = "150" height = "40"/>

            <textElement>
               <font fontName = "Monospaced" size = "12" isBold = "true"
                  isStrikeThrough = "true" pdfFontName = "Courier-Bold"/>
            </textElement>

            <text>Welcome to TutorialsPoint!</text></staticText>]]>
         </text>
      </staticText>

      <staticText>
         <reportElement x = "0" y = "350" width = "150" height = "40"
            forecolor = "#FF0000"/>

         <textElement>
            <font size = "14"/>
         </textElement>

         <text><![CDATA[Welcome to TutorialsPoint!]]></text>
      </staticText>

      <staticText>
         <reportElement x = "160" y = "350" width = "390" height = "40"/>
         <textElement/>

         <text>
            <![CDATA[<staticText>
            <reportElement x = "0" y = "450" width = "150" height = "40"
               forecolor = "red"/>

            <textElement><font size = "14"/></textElement>
            <text>Welcome to TutorialsPoint!</text></staticText>]]>
         </text>
      </staticText>

      <staticText>
         <reportElement x = "0" y = "400" width = "150" height = "40" mode = "Opaque"
            forecolor = "#00FF00" backcolor = "#FFFF00"/>

         <textElement>
            <font fontName = "Serif" size = "12" isBold = "true"
               pdfFontName = "Times-Bold"/>
         </textElement>

         <text><![CDATA[Welcome to TutorialsPoint!]]></text>
      </staticText>

      <staticText>
         <reportElement x = "160" y = "400" width = "390" height = "40"/>
         <textElement/>

         <text>
            <![CDATA[<staticText>
            <reportElement x = "0" y = "500" width = "150" height = "40"
               forecolor = "green" backcolor = "#FFFF00" mode = "Opaque"/>

            <textElement>
               <font fontName = "Serif" size = "12" isBold = "true"
                  pdfFontName = "Times-Bold"/>
            </textElement>

            <text>Welcome to TutorialsPoint!</text></staticText>]]>
         </text>
      </staticText>

      <staticText>
         <reportElement x = "0" y = "450" width = "150" height = "40" mode = "Opaque"
            forecolor = "#0000FF" backcolor = "#FFDD99"/>

         <textElement textAlignment = "Center" verticalAlignment = "Middle">
            <font fontName = "SansSerif" size = "12" isBold = "false"
            isItalic = "true" pdfFontName = "Sans.Slanted" isPdfEmbedded = "true"/>
         </textElement>

         <text><![CDATA[Welcome to TutorialsPoint!]]></text>
      </staticText>

      <staticText>
         <reportElement x = "160" y = "450" width = "390" height = "40"/>
         <textElement/>

         <text>
            <![CDATA[<staticText>
            <reportElement x = "0" y = "550" width = "150" height = "90"
               forecolor = "blue" backcolor = "#FFDD99" mode = "Opaque"/>

            <textElement textAlignment = "Center" verticalAlignment = "Middle">
               <font fontName = "SansSerif" size = "12" isBold = "false"
                  pdfFontName = "Sans.Slanted" isPdfEmbedded = "true"/>
            </textElement>

            <text>Welcome to TutorialsPoint!</text></staticText>]]>
         </text>
      </staticText>

      <staticText>
         <reportElement mode = "Opaque" x = "0" y = "500" width = "150" height = "40"
            forecolor = "#FF0000" backcolor = "#99DDFF"/>

         <textElement textAlignment = "Right" verticalAlignment = "Bottom">
            <font fontName = "SansSerif" size = "12" isBold = "true"
               pdfFontName = "DejaVu Sans Bold" isPdfEmbedded = "true"/>
         </textElement>

         <text><![CDATA[Welcome to TutorialsPoint!]]></text>
      </staticText>

      <staticText>
         <reportElement x = "160" y = "500" width = "390" height = "40"/>
         <textElement/>

         <text>
            <![CDATA[<staticText>
            <reportElement x = "0" y = "650" width = "150" height = "90"    forecolor = "red"
               backcolor = "#99DDFF" mode = "Opaque"/>

            <textElement textAlignment = "Right" verticalAlignment = "Bottom">
               <font fontName = "SansSerif" size = "12" isBold = "true"
                  pdfFontName = "DejaVu Sans Bold" isPdfEmbedded = "true"/>
            </textElement>

            <text>Welcome to TutorialsPoint!</text></staticText>]]>
         </text>

      </staticText>

   </band>
</title>

</jasperReport>

填充并生成报表的 java 代码如下所示。让我们将此文件 JasperFontsReportFill.java 保存到 C:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint 目录中。

package com.tutorialspoint;

import net.sf.jasperreports.engine.JREmptyDataSource;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperFillManager;

public class JasperFontsReportFill {
   public static void main(String[] args) {
      String sourceFileName = "C://tools/jasperreports-5.0.1/test/" +
         "jasper_report_template.jasper";

      try {
         JasperFillManager.fillReportToFile(sourceFileName, null,
            new JREmptyDataSource());
      } catch (JRException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
      }

   }
}

在这里,我们在填充报表时使用 JREmptyDataSource 实例来模拟一个包含一条记录的数据源,但所有字段都为 null。

Report Generation

我们将使用常规 ANT 构建流程编译并执行上述文件。build.xml 文件(保存在 C:\tools\jasperreports-5.0.1\test 目录下)的内容如下。

导入文件 - baseBuild.xml 从第 Environment Setup 章节中选取,且应放置在与 build.xml 相同的目录中。

<?xml version = "1.0" encoding = "UTF-8"?>
<project name = "JasperReportTest" default = "viewFillReport" basedir = ".">
   <import file = "baseBuild.xml" />

   <target name = "viewFillReport" depends = "compile,compilereportdesing,run"
      description = "Launches the report viewer to preview the report
      stored in the .JRprint file.">

      <java classname = "net.sf.jasperreports.view.JasperViewer" fork = "true">
         <arg value = "-F${file.name}.JRprint" />
         <classpath refid = "classpath" />
      </java>

   </target>

   <target name = "compilereportdesing" description = "Compiles the JXML file and
      produces the .jasper file.">

      <taskdef name = "jrc" classname = "net.sf.jasperreports.ant.JRAntCompileTask">
         <classpath refid = "classpath" />
      </taskdef>

      <jrc destdir = ".">
         <src>
            <fileset dir = ".">
               <include name = "*.jrxml" />
            </fileset>
         </src>
         <classpath refid = "classpath" />
      </jrc>

   </target>

</project>

接下来,让我们打开命令行窗口并转到放置 build.xml 的目录。最后,执行命令 ant -Dmain-class=com.tutorialspoint.JasperFontsReportFill (viewFullReport 为默认目标),如下所示 -

C:\tools\jasperreports-5.0.1\test>ant -Dmain-class=com.tutorialspoint.JasperFontsReportFill
Buildfile: C:\tools\jasperreports-5.0.1\test\build.xml

clean-sample:
   [delete] Deleting directory C:\tools\jasperreports-5.0.1\test\classes
   [delete] Deleting: C:\tools\jasperreports-5.0.1\test\jasper_report_template.jasper
   [delete] Deleting: C:\tools\jasperreports-5.0.1\test\jasper_report_template.jrprint

compile:
   [mkdir] Created dir: C:\tools\jasperreports-5.0.1\test\classes
   [javac] C:\tools\jasperreports-5.0.1\test\baseBuild.xml:28:
   warning: 'includeantruntime' was not set, defaulting to build.
   [javac] Compiling 5 source files to C:\tools\jasperreports-5.0.1\test\classes

compilereportdesing:
   [jrc] Compiling 1 report design files.
   [jrc] log4j:WARN No appenders could be found for logger
   (net.sf.jasperreports.engine.xml.JRXmlDigesterFactory).
   [jrc] log4j:WARN Please initialize the log4j system properly.
   [jrc] log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
   [jrc] File : C:\tools\jasperreports-5.0.1\test\jasper_report_template.jrxml ... OK.

run:
   [echo] Runnin class : com.tutorialspoint.JasperFontsReportFill
   [java] log4j:WARN No appenders could be found for logger
   (net.sf.jasperreports.extensions.ExtensionsEnvironment).
   [java] log4j:WARN Please initialize the log4j system properly.

viewFillReport:
   [java] log4j:WARN No appenders could be found for logger
   (net.sf.jasperreports.extensions.ExtensionsEnvironment).
   [java] log4j:WARN Please initialize the log4j system properly.

BUILD SUCCESSFUL
Total time: 45 minutes 3 seconds

作为上述编译的结果,一个 JasperViewer 窗口会打开,如以下给出的屏幕截图所示 -

report fonts example

在这里,我们可以看到文本“欢迎来到 TutorialsPoint”以不同的字体格式显示。

Unicode Support

在 JasperReports 中,处理文本需要一些专门的工具来处理字符表示和文本格式化属性。任何文本都可以看作具有特定表示结构的字符序列。文本外观包括布局(和段落)和字体设置。但在大多数情况下,文本布局保持不变,在不同区域设置中运行报表时,字体设置可能会发生变化。

我们知道,不同的语言需要不同的字符集来表示特定字符。因此,处理文本意味着处理字体。但是,有关如何在 JasperReports 中使用字体的详细讨论可在章节 Report Fonts 中找到。

有关给定报表中文本内容的一项主要功能是使其国际化的可能性。这意味着,我们可以在不同的本地化环境中运行报表,使用不同的语言和其他本地化设置,而无需进行任何硬编码修改。当报表打算国际化时,字符编码是一项重要功能。

Character Encoding

字符是传达有意义信息的最小书写单位。它是一个抽象概念,字符没有视觉外观。“大写拉丁语 A”不同于“小写拉丁语 a”以及“大写西里尔语 A”和“大写希腊 Alpha”。

字符的可视表示称为 glyph 。某一组字形称为 font 。“大写拉丁语 A”、“大写西里尔语 A”和“大写希腊 Alpha”可能具有相同的字形,但它们是不同的字符。同时,在 Times New Roman、Gill Sans 和 Poetica Chancery Italic 中,“大写拉丁语 A”的字形看起来可能非常不同,但它们仍然表示相同的字符。

可用字符集称为字符库。库中给定字符的位置(索引)称为其代码位置或代码点。在给定库中用数字表示代码点的方法称为 character encoding

编码通常用八位字节表示。八位字节是一组八个二进制数字,即八个一和零。一个八位字节可以用 0 到 255 或 0x00 到 0xFF(使用十六进制符号)之间的数值范围表示。

Unicode

Unicode 是一种字符库,其中包含世界上大多数语言中使用的字符。它可以容纳数百万个字符,并且已经包含数十万个字符。Unicode 被划分为 64K 字符的“平面”。在大多数情况下,只使用一个平面,称为基本多语言平面或 BMP。

UTF-8 是推荐的编码。它使用可变数量的八位字节来表示不同的字符。

在 JRXML 文件中,对编码属性在标题中进行了指定。在报告编译过程中,它用于对 XML 内容进行解码。例如,如果报告仅包含法语单词和 ç、é、â 等字符,那么 ISO-8859-1(又名 Latin-1)编码就足够了。

<?xml version = "1.0" encoding = "ISO-8859-1"?>

如上所见,理想情况下,我们可以选择适合最小字符集的编码,它可以正确显示文档中的所有字符。但在处理多语言文档(即包含拼写了多种语言的单词的文档)时,应选择适合最小字符集的编码,即使它们属于不同的语言,也能正确显示文档中的所有字符。能够处理多语言文档的字符编码之一是 UTF-8 ,它用作 JasperReports 的默认编码值。

在国际化过程中,文本通常保存在资源包文件中,而不是保存在文档中。因此,有时 JRXML 本身看起来完全兼容 ASCII,但运行时生成的报告确实包含无法通过 ASCII 读取的文本。因此,对于特定类型的文档导出格式(如 CSV、HTML、XHTML、XML 和文本),人们还必须了解生成文档的编码。不同的语言由不同的字符编码提供支持。因此,每次我们都需要在本地化环境中运行报告。此外,我们还必须知道,哪个是最适合生成文档语言的字符编码。在这种情况下,JRXML 文件中自行定义的编码属性可能不再有用。

要解决此类问题,我们可以使用一个称为 net.sf.jasperreports.export.character.encoding 的导出自定义属性。此导出自定义属性默认为 UTF-8,并且存在于 JasperReports 中。

此默认值在 default.jasperreports.properties 文件中设置。对于导出时的更具体选项, CHARACTER_ENCODING 导出参数也可用。

Example

为了演示在 Jasperreports 中使用 unicode 支持,我们新建一个报告模板(jasper_report_template.jrxml)。 Save it to C:\tools\jasperreports-5.0.1\test 目录。在这里,我们将使用 Unicode 字符(\uXXXX)显示不同语言的文本。使用 UTF-8 编码的任何字符都可以仅使用其 4 位十六进制代码进行显示。例如,希腊字母 Γ 可以写成 \u0393。当遇到此类表示法时,引擎会调用字符集中适当的字符表示法,并且只会打印出该特定字符。JRXML 的内容如下所示:

<?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 = "jasper_report_template" language = "groovy" pageWidth = "595"
   pageHeight = "842" columnWidth = "555" leftMargin = "20" rightMargin = "20"
   topMargin = "20" bottomMargin = "20">

   <parameter name = "GreekText" class = "java.lang.String" isForPrompting = "false">
      <defaultValueExpression><![CDATA["\u0394\u03B5\u03BD "+
         "\u03BA\u03B1\u03C4\u03B1\u03BB\u03B1\u03B2\u03B1\u03AF"+
         "\u03BD\u03C9 \u0395\u03BB\u03BB\u03B7\u03BD\u03B9\u03BA\u03AC"]]>
      </defaultValueExpression>
   </parameter>

   <parameter name = "CyrillicText" class = "java.lang.String" isForPrompting = "false">
      <defaultValueExpression><![CDATA["\u042F \u043D\u0435 "+
         "\u043C\u043E\u0433\u0443 \u043F\u043E\u043D\u044F\u0442\u044C "+
         "\u0433\u0440\u0435\u0447\u0435\u0441\u043A\u0438\u0439"]]>
      </defaultValueExpression>
   </parameter>

   <parameter name = "ArabicText" class = "java.lang.String" isForPrompting = "false">
      <defaultValueExpression><![CDATA["\u0627\u0646\u0646\u0649 \u0644\u0627 "+
         "\u0627\u0641\u0647\u0645 \u0627\u0644\u0644\u063A\u0629 "+
         "\u0627\u0644\u0639\u0631\u0628\u064A\u0629"]]>
      </defaultValueExpression>
   </parameter>

   <parameter name = "HebrewText" class = "java.lang.String" isForPrompting = "false">
      <defaultValueExpression><![CDATA["\u05D0\u05E0\u05D9 \u05DC\u05D0 "+
         "\u05DE\u05D1\u05D9\u05DF \u05E2\u05D1\u05E8\u05D9\u05EA"]]>
      </defaultValueExpression>
   </parameter>

   <title>
      <band height = "782">

         <textField>
            <reportElement x = "0" y = "50" width = "200" height = "60"/>

            <textElement>
               <font fontName = "DejaVu Sans" size = "14"/>
            </textElement>

            <textFieldExpression class = "java.lang.String">
               <![CDATA[$P{GreekText} + "\n" + $P{CyrillicText}]]>
            </textFieldExpression>
         </textField>

         <staticText>
            <reportElement x = "210" y = "50" width = "340" height = "60"/>
            <textElement/>

            <text>
               <![CDATA["GreekText and CyrillicText"]]>
            </text>
         </staticText>

         <textField>
            <reportElement x = "0" y = "120" width = "200" height = "60"/>

            <textElement>
               <font fontName = "DejaVu Sans" size = "14" isBold = "true"/>
            </textElement>

            <textFieldExpression class = "java.lang.String">
               <![CDATA[$P{GreekText} + "\n" + $P{CyrillicText}]]>
            </textFieldExpression>

         </textField>

         <staticText>
            <reportElement x = "210" y = "120" width = "340" height = "60"/>
            <textElement/>
            <text><![CDATA["GreekText and CyrillicText"]]></text>
         </staticText>

         <textField>
            <reportElement x = "0" y = "190" width = "200" height = "60"/>

            <textElement>
               <font fontName = "DejaVu Sans" size = "14" isItalic = "true"
                  isUnderline = "true"/>
            </textElement>

            <textFieldExpression class = "java.lang.String">
               <![CDATA[$P{GreekText} + "\n" + $P{CyrillicText}]]>
            </textFieldExpression>

         </textField>

         <staticText>
            <reportElement x = "210" y = "190" width = "340" height = "60"/>
            <textElement/>
            <text><![CDATA["GreekText and CyrillicText"]]></text>
         </staticText>

         <textField>
            <reportElement x = "0" y = "260" width = "200" height = "60"/>

            <textElement>
               <font fontName = "DejaVu Sans" size = "14" isBold = "true"
                  isItalic = "true" isUnderline = "true"/>
            </textElement>

            <textFieldExpression class = "java.lang.String">
               <![CDATA[$P{GreekText} + "\n" + $P{CyrillicText}]]>
            </textFieldExpression>

         </textField>

         <staticText>
            <reportElement x = "210" y = "260" width = "340" height = "60"/>
            <textElement/>
            <text><![CDATA["GreekText and CyrillicText"]]></text>
         </staticText>

         <textField>
            <reportElement x = "0" y = "330" width = "200" height = "60"/>

            <textElement textAlignment = "Right">
               <font fontName="DejaVu Sans" size = "22"/>
            </textElement>

            <textFieldExpression class = "java.lang.String">
               <![CDATA[$P{ArabicText}]]>
            </textFieldExpression>

         </textField>

         <textField>
            <reportElement x = "210" y = "330" width = "340" height = "60"/>

            <textElement textAlignment = "Right">
               <font fontName = "DejaVu Sans" size = "22"/>
            </textElement>

            <textFieldExpression class = "java.lang.String">
               <![CDATA[$P{HebrewText}]]>
            </textFieldExpression>

         </textField>

      </band>
   </title>

</jasperReport>

在上述文件中,我们可以看到 UTF-8 编码的存在。本地化的 Unicode 文本片段也存储在文档参数中。

用于填充和生成报告的 java 代码如下。我们将此文件保存在 JasperUnicodeReportFill.java 于 C:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint 目录中。

package com.tutorialspoint;

import net.sf.jasperreports.engine.JREmptyDataSource;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperFillManager;

public class JasperUnicodeReportFill {
   public static void main(String[] args) {
      String sourceFileName ="C://tools/jasperreports-5.0.1/test/" +
         "jasper_report_template.jasper";

      try {
         JasperFillManager.fillReportToFile(sourceFileName, null,
            new JREmptyDataSource());
      } catch (JRException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
      }

   }
}

在此处,我们在使用 JREmptyDataSource 填充报告时模拟了一个数据源,其中只有一条记录,但该单条记录中的所有字段都为空。

Report Generation

我们将使用常规的 ANT 构建过程编译并执行以上文件。文件 build.xml(保存在 C:\tools\jasperreports-5.0.1\test 目录下)的内容如下。

导入文件 - baseBuild.xml 从第 Environment Setup 章节中选取,且应放置在与 build.xml 相同的目录中。

<?xml version = "1.0" encoding = "UTF-8"?>
<project name = "JasperReportTest" default = "viewFillReport" basedir = ".">
   <import file = "baseBuild.xml" />

   <target name = "viewFillReport" depends = "compile,compilereportdesing,run"
      description = "Launches the report viewer to preview the report
      stored in the .JRprint file.">

      <java classname = "net.sf.jasperreports.view.JasperViewer" fork = "true">
         <arg value = "-F${file.name}.JRprint" />
         <classpath refid = "classpath" />
      </java>

   </target>

   <target name = "compilereportdesing" description = "Compiles the JXML file and
      produces the .jasper file.">

      <taskdef name = "jrc" classname = "net.sf.jasperreports.ant.JRAntCompileTask">
         <classpath refid = "classpath" />
      </taskdef>

      <jrc destdir = ".">
         <src>
            <fileset dir = ".">
               <include name = "*.jrxml" />
            </fileset>
         </src>
         <classpath refid = "classpath" />
      </jrc>

   </target>

</project>

接下来,我们打开命令行窗口并转到放置 build.xml 的目录。最后,执行命令 ant -Dmain-class=com.tutorialspoint.JasperUnicodeReportFill (viewFullReport 是默认目标),如下所示:

C:\tools\jasperreports-5.0.1\test>ant  -Dmain-class=com.tutorialspoint.JasperUnicodeReportFill
Buildfile: C:\tools\jasperreports-5.0.1\test\build.xml

clean-sample:
   [delete] Deleting directory C:\tools\jasperreports-5.0.1\test\classes
   [delete] Deleting: C:\tools\jasperreports-5.0.1\test\jasper_report_template.jasper
   [delete] Deleting: C:\tools\jasperreports-5.0.1\test\jasper_report_template.jrprint

compile:
   [mkdir] Created dir: C:\tools\jasperreports-5.0.1\test\classes
   [javac] C:\tools\jasperreports-5.0.1\test\baseBuild.xml:28:
   warning: 'includeantruntime' was not set, defaulting t
   [javac] Compiling 1 source file to C:\tools\jasperreports-5.0.1\test\classes

compilereportdesing:
   [jrc] Compiling 1 report design files.
   [jrc] log4j:WARN No appenders could be found for logger
   (net.sf.jasperreports.engine.xml.JRXmlDigesterFactory).
   [jrc] log4j:WARN Please initialize the log4j system properly.
   [jrc] log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
   [jrc] File : C:\tools\jasperreports-5.0.1\test\jasper_report_template.jrxml ... OK.

run:
   [echo] Runnin class : com.tutorialspoint.JasperUnicodeReportFill
   [java] log4j:WARN No appenders could be found for logger
   (net.sf.jasperreports.extensions.ExtensionsEnvironment).
   [java] log4j:WARN Please initialize the log4j system properly.

viewFillReport:
   [java] log4j:WARN No appenders could be found for logger
   (net.sf.jasperreports.extensions.ExtensionsEnvironment).
   [java] log4j:WARN Please initialize the log4j system properly.

BUILD SUCCESSFUL
Total time: 4 minutes 1 second

作为上述编译的结果,一个 JasperViewer 窗口会打开,如以下给出的屏幕截图所示 -

report unicode example

在这里,我们可以看到显示的文本属于不同的语言。我们还可以看到,这些语言分组在同一页面上,而且还混入同一文本元素中。

Report Styles

JasperReports 提供了一项 <style> 功能,用于控制报告模板中的文本属性。此元素是在报告级别声明的样式设置的集合。诸如前景色、背景色、字体是否加粗、倾斜或正常、字体大小、字体边框以及许多其他属性都受 <style> 元素控制。样式可以扩展其他样式,并且还可以添加或覆盖父样式的属性。

Style Properties

<style> 元素包含许多属性。下表列出了一些最常用的属性:

S.NO

Attribute and Description

1

name 是必需的。它必须是唯一的,因为它在整个报告中都引用了相应的报告样式。

2

isDefault 表示此样式是否是文档的默认样式。

3

style 是对父样式的引用。

4

mode 指定元素的透明度。可能的值是不透明和透明。

5

forecolor 是对象的ForegroundColor。

6

backcolor 是对象的背景颜色。

7

fill 确定用于填充对象的填充图案。目前,允许的单值是实心。

6

radius 指定矩形角弧的半径。

7

scaleImage 仅为图像指定比例。可能的值:剪辑、填满框架、保留形状、实际高度和实际大小。

8

hAlign 指定水平对齐方式。可能的值:左、中、右和两端对齐。

9

vAlign 指定垂直对齐方式。可能的值:上、中和下。

10

rotation 指定元素的旋转。可能的值:无、左、右和倒置。

11

lineSpacing 指定文本行之间的行距。可能的值:单行、1_1_2、双行。

12

markup 指定带样式文本的标记样式。

13

fontName Specifies the font name.

14

fontSize Specifies the font size.

15

isBold 指示字体样式是否为粗体。

16

isItalic 指示字体样式是否为斜体。

17

isUnderline 指示字体样式是否有下划线。

18

isStrikeThrough 指示字体样式是否有删除线。

19

pdfFontName 指定相关的 PDF 字体名称。

20

pdfEncoding 指定 PDF 输出格式的字符编码。

22

isPdfEmbedded 指示是否嵌入 PDF 字体。

23

pattern 指定格式化文本的格式图案。

24

isBlankWhenNull 指示如果表达式求值为 null,是否应显示空字符串(空格)。

Conditional Styles

在某些情况下,仅当满足特定条件时才应应用样式(例如,交替显示报表详细信息部分中相邻行的颜色)。这可以通过使用条件样式来实现。

条件样式有两个元素−

  1. a Boolean condition expression

  2. a style

样式仅在条件评估结果为真时使用。

Applying Styles to Report Elements

任何类型的报表元素都可以使用 style 属性引用报表样式定义。因此,样式定义中所有适用于当前元素的样式属性都将被继承。要覆盖继承的值,可以使用在报表元素级别指定的样式属性。

Style Templates

可以通过在公共位置定义样式来制作具有共同外观的一组报表。然后,报表模板可以引用此公共样式模板。样式模板是包含一个或多个样式定义的 XML 文件。惯例上样式模板文件使用 *.jrtx 扩展名,但这不是强制性的。

样式模板包含以下元素 -

  1. <jasperTemplate> - 这是样式模板文件的根元素。

  2. <template> - 此元素用于包含对其他模板文件引用的引用。该元素的内容将解释为所引用的模板文件的位置。

  3. <style> - 此元素与报表设计模板 (JRXML 文件) 中名称相同元素是相同的,除了样式模板中的样式不能包含条件样式。此限制是由条件样式涉及报表表达式,而表达式只能在单个报表定义的上下文中解释这一事实造成的。

对样式模板的引用作为 <template> 元素包含在 JRXML 报表中。样式模板在报表填充时加载,并在所有模板加载后解析样式名称引用。在加载样式模板和将样式名称解析为样式时,将创建样式模板的树/图,树的顶部是报表中定义的样式集。在此树上,样式名称引用将解析为深度优先遍历中与名称匹配的最后一个样式。

Example

让我们尝试一下条件样式和样式模板。让我们将 <*style*> 元素 alternateStyle 添加到我们现有的报表模板(章节 Report Designs )。根据条件,偶数计算的字体颜色将变为蓝色。我们还包含了一个样式模板 "styles.jrtx" 。修改后的报表模板 (jasper_report_template.jrxml) 如下所示。将其保存到 C:\tools\jasperreports-5.0.1\test 目录 -

<?xml version = "1.0"?>
<!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 = "jasper_report_template" pageWidth = "595"
   pageHeight = "842" columnWidth = "515"
   leftMargin = "40" rightMargin = "40" topMargin = "50" bottomMargin = "50">

   <template>"styles.jrtx"</template>

   <style name = "alternateStyle" fontName = "Arial" forecolor = "red">
      <conditionalStyle>
         <conditionExpression>
            <![CDATA[new Boolean($V{countNumber}.intValue() % 2 == 0)]]>
         </conditionExpression>

         <style forecolor = "blue" isBold = "true"/>
      </conditionalStyle>
   </style>

   <parameter name = "ReportTitle" class = "java.lang.String"/>
   <parameter name = "Author" class = "java.lang.String"/>

   <queryString>
      <![CDATA[]]>
   </queryString>

   <field name = "country" class = "java.lang.String">
      <fieldDescription><![CDATA[country]]></fieldDescription>
   </field>

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

   <variable name = "countNumber" class = "java.lang.Integer" calculation = "Count">
      <variableExpression><![CDATA[Boolean.TRUE]]></variableExpression>
   </variable>

   <title>
      <band height = "70">

         <line>
            <reportElement x = "0" y = "0" width = "515" height = "1"/>
         </line>

         <textField isBlankWhenNull = "true" bookmarkLevel = "1">
            <reportElement x = "0" y = "10" width = "515" height = "30"/>

            <textElement textAlignment = "Center">
               <font size = "22"/>
            </textElement>

            <textFieldExpression class = "java.lang.String">
               <![CDATA[$P{ReportTitle}]]>
            </textFieldExpression>

            <anchorNameExpression><![CDATA["Title"]]></anchorNameExpression>
         </textField>

         <textField isBlankWhenNull = "true">
            <reportElement  x = "0" y = "40" width = "515" height = "20"/>

            <textElement textAlignment = "Center">
               <font size = "10"/>
            </textElement>

            <textFieldExpression class = "java.lang.String">
               <![CDATA[$P{Author}]]>
            </textFieldExpression>

         </textField>

      </band>
   </title>

   <columnHeader>
      <band height = "23">

         <staticText>
            <reportElement mode = "Opaque" x = "0" y = "3"
               width = "535" height = "15" backcolor = "#70A9A9" />

            <box>
               <bottomPen lineWidth = "1.0" lineColor = "#CCCCCC" />
            </box>

            <textElement />

            <text>
               <![CDATA[]]>
            </text>

         </staticText>

         <staticText>
            <reportElement x = "414" y = "3" width = "121" height = "15" />

            <textElement textAlignment = "Center" verticalAlignment = "Middle">
               <font isBold = "true" />
            </textElement>

            <text><![CDATA[Country]]></text>
         </staticText>

         <staticText>
            <reportElement x = "0" y = "3" width = "136" height = "15" />

            <textElement textAlignment = "Center" verticalAlignment = "Middle">
               <font isBold = "true" />
            </textElement>

            <text><![CDATA[Name]]></text>
         </staticText>

      </band>
   </columnHeader>

   <detail>
      <band height = "16">

         <staticText>
            <reportElement mode = "Opaque" x = "0" y = "0"
               width = "535" height = "14" backcolor = "#E5ECF9" />

            <box>
               <bottomPen lineWidth = "0.25" lineColor = "#CCCCCC" />
            </box>

            <textElement />

            <text>
               <![CDATA[]]>
            </text>

         </staticText>

         <textField>
            <reportElement style = "alternateStyle" x = "414" y = "0"
               width = "121" height = "15" />

            <textElement textAlignment = "Center" verticalAlignment = "Middle">
               <font size = "9" />
            </textElement>

            <textFieldExpression class = "java.lang.String">
               <![CDATA[$F{country}]]>
            </textFieldExpression>
         </textField>

         <textField>
            <reportElement x = "0" y = "0" width = "136" height = "15"
               style = "Strong"/>
            <textElement textAlignment = "Center" verticalAlignment = "Middle" />

            <textFieldExpression class = "java.lang.String">
               <![CDATA[$F{name}]]>
            </textFieldExpression>
         </textField>

      </band>
   </detail>

</jasperReport>

样式模板 styles.jrtx 的内容如下。将其保存到 C:\tools\jasperreports-5.0.1\test 目录。

<?xml version = "1.0"?>

<!DOCTYPE jasperTemplate PUBLIC "-//JasperReports//DTD Template//EN"
  "http://jasperreports.sourceforge.net/dtds/jaspertemplate.dtd">

<jasperTemplate>
   <style name = "Strong" isBold = "true" pdfFontName = "Helvetica-Bold"
      backcolor = "lightGray forecolor = "green"/>
</jasperTemplate>

报表填充的 java 代码保持不变。文件 C:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint\JasperReportFill.java 的内容如下 -

package com.tutorialspoint;

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

import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;

public class JasperReportFill {
   @SuppressWarnings("unchecked")
   public static void main(String[] args) {
      String sourceFileName =
         "C://tools/jasperreports-5.0.1/test/jasper_report_template.jasper";

      DataBeanList DataBeanList = new DataBeanList();
      ArrayList<DataBean> dataList = DataBeanList.getDataBeanList();

      JRBeanCollectionDataSource beanColDataSource = new
         JRBeanCollectionDataSource(dataList);

      Map parameters = new HashMap();
      /**
       * Passing ReportTitle and Author as parameters
       */
      parameters.put("ReportTitle", "List of Contacts");
      parameters.put("Author", "Prepared By Manisha");

      try {
         JasperFillManager.fillReportToFile(
         sourceFileName, parameters, beanColDataSource);
      } catch (JRException e) {
         e.printStackTrace();
      }
   }
}

POJO 文件 C:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint\DataBean.java 的内容如下:

package com.tutorialspoint;

public class DataBean {
   private String name;
   private String country;

   public String getName() {
      return name;
   }

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

   public String getCountry() {
      return country;
   }

   public void setCountry(String country) {
      this.country = country;
   }
}

文件 C:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint\DataBeanList.java 的内容如下 -

package com.tutorialspoint;

import java.util.ArrayList;

public class DataBeanList {
   public ArrayList<DataBean> getDataBeanList() {
      ArrayList<DataBean> dataBeanList = new ArrayList<DataBean>();

      dataBeanList.add(produce("Manisha", "India"));
      dataBeanList.add(produce("Dennis Ritchie", "USA"));
      dataBeanList.add(produce("V.Anand", "India"));
      dataBeanList.add(produce("Shrinath", "California"));

      return dataBeanList;
   }

   /**
    * This method returns a DataBean object,
    * with name and country set in it.
    */
   private DataBean produce(String name, String country) {
      DataBean dataBean = new DataBean();
      dataBean.setName(name);
      dataBean.setCountry(country);

      return dataBean;
   }
}

Report Generation

我们将使用常规 ANT 构建流程编译并执行上述文件。build.xml 文件(保存在 C:\tools\jasperreports-5.0.1\test 目录下)的内容如下。

导入文件 - baseBuild.xml 从第 Environment Setup 章中获取,并应放置在与 build.xml 相同的目录中。

<?xml version = "1.0" encoding = "UTF-8"?>
<project name = "JasperReportTest" default = "viewFillReport" basedir = ".">
   <import file = "baseBuild.xml" />

   <target name = "viewFillReport" depends = "compile,compilereportdesing,run"
      description = "Launches the report viewer to preview the
      report stored in the .JRprint file.">

      <java classname = "net.sf.jasperreports.view.JasperViewer" fork = "true">
         <arg value = "-F${file.name}.JRprint" />
         <classpath refid = "classpath" />
      </java>

   </target>

   <target name = "compilereportdesing" description = "Compiles the JXML file and
      produces the .jasper file.">

      <taskdef name = "jrc" classname = "net.sf.jasperreports.ant.JRAntCompileTask">
         <classpath refid = "classpath" />
      </taskdef>

      <jrc destdir = ".">
         <src>
            <fileset dir = ".">
               <include name = "*.jrxml" />
            </fileset>
         </src>
         <classpath refid = "classpath" />
      </jrc>

   </target>

</project>

接下来,让我们打开命令行窗口并进入放置 build.xml 的目录。最后,执行命令 ant -Dmain-class=com.tutorialspoint.JasperReportFill (viewFullReport 是默认目标),如下所示 −

C:\tools\jasperreports-5.0.1\test>ant -Dmain-class=com.tutorialspoint.JasperReportFill
Buildfile: C:\tools\jasperreports-5.0.1\test\build.xml

clean-sample:
   [delete] Deleting directory C:\tools\jasperreports-5.0.1\test\classes
   [delete] Deleting: C:\tools\jasperreports-5.0.1\test\jasper_report_template.jasper
   [delete] Deleting: C:\tools\jasperreports-5.0.1\test\jasper_report_template.jrprint

compile:
   [mkdir] Created dir: C:\tools\jasperreports-5.0.1\test\classes
   [javac] C:\tools\jasperreports-5.0.1\test\baseBuild.xml:28: warning:
   'includeantruntime' was not set, defaulting to build.sysclasspath=last;
   set to false for repeatable builds
   [javac] Compiling 3 source files to C:\tools\jasperreports-5.0.1\test\classes

compilereportdesing:
   [jrc] Compiling 1 report design files.
   [jrc] log4j:WARN No appenders could be found for logger
   (net.sf.jasperreports.engine.xml.JRXmlDigesterFactory).
   [jrc] log4j:WARN Please initialize the log4j system properly.
   [jrc] log4j:WARN See
   http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
   [jrc] File : C:\tools\jasperreports-5.0.1\test\jasper_report_template.jrxml ... OK.

run:
   [echo] Runnin class : com.tutorialspoint.JasperReportFill
   [java] log4j:WARN No appenders could be found for logger
   (net.sf.jasperreports.extensions.ExtensionsEnvironment).
   [java] log4j:WARN Please initialize the log4j system properly.

viewFillReport:
   [java] log4j:WARN No appenders could be found for logger
   (net.sf.jasperreports.extensions.ExtensionsEnvironment).
   [java] log4j:WARN Please initialize the log4j system properly.

作为上述编译的结果,一个 JasperViewer 窗口会打开,如以下给出的屏幕截图所示 -

style example

在这里,我们可以看到,偶数的字体颜色已变为蓝色(在国家/地区列中)。在名称列中,字体颜色已变为绿色(此样式引用自样式模板)。

Report Scriptlets

我们在前几章中看到,报告上显示的数据通常从报表参数和字段中获取。可以使用报表变量及其表达式来处理此数据。有时,不能使用报表表达式或变量轻松实现复杂的功能。这方面的示例可能是复杂的字符串操作、构建映射、内存中的对象列表或使用第三方 Java API 执行日期操作。对于这种情况,JasperReports 向我们提供了一种简单而有效的方法,即 Scriptlets

脚本是每次发生报告事件时执行的 Java 代码序列。可以通过脚本影响报表变量的值。

Scriptlet Declaration

我们可以通过两种方式声明脚本 -

  1. 使用 <*scriptlet*> 元素。此元素具有 name 属性和 class 属性。class 属性应该指定类的名称,该类扩展 JRAbstractScriptlet 类。该类必须在报表填充时可在类路径中,并且必须有空构造函数,以便引擎可以动态初始化该类。

  2. 使用报表模板(JRXML)中元素 <*jasperReport*> 的属性 scriptletClass 。通过使用脚本的完全限定名称(包括整个包名称)设置此属性,我们表明我们希望使用脚本。使用此属性创建的脚本实例充当脚本列表中的第一个脚本,并具有预定义名称 REPORT。

Scriptlet class

脚本是 Java 类,它必须扩展以下任一类 -

  1. net.sf.jasperreports.engine.JRAbstractScriptlet −该类包含一些抽象方法,每个实现里都必须覆盖它。这些方法在适当的时刻被 JasperReports 自动调用。开发人员必须实现所有抽象方法。

  2. net.sf.jasperreports.engine.JRDefaultScriptlet −该类包含 JRAbstractScriptlet 中的每个方法的默认空实现。开发人员仅需要实现他/她为项目需要的方法。

下表列出了上面类中的方法。在报表填充阶段,这些方法将在适当的时候由报表引擎调用。

S.NO

Method and Description

1

public void beforeReportInit() 在报表初始化之前调用。

2

public void afterReportInit() 在报表初始化之后调用。

3

public void beforePageInit() 在初始化每个页面之前调用。

4

public void afterPageInit() 在初始化每个页面之后调用。

5

public void beforeColumnInit() 在初始化每个列之前调用。

6

public void afterColumnInit() 在初始化每个列之后调用。

7

public void beforeGroupInit(String groupName) 在初始化参数中指定的组之前调用。

8

public void afterGroupInit(String groupName) 在初始化参数中指定的组之后调用。

9

public void beforeDetailEval() 在计算报表详细信息部分中的每条记录之前调用。

10

public void afterDetailEval() 在计算报表详细信息部分中的每条记录之后调用。

每个报表可以指定任意数量的脚本。如果未为报表指定脚本,引擎仍会创建单个 JRDefaultScriptlet 实例,并使用内置的 REPORT_SCRIPTLET 参数将其注册。

我们可以向脚本添加我们需要的任何其他方法。报表可以使用内置参数 REPORT_SCRIPTLET 调用这些方法。

Global Scriptlets

我们可以通过另一种方式为报告关联脚本,即全局声明脚本。这使得脚本适用于给定 JasperReports 部署中正在填充的所有报告。由于可以将脚本小程序作为扩展添加到 JasperReports,因此可以轻松实现这一点。脚本扩展点表示为 net.sf.jasperreports.engine.scriptlets.ScriptletFactory 接口。运行时,JasperReports 将加载通过扩展提供的可用脚本工厂。然后,它会向每个脚本工厂询问他们要应用于当前正在运行的报表的脚本实例列表。在询问脚本实例列表时,引擎会提供一些上下文信息,工厂可以使用这些信息来决定哪些脚本实际上适用于当前报表。

Report Governors

总督只是全局脚本的扩展,它使我们能够解决在生成报表时报表引擎在运行时进入无限循环的问题。无效的报表模板无法在设计时检测到,因为大多数时候,进入无限循环的条件取决于在运行时馈入引擎的实际数据。报表总督有助于决定某个报表是否进入了无限循环,并且可以停止它。这可以防止为运行报表的机器耗尽资源。

JasperReports 具有两个简单的报表总督,它们将根据指定的最大页数或指定的超时间隔来停止报表执行。它们是 −

  1. net.sf.jasperreports.governors.MaxPagesGovernor −这是一个全局脚本,用于查找两个配置属性以确定其是否应用于当前正在运行的报表。配置属性为 −net.sf.jasperreports.governor.max.pages.enabled=[true|false]net.sf.jasperreports.governor.max.pages=[integer]

  2. net.sf.jasperreports.governors.TimeoutGovernor − 这也是一个全局小脚本,它会查找以下两个配置属性以决定是否应用。配置属性是 −net.sf.jasperreports.governor.timeout.enabled=[true|false]net.sf.jasperreports.governor.timeout=[milliseconds]

这两个调节器的属性可以作为自定义报告属性在 jasperreports.properties 文件中全局设置,或者在报告级别设置。由于不同的报告可以具有不同的估计大小或超时限制,并且你可能希望对所有报告启用调节器,同时对某些报告禁用,反之亦然,因此此功能非常有用。

Example

我们编写一个脚本小类 ( MyScriptlet )。C:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint\MyScriptlet.java 文件的内容如下 −

package com.tutorialspoint;

import net.sf.jasperreports.engine.JRDefaultScriptlet;
import net.sf.jasperreports.engine.JRScriptletException;


public class MyScriptlet extends JRDefaultScriptlet {

   public void afterReportInit() throws JRScriptletException{
      System.out.println("call afterReportInit()");
      // this.setVariableValue("AllCountries", sbuffer.toString());
      this.setVariableValue("someVar", new String("This variable value
         was modified by the scriptlet."));
   }

   public String hello() throws JRScriptletException {
      return "Hello! I'm the report's scriptlet object.";
   }

}

上述脚本小类详细信息如下 −

  1. 在 afterReportInit 方法中,我们向变量 "someVar" 赋值 this.setVariableValue("someVar", new String("This variable value was modified by the scriptlet.")).

  2. 在该类的末尾,定义了一个名为 'hello' 的额外方法。这是可以添加至脚本小类的并且实际会返回一个值(而不是设置一个变量)的方法的一个示例。

接下来,我们在现有的报告模板(章节 Report Designs )中添加脚本小类引用。修订后的报告模板(jasper_report_template.jrxml)如下。将其保存到 C:\tools\jasperreports-5.0.1\test 目录 −

<?xml version = "1.0"?>
<!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 = "jasper_report_template" pageWidth = "595"
   pageHeight = "842" columnWidth = "515"
   leftMargin = "40" rightMargin = "40" topMargin = "50" bottomMargin = "50"
   scriptletClass = "com.tutorialspoint.MyScriptlet">

   <style name = "alternateStyle" fontName = "Arial" forecolor = "red">

      <conditionalStyle>
         <conditionExpression>
            <![CDATA[new Boolean($V{countNumber}.intValue() % 2 == 0)]]>
         </conditionExpression>

         <style forecolor = "blue" isBold = "true"/>
      </conditionalStyle>
   </style>

   <parameter name = "ReportTitle" class = "java.lang.String"/>
   <parameter name = "Author" class = "java.lang.String"/>

   <queryString>
      <![CDATA[]]>
   </queryString>

   <field name = "country" class = "java.lang.String">
      <fieldDescription>
         <![CDATA[country]]>
      </fieldDescription>
   </field>

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

   <variable name = "countNumber" class = "java.lang.Integer"
      calculation = "Count">
      <variableExpression><
         ![CDATA[Boolean.TRUE]]>
      </variableExpression>
   </variable>

   <variable name = "someVar" class = "java.lang.String">
      <initialValueExpression>
        <![CDATA["This is the initial variable value."]]>
      </initialValueExpression>
   </variable>

   <title>
      <band height = "100">

         <line>
            <reportElement x = "0" y = "0" width = "515" height = "1"/>
         </line>

         <textField isBlankWhenNull = "true" bookmarkLevel = "1">
            <reportElement x = "0" y = "10" width = "515" height = "30"/>

            <textElement textAlignment = "Center">
              <font size = "22"/>
            </textElement>

            <textFieldExpression class = "java.lang.String">
              <![CDATA[$P{ReportTitle}]]>
            </textFieldExpression>

            <anchorNameExpression>
               <![CDATA["Title"]]>
            </anchorNameExpression>
         </textField>

         <textField isBlankWhenNull = "true">
            <reportElement  x = "0" y = "40" width = "515" height = "20"/>

            <textElement textAlignment = "Center">
               <font size = "10"/>
            </textElement>

            <textFieldExpression class = "java.lang.String">
               <![CDATA[$P{Author}]]>
            </textFieldExpression>
         </textField>

         <textField isBlankWhenNull = "true">
            <reportElement  x = "0" y = "50" width = "515"
               height = "30" forecolor = "#993300"/>

            <textElement textAlignment = "Center">
               <font size = "10"/>
            </textElement>

            <textFieldExpression class = "java.lang.String">
               <![CDATA[$V{someVar}]]>
            </textFieldExpression>

         </textField>

      </band>
   </title>

   <columnHeader>
      <band height = "23">

         <staticText>
            <reportElement mode = "Opaque" x = "0" y = "3"
               width = "535" height = "15"
               backcolor = "#70A9A9" />

            <box>
               <bottomPen lineWidth = "1.0" lineColor = "#CCCCCC" />
            </box>

            <textElement />

            <text>
               <![CDATA[]]>
            </text>

         </staticText>

         <staticText>
            <reportElement x = "414" y = "3" width = "121" height = "15" />

            <textElement textAlignment = "Center" verticalAlignment = "Middle">
               <font isBold = "true" />
            </textElement>

            <text><![CDATA[Country]]></text>
         </staticText>

         <staticText>
            <reportElement x = "0" y = "3" width = "136" height = "15" />

            <textElement textAlignment = "Center" verticalAlignment = "Middle">
               <font isBold = "true" />
            </textElement>

            <text><![CDATA[Name]]></text>
         </staticText>

      </band>
   </columnHeader>

   <detail>
      <band height = "16">

         <staticText>
            <reportElement mode = "Opaque" x = "0" y = "0"
               width = "535"	height = "14"
               backcolor = "#E5ECF9" />

            <box>
               <bottomPen lineWidth = "0.25" lineColor = "#CCCCCC" />
            </box>

            <textElement />

            <text>
               <![CDATA[]]>
            </text>
         </staticText>

         <textField>
            <reportElement style = "alternateStyle" x="414" y = "0"
               width = "121" height = "15" />

            <textElement textAlignment = "Center" verticalAlignment = "Middle">
               <font size = "9" />
            </textElement>


            <textFieldExpression class = "java.lang.String">
               <![CDATA[$F{country}]]>
            </textFieldExpression>
         </textField>

         <textField>
            <reportElement x = "0" y = "0" width = "136" height = "15" />
            <textElement textAlignment = "Center" verticalAlignment = "Middle" />

            <textFieldExpression class = "java.lang.String">
               <![CDATA[$F{name}]]>
            </textFieldExpression>
         </textField>

      </band>
   </detail>

   <summary>
      <band height = "45">

         <textField isStretchWithOverflow = "true">
            <reportElement x = "0" y = "10" width = "515" height = "15" />
            <textElement textAlignment = "Center"/>

            <textFieldExpression class = "java.lang.String">
               <![CDATA["There are " + String.valueOf($V{REPORT_COUNT}) +
                  " records on this report."]]>
            </textFieldExpression>
         </textField>

         <textField isStretchWithOverflow = "true">
            <reportElement positionType = "Float" x = "0" y = "30" width = "515"
               height = "15" forecolor = "# 993300" />

            <textElement textAlignment = "Center">
               <font size = "10"/>
            </textElement>

            <textFieldExpression class = "java.lang.String">
               <![CDATA[$P{REPORT_SCRIPTLET}.hello()]]>
            </textFieldExpression>

         </textField>

      </band>
   </summary>

</jasperReport>

修订后的报告模板的详细信息如下 −

  1. 我们引用了 <jasperReport> 元素的 scriptletClass 属性中的 MyScriptlet 类。

  2. 脚本小类只能访问,但不能修改报告字段和参数。但是,脚本小类可以修改报告变量值。可以通过调用 setVariableValue() 方法来实现上述操作。此方法在 JRAbstractScriptlet 类中定义,它始终是任何脚本小类(scriptlet)的父类。此处,我们定义了一个变量 someVar,脚本小类 MyScriptlet 将对其进行修改,使之具有值 This value was modified by the scriptlet。

  3. 上述报告模板在 Summary 波段中有一个方法调用,它说明了如何在报告模板中编写新方法(在 scriptlet 中)并使用它们 ( $P{REPORT_SCRIPTLET}.hello() )

报表填充的 java 代码保持不变。文件 C:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint\JasperReportFill.java 的内容如下 -

package com.tutorialspoint;

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

import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;

public class JasperReportFill {
   @SuppressWarnings("unchecked")
   public static void main(String[] args) {
      String sourceFileName =
         "C://tools/jasperreports-5.0.1/test/jasper_report_template.jasper";

      DataBeanList DataBeanList = new DataBeanList();
      ArrayList<DataBean> dataList = DataBeanList.getDataBeanList();

      JRBeanCollectionDataSource beanColDataSource = new
         JRBeanCollectionDataSource(dataList);

      Map parameters = new HashMap();
      /**
       * Passing ReportTitle and Author as parameters
       */
      parameters.put("ReportTitle", "List of Contacts");
      parameters.put("Author", "Prepared By Manisha");

      try {
         JasperFillManager.fillReportToFile(
         sourceFileName, parameters, beanColDataSource);
      } catch (JRException e) {
         e.printStackTrace();
      }
   }
}

C:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint\DataBean.java POJO 文件的内容如下 −

package com.tutorialspoint;

public class DataBean {
   private String name;
   private String country;

   public String getName() {
      return name;
   }

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

   public String getCountry() {
      return country;
   }

   public void setCountry(String country) {
      this.country = country;
   }
}

C:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint\DataBeanList.java 文件的内容如下 −

package com.tutorialspoint;

import java.util.ArrayList;

public class DataBeanList {
   public ArrayList<DataBean> getDataBeanList() {
      ArrayList<DataBean> dataBeanList = new ArrayList<DataBean>();

      dataBeanList.add(produce("Manisha", "India"));
      dataBeanList.add(produce("Dennis Ritchie", "USA"));
      dataBeanList.add(produce("V.Anand", "India"));
      dataBeanList.add(produce("Shrinath", "California"));

      return dataBeanList;
   }

   /**
    * This method returns a DataBean object,
    * with name and country set in it.
    */
   private DataBean produce(String name, String country) {
      DataBean dataBean = new DataBean();
      dataBean.setName(name);
      dataBean.setCountry(country);

      return dataBean;
   }
}

Report Generation

我们将使用常规 ANT 构建流程编译并执行上述文件。build.xml 文件(保存在 C:\tools\jasperreports-5.0.1\test 目录下)的内容如下。

导入文件 - baseBuild.xml 从第 Environment Setup 章中获取,并应放置在与 build.xml 相同的目录中。

<?xml version = "1.0" encoding = "UTF-8"?>
<project name = "JasperReportTest" default = "viewFillReport" basedir = ".">
   <import file = "baseBuild.xml" />

   <target name = "viewFillReport" depends = "compile,compilereportdesing,run"
      description = "Launches the report viewer to preview
      the report stored in the .JRprint file.">

      <java classname = "net.sf.jasperreports.view.JasperViewer" fork = "true">
         <arg value = "-F${file.name}.JRprint" />
         <classpath refid = "classpath" />
      </java>
   </target>

   <target name = "compilereportdesing" description = "Compiles the JXML file and
      produces the .jasper file.">

      <taskdef name = "jrc" classname = "net.sf.jasperreports.ant.JRAntCompileTask">
         <classpath refid = "classpath" />
      </taskdef>

      <jrc destdir = ".">
         <src>
            <fileset dir = ".">
               <include name = "*.jrxml" />
            </fileset>
         </src>
         <classpath refid = "classpath" />
      </jrc>

   </target>

</project>

接下来,让我们打开命令行窗口并进入放置 build.xml 的目录。最后,执行命令 ant -Dmain-class=com.tutorialspoint.JasperReportFill (viewFullReport 是默认目标),如下所示 −

C:\tools\jasperreports-5.0.1\test>ant -Dmain-class=com.tutorialspoint.JasperReportFill
Buildfile: C:\tools\jasperreports-5.0.1\test\build.xml

clean-sample:
   [delete] Deleting directory C:\tools\jasperreports-5.0.1\test\classes
   [delete] Deleting: C:\tools\jasperreports-5.0.1\test\jasper_report_template.jasper
   [delete] Deleting: C:\tools\jasperreports-5.0.1\test\jasper_report_template.jrprint

compile:
   [mkdir] Created dir: C:\tools\jasperreports-5.0.1\test\classes
   [javac] C:\tools\jasperreports-5.0.1\test\baseBuild.xml:28:
   warning: 'includeantruntime' was not set, defaulting to bu
   [javac] Compiling 4 source files to C:\tools\jasperreports-5.0.1\test\classes

compilereportdesing:
   [jrc] Compiling 1 report design files.
   [jrc] log4j:WARN No appenders could be found for logger
   (net.sf.jasperreports.engine.xml.JRXmlDigesterFactory).
   [jrc] log4j:WARN Please initialize the log4j system properly.
   [jrc] log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
   [jrc] File : C:\tools\jasperreports-5.0.1\test\jasper_report_template.jrxml ... OK.

run:
   [echo] Runnin class : com.tutorialspoint.JasperReportFill
   [java] log4j:WARN No appenders could be found for logger
   (net.sf.jasperreports.extensions.ExtensionsEnvironment).
   [java] log4j:WARN Please initialize the log4j system properly.
   [java] call afterReportInit()
   [java] call afterReportInit()

viewFillReport:
   [java] log4j:WARN No appenders could be found for logger
   (net.sf.jasperreports.extensions.ExtensionsEnvironment).
   [java] log4j:WARN Please initialize the log4j system properly.

BUILD SUCCESSFUL
Total time: 18 minutes 49 seconds

作为上述编译的结果,一个 JasperViewer 窗口会打开,如以下给出的屏幕截图所示 -

report scriptlet example

此处我们看到从 MyScriptlet 类显示了两条消息 −

  1. 在标题部分 − This variable value was modified by the scriptlet

  2. 在底部 − Hello! I’m the report’s scriptlet object.

Create SubReports

子报表是 JasperReports 的一项不错的功能。此功能允许在另一个报表内合并报表,即一个报表可以是另一个报表的子报表。子报表帮助我们保持报表设计简单,因为我们可以创建许多简单的报表并将其封装到一个主报表中。子报表像普通报表一样进行编译和填充。在合并到另一个报表模板时,任何报表模板都可以用作子报表,而无需对(报表模板)中的任何内容进行更改。

子报表就像普通报表模板。实际上,它们是 net.sf.jasperreports.engine.JasperReport 对象,在编译 net.sf.jasperreports.engine.design.JasperDesign 对象后获得这些对象。

<subreport> Element

在将子报表引入主报表时,会使用 <subreport> 元素。下面是 <subreport> JRXML 元素的子元素列表。

  1. <reportElement>

  2. <parametersMapExpression> − 用于向子报表传递包含报表参数的映射。该映射通常从主报表中的一个参数获取,也可以通过使用内置 REPORTS_PARAMETERS_MAP 参数将父报表的参数传递到子报表。此表达式应始终返回一个 java.util.Map 对象,其中键是参数名称。

  3. <subreportParameter> − 此元素用于向子报表传递参数。它有一个必需的 name 属性。

  4. <connectionExpression > − 用于向子报表传递 java.sql.Connection。仅在子报表模板在报表填充阶段需要数据库连接时才使用此参数。

  5. <dataSourceExpression> − 用于向子报表传递数据源。此数据源通常从主报表中的一个参数获取,也可以通过使用内置 REPORT_DATA_SOURCE 参数将父报表的参数传递到子报表。

  6. 元素(connectionExpression 和 dataSourceExpression)不能同时出现在 <subreport> 元素声明中。这是因为我们无法同时向子报表提供数据源和连接。我们必须决定一个数据库,并坚持下去。

  7. <returnValue> − 用于将子报表变量之一的值分配给主报表变量之一。此子元素具有以下属性 −subreportVariable − 此属性指定要返回其值的子报表变量的名称。toVariable − 此属性指定要将来自子报表的 value 复制/增加到其中的父报表变量的名称。calculation − 此属性可以采用下列值:Nothing、Count、DistinctCount、Sum、Average、Lowest、Highest、StandardDeviation、Variance。calculation 属性的默认值是 “Nothing”。incrementerFactoryClass − 此属性指定用于创建增量器实例的工厂类。

  8. <subreportExpression> − 指示在何处查找子报表的已编译报表模板。此元素具有 class 属性。class 属性可以采用以下任何值:java.lang.String、java.io.File、java.net.URL、java.io.InputStream、net.sf.jasperreports.engine.JasperReport. 默认值是 java.lang.String。

  9. isUsingCache − 这是 <subreport> 元素的一个属性。它是一个 Boolean,当设置为 true 时,报告引擎将尝试使用指定的源识别先前加载的子报表模板对象。此缓存功能仅适用于具有将表达式返回为 java.lang.String 对象(表示文件名称、URL 或类路径资源)作为子报表模板源的子报表元素。

Example

让我们举一个简单的示例来说明使用 JRDataSource 创建子报表的步骤。首先,我们编写两个新的报表模板,一个是子报表,另一个是主报表。子报表 (address_report_template.jrxml) 模板的内容如下。将其保存到 C:\tools\jasperreports-5.0.1\test 目录中。

<?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 = "address_report_template" pageWidth = "175" pageHeight = "842"
   columnWidth = "175" leftMargin = "0" rightMargin = "0"
   topMargin = "0" bottomMargin = "0">

   <field name = "city" class = "java.lang.String"/>
   <field name = "street" class = "java.lang.String"/>

   <background>
      <band splitType = "Stretch"/>
   </background>

   <title>
      <band height = "20" splitType = "Stretch">

         <staticText>
            <reportElement x = "0" y = "0" width = "100" height = "20"/>

            <textElement>
               <font size = "14" isBold = "true"/>
            </textElement>

            <text><![CDATA[Addresses]]></text>
         </staticText>

      </band>
   </title>

   <pageHeader>
      <band height = "12" splitType = "Stretch"/>
   </pageHeader>

   <columnHeader>
      <band height = "12" splitType = "Stretch"/>
   </columnHeader>

   <detail>
      <band height = "27" splitType = "Stretch">

         <textField>
            <reportElement x = "0" y = "0" width = "120" height = "20"/>

            <textElement>
               <font size = "12" isBold = "true"/>
            </textElement>

            <textFieldExpression class = "java.lang.String">
               <![CDATA[$F{city}+" Address:"]]>
            </textFieldExpression>
         </textField>

         <textField isStretchWithOverflow = "true">
            <reportElement x = "120" y = "0" width = "435" height = "20"/>

            <textElement>
               <font size = "12"/>
            </textElement>

            <textFieldExpression class = "java.lang.String">
               <![CDATA[$F{street}]]>
            </textFieldExpression>
         </textField>

      </band>
   </detail>

   <columnFooter>
      <band height = "8" splitType = "Stretch"/>
   </columnFooter>

   <pageFooter>
      <band height = "11" splitType = "Stretch"/>
   </pageFooter>

   <summary>
      <band height = "9" splitType = "Stretch"/>
   </summary>

</jasperReport>

由于我们使用数据源,因此我们需要编写一个相应的 POJO 文件 *SubReportBean.java *,如下所示。将其保存到目录 C:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint −

package com.tutorialspoint;

public class SubReportBean {
   private String city;
   private String street;

   public String getCity() {
      return city;
   }

   public void setCity(String city) {
      this.city = city;
   }

   public String getStreet() {
      return street;
   }

   public void setStreet(String street) {
      this.street = street;
   }
}

在此,我们声明了两个字段 'city' 和 'street',并定义了相应的 getter 和 setter 方法。

现在,我们来更新现有的 DataBean 文件。我们将添加一个新字段 subReportBeanList,它是一个 java.util.List。此字段将保存 SubReportBean 对象的列表。DataBean 文件的内容如下。将其保存到目录 C:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint。

package com.tutorialspoint;

import java.util.List;

public class DataBean {
   private String name;
   private String country;
   private List<SubReportBean> subReportBeanList;

   public String getName() {
      return name;
   }

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

   public String getCountry() {
      return country;
   }

   public void setCountry(String country) {
      this.country = country;
   }

   public List<SubReportBean> getSubReportBeanList() {
      return subReportBeanList;
   }

   public void setSubReportBeanList(List<SubReportBean> subReportBeanList) {
      this.subReportBeanList = subReportBeanList;
   }
}

我们现在更新文件 C:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint*DataBeanList.java*。该文件的内容如下 −

package com.tutorialspoint;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class DataBeanList {
   public ArrayList<DataBean> getDataBeanList() {

      // Create sub report data
      SubReportBean subBean1 = new SubReportBean();
      subBean1.setCity("Mumbai");
      subBean1.setStreet("M.G.Road");
      SubReportBean subBean2 = new SubReportBean();
      subBean2.setCity("New York");
      subBean2.setStreet("Park Street");
      SubReportBean subBean3 = new SubReportBean();
      subBean3.setCity("San Fransisco");
      subBean3.setStreet("King Street");

      ArrayList<DataBean> dataBeanList = new ArrayList<DataBean>();

      // Create master report data
      dataBeanList.add(produce("Manisha", "India",
         Arrays.asList(subBean1)));
      dataBeanList.add(produce("Dennis Ritchie", "USA",
         Arrays.asList(subBean2)));
      dataBeanList.add(produce("V.Anand", "India",
         Arrays.asList(subBean1)));
      dataBeanList.add(produce("Shrinath", "California",
         Arrays.asList(subBean3)));

      return dataBeanList;
   }

   /*
    * This method returns a DataBean object,
    * with name, country and sub report
    * bean data set in it.
    */
   private DataBean produce(String name, String country,
      List<SubReportBean> subBean) {
      DataBean dataBean = new DataBean();

      dataBean.setName(name);
      dataBean.setCountry(country);
      dataBean.setSubReportBeanList(subBean);

      return dataBean;
   }
}

在上述文件中的 produce() 方法中,我们设置了 SubReportBean 的列表。

现在,我们来编写一个新的主报表模板(jasper_report_template.jrxml)。将此文件保存到目录 C:\tools\jasperreports-5.0.1\test 。该文件的内容如下 −

<?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 = "jasper_report_template" language = "groovy" pageWidth = "595"
   pageHeight = "842" columnWidth ="555" leftMargin = "20" rightMargin = "20"
   topMargin = "20" bottomMargin = "20">

   <parameter name = "SUBREPORT_DIR" class = "java.lang.String" isForPrompting = "false">
      <defaultValueExpression>
         <![CDATA["C:\\tools\\jasperreports-5.0.1\\test\\"]]>
      </defaultValueExpression>
   </parameter>

   <field name = "country" class = "java.lang.String"/>
   <field name = "name" class = "java.lang.String"/>
   <field name = "subReportBeanList" class = "java.util.List"/>

   <background>
      <band splitType = "Stretch"/>
   </background>

   <title>
      <band height = "35" splitType = "Stretch">

         <staticText>
            <reportElement x = "0" y = "0" width = "204" height = "34"/>

            <textElement>
               <font size = "26" isBold = "true"/>
            </textElement>

            <text><![CDATA[Contact Report]]></text>
         </staticText>

      </band>
   </title>

   <pageHeader>
      <band height = "17" splitType = "Stretch"/>
   </pageHeader>

   <columnHeader>
      <band height = "21" splitType = "Stretch"/>
   </columnHeader>

   <detail>
      <band height = "112" splitType = "Stretch">

         <staticText>
            <reportElement x = "0" y = "0" width = "100" height = "20"/>

            <textElement>
               <font size = "12" isBold = "true"/>
            </textElement>

            <text><![CDATA[Name:]]></text>
         </staticText>

         <staticText>
            <reportElement x = "0" y = "20" width = "100" height = "20"/>

            <textElement>
               <font size = "12" isBold = "true"/>
            </textElement>

            <text><![CDATA[Country:]]></text>
         </staticText>

         <textField>
            <reportElement x = "104" y = "0" width = "277" height = "20"/>

            <textElement>
               <font size = "12"/>
            </textElement>

            <textFieldExpression class = "java.lang.String">
               <![CDATA[$F{name}]]>
            </textFieldExpression>
         </textField>

         <textField>
            <reportElement x = "104" y = "20" width = "277" height = "20"/>

            <textElement>
               <font size = "12"/>
            </textElement>

            <textFieldExpression class = "java.lang.String">
               <![CDATA[$F{country}]]>
            </textFieldExpression>
         </textField>

         <subreport>
            <reportElement positionType = "Float" x = "335" y = "25" width = "175"
               height = "20" isRemoveLineWhenBlank = "true" backcolor = "#99ccff"/>

            <dataSourceExpression>
               new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource
                  ($F{subReportBeanList})
            </dataSourceExpression>

            <subreportExpression class = "java.lang.String">
               <![CDATA[$P{SUBREPORT_DIR} + "address_report_template.jasper"]]>
            </subreportExpression>
         </subreport>

         <line>
            <reportElement x = "0" y = "50" width = "550" height = "1"/>
         </line>

      </band>
   </detail>

   <columnFooter>
      <band height = "19" splitType = "Stretch"/>
   </columnFooter>

   <pageFooter>
      <band height = "18" splitType = "Stretch"/>
   </pageFooter>

   <summary>
      <band height = "14" splitType = "Stretch"/>
   </summary>

</jasperReport>

在上述模板中,我们定义了一个新参数“SUBREPORT_DIR”,该参数定义了子报表的路径。我们定义了一个类型为 java.util.List 的字段 subReportBeanList,它对应于 DataBean 文件中的属性。元素 <subreport> 有子元素 <dataSourceExpression>。我们已将列表 subReportBeanList 放入 JRBeanCollectionDataSource 的实例中。在子元素 <subreportExpression/> 中,我们给出了子报表名称(AddressReport.jasper)。

现在,我们来编写一个新类 CreateReport 来编译和执行我们的报表模板。文件 C:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint\CreateReport.java 的内容如下 −

package com.tutorialspoint;

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

import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;

public class CreateReport {

   public static void main(String[] args) {
      String masterReportFileName = "C://tools/jasperreports-5.0.1/test"
         + "/jasper_report_template.jrxml";
      String subReportFileName = "C://tools/jasperreports-5.0.1/test"
         + "/AddressReport.jrxml";
      String destFileName = "C://tools/jasperreports-5.0.1/test"
         + "/jasper_report_template.JRprint";

      DataBeanList DataBeanList = new DataBeanList();
      ArrayList<DataBean> dataList = DataBeanList.getDataBeanList();
      JRBeanCollectionDataSource beanColDataSource = new
         JRBeanCollectionDataSource(dataList);

      try {
         /* Compile the master and sub report */
         JasperReport jasperMasterReport = JasperCompileManager
            .compileReport(masterReportFileName);
         JasperReport jasperSubReport = JasperCompileManager
            .compileReport(subReportFileName);

         Map<String, Object> parameters = new HashMap<String, Object>();
         parameters.put("subreportParameter", jasperSubReport);
         JasperFillManager.fillReportToFile(jasperMasterReport,
            destFileName, parameters, beanColDataSource);

      } catch (JRException e) {

         e.printStackTrace();
      }
      System.out.println("Done filling!!! ...");
   }
}

此处,可以看到我们在编译主模板和子报表模板,并传递主报表(.jasper)文件以用于报表填充。

Report Generation

现在,我们的所有文件都准备好了,我们使用常规 ANT 构建流程来编译和执行它们。文件 build.xml 的内容(保存在目录 C:\tools\jasperreports-5.0.1\test 下)如下所示。

导入文件 - baseBuild.xml 从第 Environment Setup 章中获取,并应放置在与 build.xml 相同的目录中。

<?xml version = "1.0" encoding = "UTF-8"?>
<project name = "JasperReportTest" default = "viewFillReport" basedir = ".">
   <import file = "baseBuild.xml" />

   <target name = "viewFillReport" depends = "compile,compilereportdesing,run"
      description = "Launches the report viewer to preview the
      report stored in the .JRprint file.">

      <java classname = "net.sf.jasperreports.view.JasperViewer" fork = "true">
         <arg value = "-F${file.name}.JRprint" />
         <classpath refid = "classpath" />
      </java>
   </target>

   <target name = "compilereportdesing" description = "Compiles the JXML file and
      produces the .jasper file.">

      <taskdef name = "jrc" classname = "net.sf.jasperreports.ant.JRAntCompileTask">
         <classpath refid = "classpath" />
      </taskdef>

      <jrc destdir = ".">
         <src>
            <fileset dir = ".">
               <include name = "*.jrxml" />
            </fileset>
         </src>
         <classpath refid = "classpath" />
      </jrc>

   </target>

</project>

接下来,让我们打开命令行窗口并转到放置 build.xml 的目录。最后,执行命令 ant -Dmain-class=com.tutorialspoint.CreateReport (viewFullReport 是默认目标),如下所示 −

Buildfile: C:\tools\jasperreports-5.0.1\test\build.xml

clean-sample:
   [delete] Deleting directory C:\tools\jasperreports-5.0.1\test\classes

compile:
   [mkdir] Created dir: C:\tools\jasperreports-5.0.1\test\classes
   [javac] C:\tools\jasperreports-5.0.1\test\baseBuild.xml:28:
      warning: 'includeantruntime' was not set, defaulting to
   [javac] Compiling 7 source files to C:\tools\jasperreports-5.0.1\test\classes

compilereportdesing:
   [jrc] Compiling 1 report design files.
   [jrc] log4j:WARN No appenders could be found for logger
   (net.sf.jasperreports.engine.xml.JRXmlDigesterFactory).
   [jrc] log4j:WARN Please initialize the log4j system properly.
   [jrc] log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig
      for more info.
   [jrc] File : C:\tools\jasperreports-5.0.1\test\
      jasper_report_template.jrxml ... OK.

run:
   [echo] Runnin class : com.tutorialspoint.CreateReport
   [java] Compiling Report Design ...
   [java] log4j:WARN No appenders could be found for logger
   (net.sf.jasperreports.engine.xml.JRXmlDigesterFactory).
   [java] log4j:WARN Please initialize the log4j system properly.
   [java] Done filling!!! ...

viewFillReport:
   [java] log4j:WARN No appenders could be found for logger
   (net.sf.jasperreports.extensions.ExtensionsEnvironment).
   [java] log4j:WARN Please initialize the log4j system properly.

BUILD SUCCESSFUL
Total time: 72 minutes 13 seconds

作为上述编译的结果,一个 JasperViewer 窗口会打开,如以下给出的屏幕截图所示 -

subreport example

此处,可以看到显示了属性 Name、Country 和 Address。

Creating Charts

此前,人们不得不依赖脚本小类来收集图表数据,并使用报告模板中的图像元素来呈现图表。JasperReports 现在让此过程变得简单,因为它对使用新图表组件的图表内置有支持。

使用新的图表组件,用户只需要应用视觉设置,并定义有助于构建图表数据集的表达式。JasperReports 使用 JFreeChart 作为底层图表库。在配置新的图表组件时,涉及以下三个组件 −

  1. The overall chart component.

  2. 图表数据集(对图表数据相关设置分组)。

  3. 图表绘图(对图表项目呈现方式相关的视觉设置分组)。

JasperReports 目前支持以下类型的图表:饼图、3D 饼图、条形图、3D 条形图、XY 条形图、堆积条形图、3D 堆积条形图、折线图、XY 折线图、面积图、XY 面积图、堆积面积图、散点图、气泡图、时间序列图、高开低收图、蜡烛图、多轴图表、仪表图、温度计和甘特图。

Chart Properties

图表是常规报表元素,因此它们与其它的报表元素共享一些属性。有一个名为 <*chart*> 的 JRXML 元素,用于创建所有类型的图表。此元素将适用于所有类型的图表特殊图表相关设置分组。

Chart Sub-Elements

<chart> 元素的子元素是:

  1. &lt;reportElement&gt; - 这些是可显示的对象,如静态文本、文本域、图像、线条和矩形,您可以将其放置在报表模板部分中。

  2. &lt;Box&gt; - 此元素用于用可在每侧进行自定义的边框包围图表。

  3. &lt;chartTitle&gt; - 此元素用于放置图表标题。position 属性决定了图表标题在报表中的位置。此元素具有下列属性: Position (值可以为顶部、底部、左侧、右侧。默认值为顶部), color 。<chartTitle> 以字体和 titleExpression 为子元素。

  4. &lt;chartSubtitle&gt; - 此元素用于放置图表子标题。此元素具有下列属性: color 。<chartSubtitle> 以字体和 subtitleExpression 为子元素。

  5. &lt;chartLegend&gt; - 此元素可以控制字体相关的属性以及使用此元素图表图例的文本颜色和背景颜色。此元素具有下列属性: textColorbackgroundColor

  6. &lt;anchorNameExpression&gt; - 此元素创建锚点的目标。

  7. &lt;hyperlinkReferenceExpression&gt; - 此元素包含指示外部资源(通常是 URL)名称的报表表达式。

  8. &lt;hyperlinkAnchorExpression&gt; - 超链接指向外部资源中的锚点。

  9. &lt;hyperlinkPageExpression&gt; - 超链接指向当前报表中的页面。

  10. &lt;hyperlinkTooltipExpression&gt; - 此元素控制超链接的工具提示。表达式的类型应为 java.lang.String。

  11. &lt;hyperlinkParameter&gt; - 此元素在存在时会根据参数值生成最终超链接。

Chart attributes

<chart> 元素中可用于所有图表类型的所有属性:

  1. isShowLegend - 此属性用于确定是否在报表上显示图表图例。值可以为 true 或 false。默认值为 true。

  2. evaluationTime - 确定在何时计算图表表达式。值可以为 Now、Report、Page、Column、Group、Band。默认值为 Now。

  3. evaluationGroup - 此属性确定用于计算图表表达式的组的名称。此属性的值必须与希望用作图表计算组的组的名称相匹配。

  4. hyperlinkType - 此属性可以保存任何文本值。默认值为 None。这意味着即使存在特殊的超链接表达式,文本域或图像也不会表示超链接。

  5. hyperlinkTarget - 此属性有助于在查看器中单击指定链接时自定义其行为。值可以为 Self 或 Blank。默认值为 Self。

  6. bookmarkLevel - 当将此属性设置为正整数时,将在导出到 PDF 的报表中生成书签。默认值为 0。

  7. customizerClass - 这是可用于自定义图表的一个类(可选)的名称。此元素的值必须是包含自定义器类名称的字符串。

Chart customization

如上所述,JasperReports 使用 JFreeChart 作为底层制图库。JFreeChart 包含 JasperReports 不直接支持的功能。我们可以通过 <chart> 元素中的 customizerClass 属性提供自定义器类来利用这些功能。自定义器类不过是 net.sf.jasperreports.engine.JRChartCustomizer 界面的实现。实现此界面的最简单方法是扩展 net.sf.jasperreports.engine.JRAbstractChartCustomizer 类,从而访问参数、字段和变量,以便根据报表数据更灵活地自定义图表。

Chart Datasets

所有图表类型的一个通用属性是 <*dataset*> 元素。图表数据集有助于映射报表数据并在运行时检索图表数据。每种图表类型包含不同的子元素来定义图表表达式。这些表达式定义用于生成图表的数据。所有这些子元素都包含一个 <dataset> 元素,该元素定义何时对图表表达式进行求值和重置。

JasperReports 中有几种图表数据集类型,因为每种类型的图表都与某些数据集一起使用:Pie、Category、XY、Time Series、Time Period、XYZ 和 High-Low。每种数据集类型都实现了定义图表数据集的 net.sf.jasperreports.engine.JRChartDataset 接口。所有图表数据集都以相同的方式初始化和递增;但是,它们仅在映射的数据或数据序列的类型上有所不同。

Dataset Properties

下表总结了元素 <dataset> 的属性 -

Attribute

Description

Values

resetType

此属性确定何时重置图表表达式的值。

无、报表、页、列、组。默认值为 Report

resetGroup

此属性确定重置图表表达式值时组的名称。

此属性的值必须与 JRXML 报表模板中声明的任何组的名称匹配。

incrementType

此属性确定何时重新计算图表表达式的值。

无、报表、页、列、组。默认值为 "None"

incrementGroup

此属性确定重新计算图表表达式时组的名称。

此属性的值必须与 JRXML 报表模板中声明的组的名称匹配。

下表总结了元素 <dataset> 的子元素 -

Sub element

Description

<incrementWhenExpression>

可以通过使用此子元素筛选掉不需要的数据来自定义图表数据集的递增方式。

<datasetRun>

其中包含实例化报表子数据集所需的信息。

Dataset Types

特定的数据集类型说明如下 -

Pie Dataset

饼形图数据集的特征在于以下表达式 -

  1. <keyExpression> − 表示将组成饼状图中扇形的类别。此表达式可以返回任何 java.lang.Comparable 对象。

  2. <valueExpression> − 生成对应数据集中的每个类别/键的值。值始终是 java.lang.Number 对象。

  3. <labelExpression> − 如果此表达式缺失,该图表将为饼状图中的每个扇形显示默认标签。使用此表达式,它返回 java.lang.String 值,以自定义饼状图的项标签。

  4. <sectionHyperlink> − 设置与饼状图扇形关联的超链接。

Category Dataset

类别数据集的特征是 <categorySeries> 元素,其中包含 −

  1. <seriesExpression> − 指示系列的名称。此表达式可以返回任何 java.lang.Comparable 对象。

  2. <categoryExpression> − 返回系列表达式指定的系列内部每个值的类别的名称。类别是 java.lang.Comparable 对象。

  3. <valueExpression> − 生成对应数据集中的每个类别的值。值始终是 java.lang.Number 对象。

  4. <labelExpression> − 如果此表达式缺失,该图表将为图表中的每个项显示默认标签。使用此表达式,它返回 java.lang.String 值,以自定义图表中项标签。

  5. <itemHyperlink> − 设置与图表项关联的超链接。

XY Dataset

XY 数据集的特征是 <xySeries> 元素,其中包含 −

  1. <seriesExpression> − 指示系列的名称。此表达式可以返回任何 java.lang.Comparable 对象。

  2. <xValueExpression> − 返回表示 (x, y) 对中 X 值的 java.lang.Number 值,将该值添加到当前数据系列。

  3. <yValueExpression> − 返回表示 (x, y) 对中 Y 值的 java.lang.Number 值,将该值添加到当前数据系列。

  4. <labelExpression> − 如果此表达式缺失,该图表将为图表中的每个项显示默认标签。使用此表达式,它返回 java.lang.String 值,以自定义图表中项标签。

  5. <itemHyperlink> − 设置与图表项关联的超链接。

XYZ Dataset

XYZ 数据集的特征是 <xyzSeries> 元素,其中包含 −

  1. <seriesExpression> − 指示系列的名称。此表达式可以返回任何 java.lang.Comparable 对象。

  2. <xValueExpression> − 返回表示 (x, y, z) 项中 X 值的 java.lang.Number 值,将该值添加到当前数据系列。

  3. <yValueExpression> − 返回表示 (x, y, z) 项中 Y 值的 java.lang.Number 值,将该值添加到当前数据系列。

  4. <zValueExpression> − 返回表示 (x, y, z) 项中 Z 值的 java.lang.Number 值,将该值添加到当前数据系列。

  5. <labelExpression> − 如果此表达式缺失,该图表将为图表中的每个项显示默认标签。使用此表达式,它返回 java.lang.String 值,以自定义图表中项标签。

  6. <itemHyperlink> − 设置与图表项关联的超链接。

Time Series Dataset

时间序列数据集的特征是 timePeriod 属性以及 <timeSeries> 元素。timePeriod 属性指定了数据集中数据系列的类型。时间序列可以包含与天、月、年或其他预定义时间段关联的数字值。可能的值有:年、季度、月、周、日 - 这是默认值、小时、分钟、秒、毫秒。

<timeSeries> 元素包含 −

  1. <seriesExpression> − 指示系列的名称。此表达式可以返回任何 java.lang.Comparable 对象。

  2. <timePeriodExpression> − 返回一个java.util.Date值,引擎将根据上面提到的timePeriod属性设置为相应的时间段提取该值。

  3. <valueExpression> − 在递增数据集的当前序列时,返回要与相应时间段值关联的java.lang.Number值。

  4. <labelExpression> − 如果此表达式缺失,该图表将为图表中的每个项显示默认标签。使用此表达式,它返回 java.lang.String 值,以自定义图表中项标签。

  5. <itemHyperlink> − 设置与图表项关联的超链接。

Time Period Dataset

时间段数据集由<timePeriodSeries>元素表征,其中包含 −

  1. <seriesExpression> − 指示系列的名称。此表达式可以返回任何 java.lang.Comparable 对象。

  2. <startDateExpression> − 指定与将数值添加到时间段序列时将与之关联的日期间隔的开始。

  3. <endDateExpression> − 指定与将数值添加到时间段序列时将与之关联的日期间隔的结束。

  4. <valueExpression> − 返回要与由开始日期和结束日期表达式指定的当前日期间隔关联的java.lang.Number值。

  5. <labelExpression> − 如果此表达式缺失,该图表将为图表中的每个项显示默认标签。使用此表达式,它返回 java.lang.String 值,以自定义图表中项标签。

  6. <itemHyperlink> − 设置与图表项关联的超链接。

High Low Dataset

高低数据集由以下表达式表征 −

  1. <seriesExpression> − 目前,高低或蜡烛图内仅支持一个序列。但是,此单个系列必须由该表达式返回的java.lang.Comparable值标识,并且还必须用作图表图例中的系列名称。

  2. <dateExpression> − 返回当前(高、低、开、收、量)项所指的日期。

  3. <highExpression> − 返回一个java.lang.Number值,该值将成为在数据集增量时添加到该系列的数据项的一部分。

  4. <lowExpression> − 返回一个java.lang.Number值,该值将成为在数据集增量时添加到该系列的数据项的一部分。

  5. <openExpression> − 返回一个java.lang.Number值,该值将成为在数据集增量时添加到该系列的数据项的一部分。

  6. <closeExpression> − 返回一个java.lang.Number值,该值将成为在数据集增量时添加到该系列的数据项的一部分。

  7. <volumeExpression> − 返回用于当前数据项的成交量的数字表达式。它仅用于蜡烛图。

  8. <itemHyperlink> − 设置与图表项关联的超链接。

Value Dataset

这是一种特殊图表数据集实现,包含一个值,且用于渲染计量器和温度计图表。使用<valueExpression>表达式收集值。

Chart Plots

另一个贯穿所有图表类型的常见JRXML元素是<*plot*>元素。这使我们可以定义图表的多项特征,如方向和背景颜色。根据图表类型,绘图有所不同。

Plot Attribute

下表总结了<plot>元素的属性 −

Attribute

Description

Values

backcolor

此属性定义图表背景颜色。

任何六位十六进制值均为该属性的有效值。十六进制值前面必须加上一个 #。

orientation

此属性定义图表的方向。

水平,垂直 默认值是“垂直”

backgroundAlpha

此属性定义图表背景颜色的透明度。

此属性的有效值包括介于 0 和 1(含)之间的任何小数。数字越大,背景越不透明。默认值是“1”。

foregroundAlpha

此属性定义图表前景颜色的透明度。

此属性的有效值包括介于 0 和 1(含)之间的任何小数。数字越大,背景越不透明。默认值是“1”。

labelRotation

此属性允许旋转 x 轴上的文本标签,以顺时针或逆时针旋转。此属性仅适用于 x 轴不是数字或不显示日期的图表。

Default value is "0.0."

<plot> 元素有一个子元素 <seriesColor>,其属性有:seriesOrder 和 color。此元素自定义系列的颜色及其在颜色序列中的位置。

Specific Settings for Chart Plots

  1. piePlot − 没有具体设置

  2. pie3DPlot − 包含 depthFactor 属性,一个介于 0 到 1 之间表示饼图深度占绘图区域高度百分比的数字值。

  3. barPlot − 可以显示或隐藏刻度标签、刻度线或项目标签,并为两条轴提供设置。

  4. bar3DPlot − 提供与 barPlot 相同的设置,并使用 xOffset 和 yOffset 属性生成 3D 效果。

  5. linePlot − 可以显示或隐藏连接项目点的线段,可以显示或隐藏与项目点关联的图形,并为两条轴提供设置。

  6. scatterPlot − 类似于 linePlot,它可以显示或隐藏连接项目点的线段,可以显示或隐藏与项目点关联的图形,并为两条轴提供设置。

  7. areaPlot − 为两条轴提供设置。

  8. bubblePlot − 可以通过设置 scaleType 属性设置气泡尺寸,并为两条轴提供设置。

  9. timeSeriesPlot − 可以显示或隐藏连接项目点的线段,可以显示或隐藏与项目点关联的图形,并为两条轴提供设置。

  10. highLowPlot − 可以显示或隐藏开盘刻度、可以显示或隐藏收盘刻度,并为两条轴提供设置。

  11. candlestickPlot − 可以显示或隐藏成交量,并为两条轴提供设置。

  12. meterPlot − 包含刻度形状、刻度角度、度量单位、刻度间隔、刻度颜色、指针颜色、刻度颜色、值显示字体、颜色和格式模式、数据范围和仪表间隔的具体设置。

  13. thermometerPlot − 包含值位置、水银颜色、显示/隐藏值行、值显示字体、颜色和格式模式、数据范围、低范围、中范围和高范围的具体设置。

  14. multiAxisChart − 包含绘图中包含的轴的具体设置。

Types of Charts

JasperReports 提供对多种图表类型的内置支持。它们如下所列 −

  1. pieChart − 饼数据集和饼图的组合。

  2. pie3DChart − 分组饼数据集和饼图 3D 图。

  3. barChart − 类别数据集和条形图的基本组合。

  4. bar3DChart − 封装类别数据集和条形图 3D 图。

  5. xyBarChart − 支持时间段数据集、时间序列数据集和 XY 数据集,并使用条形图呈现轴和项目。

  6. stackedBarChart − 使用类别数据集中的数据,并使用条形图呈现其内容。

  7. stackedBar3DChart − 使用类别数据集中的数据,并使用条形图 3D 图呈现其内容。

  8. lineChart − 分组类别数据集和折线图。

  9. xyLineChart − 分组 XY 数据集和折线图。

  10. areaChart − 使用面积图呈现类别数据集中的项目。

  11. stackedAreaChart − 使用面积图呈现类别数据集中的项目。

  12. xyAreaChart − 使用 XY 数据集中的数据,并通过面积图呈现。

  13. scatterChart − 用散点图封装 XY 数据集。

  14. bubbleChart − 将 XYZ 数据集与气泡图相结合。

  15. timeSeriesChart − 分组时间序列数据集和时间序列图。

  16. highLowChart - 高-低数据集和高-低图的组合。

  17. candlestickChart - 使用来自高-低数据集的数据,但使用特殊的蜡烛图。

  18. meterChart - 使用仪表图的渲染选项,在刻度盘上显示值数据集中的单个值。

  19. thermometerChart - 使用温度计图的渲染选项,显示值数据集中的单个值。

  20. multiAxisChart - 包含多个范围轴,所有这些轴共享一个公共域轴。

Example

为了演示图表,我们编写一个新的报表模板 (jasper_report_template.jrxml)。在此,我们将 <*barChart*> 元素添加到 <pageHeader> 部分,将 <*pieChart*> 添加到 <summary> 部分。我们将以图表形式显示每门功课获得的分数。将其保存到目录 C:\tools\jasperreports-5.0.1\test 。该文件的内容如下所述 −

<?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 = "jasper_report_template" pageWidth = "595" pageHeight = "860"
   columnWidth = "515" leftMargin = "40" rightMargin = "40"
   topMargin = "50" bottomMargin = "50">

   <field name = "subjectName" class = "java.lang.String"/>
   <field name = "marks" class = "java.lang.Integer"/>

   <variable name = "countNumber" class = "java.lang.Integer" calculation = "Count">
      <variableExpression>
         <![CDATA[Boolean.TRUE]]>
      </variableExpression>
   </variable>

   <background>
      <band splitType = "Stretch"/>
   </background>

   <title>
      <band height = "79" splitType = "Stretch"/>
   </title>

   <pageHeader>
      <band height = "200">

         <barChart>
            <chart evaluationTime = "Report">
               <reportElement x = "0" y = "0" width = "555" height = "200"/>

               <chartTitle>
                  <titleExpression>
                     <![CDATA["My First JR Bar Chart"]]>
                  </titleExpression>
               </chartTitle>
            </chart>

            <categoryDataset>
               <dataset incrementType = "None"/>

               <categorySeries>
                  <seriesExpression>
                     <![CDATA[$F{subjectName}]]>
                  </seriesExpression>

                  <categoryExpression>
                     <![CDATA[$F{subjectName}]]>
                  </categoryExpression>

                  <valueExpression>
                     <![CDATA[$F{marks}]]>
                  </valueExpression>

               </categorySeries>
            </categoryDataset>

            <barPlot isShowTickMarks = "false">
               <plot/>
            </barPlot>
         </barChart>

      </band>
   </pageHeader>

   <columnHeader>
      <band height = "20" splitType = "Stretch"/>
   </columnHeader>

   <detail>
      <band height = "20" splitType = "Stretch"/>
   </detail>

   <columnFooter>
      <band height = "20" splitType = "Stretch"/>
   </columnFooter>

   <pageFooter>
      <band height = "20" splitType = "Stretch"/>
   </pageFooter>

   <summary>
      <band height = "400" splitType = "Stretch">

         <pieChart>
            <chart evaluationTime = "Report">
               <reportElement x = "135" y = "0" width = "270" height = "300"/>

               <chartTitle>
                  <titleExpression>
                     <![CDATA["My First JR Pie Chart"]]>
                  </titleExpression>
               </chartTitle>
            </chart>

            <pieDataset>
               <dataset incrementType = "None"/>

               <keyExpression>
                  <![CDATA[$F{subjectName}]]>
               </keyExpression>

               <valueExpression>
                  <![CDATA[$F{marks}]]>
               </valueExpression>
            </pieDataset>

            <piePlot>
               <plot/>
               <itemLabel/>
            </piePlot>
         </pieChart>

      </band>
   </summary>

</jasperReport>

以上文件的内容如下所述 −

  1. 用于创建条形图的 JRXML 元素是 <pageHeader> 中的 </barChart>。它包含一个 </chart> 子元素,其中包含一个定义图表尺寸和位置的 <reportElement> 子元素。

  2. 条形图中的 <dataset> 元素必须包含在 <categoryDataset> 和 </categoryDataset> JRXML 元素之间。

  3. <categoryDataset> 必须包含一个 <categorySeries> 元素。该元素定义条形图将表示的数据元素(在本例中为科目名称)。

  4. <categoryDataset> 还必须包含一个元素,该元素定义如何将数据划分为可比较的类别。在此,数据按科目名称划分。

  5. <valueExpression> 元素定义用于确定图表中每条条形图的值的表达式。在此,我们使用“分数”。

  6. 对于饼图,我们在 <summary> 部分下使用了元素 <pieChart>。它包含一个 </chart> 子元素。

  7. 子元素包含一个报表表达式,指示在图表中用作键的内容。在此,我们使用了 subjectName。

  8. 子元素包含一个用于计算键值的表达式。在此,我们使用了分数。

用于填充报告的 Java 代码保持不变。文件 C:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint\JasperReportFill.java 的内容如下 -

package com.tutorialspoint;

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

import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;

public class JasperReportFill {
   @SuppressWarnings("unchecked")
   public static void main(String[] args) {
      String sourceFileName =
         "C://tools/jasperreports-5.0.1/test/jasper_report_template.jasper";

      DataBeanList DataBeanList = new DataBeanList();
      ArrayList<DataBean> dataList = DataBeanList.getDataBeanList();

      JRBeanCollectionDataSource beanColDataSource = new
         JRBeanCollectionDataSource(dataList);

      Map parameters = new HashMap();

      try {
         JasperFillManager.fillReportToFile( sourceFileName,
            parameters, beanColDataSource);
      } catch (JRException e) {
         e.printStackTrace();
      }
   }
}

由于我们要显示每门功课获得的分数,因此需要更改 POJO。文件 C:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint\DataBean.java 内容如下所述 −

package com.tutorialspoint;

public class DataBean {
   private String subjectName;
   private Integer marks;

   public String getSubjectName() {
      return subjectName;
   }

   public void setSubjectName(String subjectName) {
      this.subjectName = subjectName;
   }

   public Integer getMarks() {
      return marks;
   }

   public void setMarks(Integer marks) {
      this.marks = marks;
   }

}

甚至文件 C:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint\DataBeanList.java 的内容也需要按如下所示进行更新 −

package com.tutorialspoint;

import java.util.ArrayList;

public class DataBeanList {
   public ArrayList<DataBean> getDataBeanList() {
      ArrayList<DataBean> dataBeanList = new ArrayList<DataBean>();

      dataBeanList.add(produce("English", 58));
      dataBeanList.add(produce("SocialStudies", 68));
      dataBeanList.add(produce("Maths", 38));
      dataBeanList.add(produce("Hindi", 88));
      dataBeanList.add(produce("Scince", 78));

      return dataBeanList;
   }

   /*
    * This method returns a DataBean object, with subjectName ,
    * and marks set in it.
    */
   private DataBean produce(String subjectName, Integer marks) {
      DataBean dataBean = new DataBean();

      dataBean.setSubjectName(subjectName);
      dataBean.setMarks(marks);

      return dataBean;
   }
}

Report Generation

接下来,让我们使用我们的常规 ANT 构建过程编译和执行上述文件。文件 build.xml(保存在目录 C:\tools\jasperreports-5.0.1\test 中)的内容如下所示。

导入文件 - baseBuild.xml 从第 Environment Setup 章中获取,并应放置在与 build.xml 相同的目录中。

<?xml version = "1.0" encoding = "UTF-8"?>
<project name = "JasperReportTest" default = "viewFillReport" basedir = ".">
   <import file = "baseBuild.xml" />

   <target name = "viewFillReport" depends = "compile,compilereportdesing,run"
      description = "Launches the report viewer to preview the
      report stored in the .JRprint file.">

      <java classname = "net.sf.jasperreports.view.JasperViewer" fork = "true">
         <arg value = "-F${file.name}.JRprint" />
         <classpath refid = "classpath" />
      </java>
   </target>

   <target name = "compilereportdesing" description = "Compiles the JXML file and
      produces the .jasper file.">

      <taskdef name = "jrc" classname = "net.sf.jasperreports.ant.JRAntCompileTask">
         <classpath refid = "classpath" />
      </taskdef>

      <jrc destdir = ".">
         <src>
            <fileset dir = ".">
               <include name = "*.jrxml" />
            </fileset>
         </src>

         <classpath refid = "classpath" />
      </jrc>
   </target>

</project>

接下来,让我们打开命令行窗口并转到放置 build.xml 的目录。最后,执行以下命令 ant -Dmain-class=com.tutorialspoint.JasperReportFill (viewFullReport 是默认目标) -

C:\tools\jasperreports-5.0.1\test>ant -Dmain-class=com.tutorialspoint.JasperReportFill
Buildfile: C:\tools\jasperreports-5.0.1\test\build.xml

clean-sample:
   [delete] Deleting directory C:\tools\jasperreports-5.0.1\test\classes
   [delete] Deleting: C:\tools\jasperreports-5.0.1\test\jasper_report_template.jasper
   [delete] Deleting: C:\tools\jasperreports-5.0.1\test\jasper_report_template.jrprint

compile:
   [mkdir] Created dir: C:\tools\jasperreports-5.0.1\test\classes
   [javac] C:\tools\jasperreports-5.0.1\test\baseBuild.xml:28:
   warning: 'includeantruntime' was not set, defaulting to bu
   [javac] Compiling 3 source files to C:\tools\jasperreports-5.0.1\test\classes

compilereportdesing:
   [jrc] Compiling 1 report design files.
   [jrc] log4j:WARN No appenders could be found for logger
   (net.sf.jasperreports.engine.xml.JRXmlDigesterFactory).
   [jrc] log4j:WARN Please initialize the log4j system properly.
   [jrc] log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig
      for more info.
   [jrc] File : C:\tools\jasperreports-5.0.1\test\jasper_report_template.jrxml ... OK.

run:
   [echo] Runnin class : com.tutorialspoint.JasperReportFill
   [java] log4j:WARN No appenders could be found for logger
   (net.sf.jasperreports.extensions.ExtensionsEnvironment).
   [java] log4j:WARN Please initialize the log4j system properly.

viewFillReport:
   [java] log4j:WARN No appenders could be found for logger
   (net.sf.jasperreports.extensions.ExtensionsEnvironment).
   [java] log4j:WARN Please initialize the log4j system properly.

BUILD SUCCESSFUL
Total time: 19 minutes 45 seconds

以上编译的结果是在屏幕下方打开一个 JasperViewer 窗口−

report bar chart example
report pie chart example

在此,我们看到条形图是在 pageheader 中创建的,饼图是在 summary 部分中创建的。

JasperReports - Crosstabs

交叉表(交叉制表)报告是包含以表格形式排列数据(行和列)的表的报告。Crosstab 对象用于在主报告中插入交叉表报告。交叉表可与任何级别的数据(名义、序数、间隔或比率)协同使用,通常将存储在报告变量中的汇总数据显示为动态表格的形式。变量用于显示汇总数据,如合计、计数、平均值。

Crosstab Properties

JRXML 元素 <*crosstab*> 用于将交叉表插入报告。

Attribute

以下是一些 <*crosstab*> 元素的属性列表 -

  1. isRepeatColumnHeaders − 指示是否应在分页符之后重新打印列标题。默认值为 true。

  2. isRepeatRowHeaders − 指示是否应在交叉表列中断后重新打印行标题。默认值为 true。

  3. columnBreakOffset − 当列中断发生时,表示在同一页上的前一个下方放置随后的交叉表部分之前的垂直空间量(以像素为单位)。默认值为 10。

  4. runDirection − 表示应从左至右 (LTR) 填充交叉表数据还是从右至左 (RTL) 填充交叉表数据。默认值为 LTR。

  5. ignoreWidth − 表示交叉表将超出于初始交叉表宽度限制,且不生成列中断。否则,它将停止在交叉表宽度限制内呈现列,且仅在所有行开始呈现后才继续处理其余列。默认值为 false。

Sub Elements

<crosstab> 元素下有以下子元素 -

  1. &lt;reportElement&gt; − 此元素定义交叉表在封闭元素中的位置、宽度和高度。此元素的属性包括所有标准的 <reportElement> 属性。

  2. &lt;crosstabParameter&gt; − 此元素用于从交叉表中访问报告变量和参数。此元素的属性包括 -name - 此属性定义参数名称。class - 此属性指示参数类。

  3. &lt;parametersMapExpression&gt; − 此元素用于传递报告变量或包含 java.util.Map 实例的参数,作为交叉表的一组参数。此元素不包含任何属性。

  4. &lt;crosstabDataset&gt; − 此元素定义用于填充交叉表的 a 数据集(有关详细说明,请参见下一节)。此元素的属性包括 -isDataPreSorted - 此属性指示数据集中数据的预排序状态。默认值为 false。

  5. &lt;crosstabHeaderCell&gt; − 此元素定义交叉表左上角区域的内容,在此区域中列标题和行标题交汇。此单元格的大小根据已定义的行宽和行高自动计算。

  6. &lt;rowGroup&gt; - 此元素定义了一个用于将数据分割成行的组。此元素的属性包括 -name - 用于定义行组的名称。width - 用于定义行组的宽度。headerPosition - 用于定义页眉内容的位置(顶部、中部、底部、拉伸)。totalPosition - 用于定义整列的位置(开始、结束、无)。此元素包含以下子元素 -<bucket><crosstabRowHeader><crosstabTotalRowHeader>

  7. &lt;columnGroup&gt; - 此元素定义了一个用于将数据分割成列的组。此元素的属性包括 -name - 用于定义列组名称。height - 用于定义列组页眉的宽度。headerPosition - 用于定义页眉内容的位置(右侧、左侧、中心、拉伸)。totalPosition - 用于定义整列的位置(开始、结束、无)。此元素包含以下子元素 -<bucket><crosstabColumnHeader><crosstabTotalColumnHeader>

  8. &lt;measure&gt; - 此元素定义在行和列中执行的计算。此元素的属性包括 -name - 用于定义度量名称。class - 用于指示度量类别。calculation - 用于指示要在交叉表单元格值之间执行的计算。其值可以是以下任意值:无、计数、计数、和、平均、最低、最高、标准差、方差和第一个。默认值是 Nothing

  9. &lt;crosstabCell&gt; - 此元素定义非页眉单元格中的数据布局方式。此元素的属性包括 -columnTotalGroup - 用于指示用于计算列总数的组。height - 用于定义单元格的高度。rowTotalGroup - 用于指示用于计算行总数的组。width - 用于定义单元格的宽度。

  10. &lt;whenNoDataCell&gt; - 此元素定义在空交叉表单元格中显示的内容。此元素不包含任何属性。

Data Grouping in Crosstab

交叉表计算引擎通过遍历关联数据集记录来聚合数据。要聚合数据,首先需要对数据进行分组。在交叉表中,行和列基于特定的组项(称为 buckets )。存储段定义应包含 -

  1. bucketExpression - 要评估以获取数据组项的表达式。

  2. comparatorExpression - 如果值的自然排序不是最佳选择,则需要此项。

  3. orderByExpression - 用于指示用于对数据进行排序的值。

交叉表中的行和列组(上述定义)依赖于 buckets

Built-In Crosstab Total Variables

下面是按名称命名的变量中可访问的与单元格对应的当前度量值和不同级别的总计列表:

  1. 度量计算的当前值存储在与度量同名的变量中。

  2. <Measure>_<Column Group>_ALL - 这将生成来自同一行的列组中所有条目的总计。

  3. <Measure>_<Row Group>_ALL - 这将生成来自同一列的行组中所有条目的总计。

  4. <Measure>_<Row Group>_<Column Group>_ALL - 这将生成对应于行组和列组中所有条目的合并总计。

Example

为了演示交叉表,让我们编写一个新的报表模板(jasper_report_template.jrxml)。在此处,我们将交叉表添加到摘要部分。将其保存到目录 C:\tools\jasperreports-5.0.1\test 。该文件的具体内容如下:

<?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 = "jasper_report_template" language = "groovy" pageWidth = "595"
   pageHeight = "842" columnWidth = "555" leftMargin = "20" rightMargin = "20"
   topMargin = "20" bottomMargin = "20">

   <parameter name = "ReportTitle" class = "java.lang.String"/>
   <parameter name = "Author" class = "java.lang.String"/>

   <field name = "name" class = "java.lang.String"/>
   <field name = "country" class = "java.lang.String"/>

   <title>
      <band height = "70">

         <line>
            <reportElement x = "0" y = "0" width = "515" height = "1"/>
         </line>

         <textField isBlankWhenNull = "true" bookmarkLevel = "1">
            <reportElement x = "0" y = "10" width = "515" height = "30"/>

            <textElement textAlignment = "Center">
               <font size = "22"/>
            </textElement>

            <textFieldExpression class = "java.lang.String">
               <![CDATA[$P{ReportTitle}]]>
            </textFieldExpression>

            <anchorNameExpression>
               <![CDATA["Title"]]>
            </anchorNameExpression>
         </textField>

         <textField isBlankWhenNull = "true">
            <reportElement  x = "0" y = "40" width = "515" height = "20"/>

            <textElement textAlignment = "Center">
               <font size = "10"/>
            </textElement>

            <textFieldExpression class = "java.lang.String">
               <![CDATA[$P{Author}]]>
            </textFieldExpression>
         </textField>

      </band>
   </title>

   <summary>
      <band height = "60">

      <crosstab>
         <reportElement width = "782" y = "0" x = "0" height = "60"/>

         <rowGroup name = "nameGroup" width = "100">

            <bucket>
               <bucketExpression class = "java.lang.String">
                  <![CDATA[$F{name}]]>
               </bucketExpression>
            </bucket>

            <crosstabRowHeader>

               <cellContents>
                  <box border = "Thin" borderColor = "black"/>

                  <textField>
                     <reportElement width = "100" y = "0" x = "0" height = "20"/>
                     <textElement textAlignment = "Right"
                        verticalAlignment = "Middle"/>

                     <textFieldExpression>
                        <![CDATA[$V{nameGroup}]]>
                     </textFieldExpression>
                  </textField>

               </cellContents>

            </crosstabRowHeader>

         </rowGroup>

         <columnGroup name = "countryGroup" height = "20">
            <bucket>

               <bucketExpression class = "java.lang.String">
                  $F{country}
               </bucketExpression>
            </bucket>

            <crosstabColumnHeader>
               <cellContents>
                  <box border = "Thin" borderColor = "black"/>
                  <textField isStretchWithOverflow = "true">
                     <reportElement width = "60" y = "0" x = "0" height = "20"/>
                     <textElement verticalAlignment = "Bottom"/>
                     <textFieldExpression>
                        <![CDATA[$V{countryGroup}]]>
                     </textFieldExpression>
                  </textField>
               </cellContents>
            </crosstabColumnHeader>

         </columnGroup>

         <measure name = "tailNumCount" class = "java.lang.Integer"
            calculation = "Count">
            <measureExpression>$F{country}</measureExpression>
         </measure>

         <crosstabCell height = "20" width = "60">
            <cellContents backcolor = "#FFFFFF">
               <box borderColor = "black" border = "Thin"/>
               <textField>
                  <reportElement x = "5" y = "0" width = "55" height = "20"/>
                  <textElement textAlignment = "Left"
                     verticalAlignment = "Bottom"/>
                  <textFieldExpression class = "java.lang.Integer">
                      $V{tailNumCount}
                  </textFieldExpression>
               </textField>
            </cellContents>
         </crosstabCell>

      </crosstab>

      </band>
   </summary>

</jasperReport>

上述文件的详细信息如下:

  1. 交叉表由 <crosstab> 元素定义。

  2. <rowGroup> 元素定义了一个用于将数据分割成行的组。在此处,每行将针对不同的名称显示数据。

  3. <bucket> 和 <bucketExpression> 元素定义要作为 <rowGroup> 组分隔符使用的报告表达式。在这里,我们使用 name 字段作为分隔符,以便按 name 拆分行。

  4. <crosstabRowHeader> 元素定义要作为行标题使用的表达式。它包含一个 <cellContents> 子元素,该子元素类似于 crosstab 中的内部频带。我们已经将 <crosstabRowHeader> 中文本字段的变量名称分配给 <rowGroup>(通过其名称属性),因而创建了隐式变量,而不是为该变量定义名称。<crosstabRowHeader> 元素定义针对整行的标题单元格的内容。它只将一个 <cellContents> 元素作为其唯一子元素。

  5. <columnGroup> 元素及其子元素类似于 <rowGroup> 元素,但它们影响列而不是行。

  6. <measure> 元素定义将在行和列中执行的计算。计算属性设置为 Count。

  7. <crosstabCell> 元素定义非标题单元格中的数据将如何布置。此元素还包含一个 <crosstabCell> 元素作为其唯一子元素。

用于填充报告的 Java 代码保持不变。文件 C:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint\JasperReportFill.java 的内容如下 -

package com.tutorialspoint;

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

import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;

public class JasperReportFill {
   @SuppressWarnings("unchecked")
   public static void main(String[] args) {
      String sourceFileName =
         "C://tools/jasperreports-5.0.1/test/jasper_report_template.jasper";

      DataBeanList DataBeanList = new DataBeanList();
      ArrayList<DataBean> dataList = DataBeanList.getDataBeanList();

      JRBeanCollectionDataSource beanColDataSource =
      new JRBeanCollectionDataSource(dataList);

      Map parameters = new HashMap();
      /**
       * Passing ReportTitle and Author as parameters
       */
      parameters.put("ReportTitle", "List of Contacts");
      parameters.put("Author", "Prepared By Manisha");

      try {
         JasperFillManager.fillReportToFile(
         sourceFileName, parameters, beanColDataSource);
      } catch (JRException e) {
         e.printStackTrace();
      }
   }
}

文件 C:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint\DataBean.java 的内容如下 -

package com.tutorialspoint;

public class DataBean {
   private String name;
   private String country;

   public String getName() {
      return name;
   }

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

   public String getCountry() {
      return country;
   }

   public void setCountry(String country) {
      this.country = country;
   }
}

文件 C:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint\DataBeanList.java 的内容如下 -

package com.tutorialspoint;

import java.util.ArrayList;

public class DataBeanList {
   public ArrayList<DataBean> getDataBeanList() {
      ArrayList<DataBean> dataBeanList = new ArrayList<DataBean>();

      dataBeanList.add(produce("Manisha", "India"));
      dataBeanList.add(produce("Dennis Ritchie", "USA"));
      dataBeanList.add(produce("V.Anand", "India"));
      dataBeanList.add(produce("Shrinath", "California"));

      return dataBeanList;
   }

   /**
    * This method returns a DataBean object,
    * with name and country set in it.
    */
   private DataBean produce(String name, String country) {
      DataBean dataBean = new DataBean();
      dataBean.setName(name);
      dataBean.setCountry(country);

      return dataBean;
   }
}

Report Generation

接下来,让我们使用我们的常规 ANT 构建过程编译和执行上述文件。文件 build.xml(保存在目录 C:\tools\jasperreports-5.0.1\test 中)的内容如下所示。

导入文件 - baseBuild.xml 从第 Environment Setup 章中获取,并应放置在与 build.xml 相同的目录中。

<?xml version = "1.0" encoding = "UTF-8"?>
<project name = "JasperReportTest" default = "viewFillReport" basedir = ".">
   <import file = "baseBuild.xml" />

   <target name = "viewFillReport" depends = "compile,compilereportdesing,run"
      description = "Launches the report viewer to preview the
      report stored in the .JRprint file.">

      <java classname = "net.sf.jasperreports.view.JasperViewer" fork = "true">
         <arg value = "-F${file.name}.JRprint" />
         <classpath refid = "classpath" />
      </java>
   </target>

   <target name = "compilereportdesing" description = "Compiles the JXML file and
      produces the .jasper file.">

      <taskdef name = "jrc" classname = "net.sf.jasperreports.ant.JRAntCompileTask">
         <classpath refid = "classpath" />
      </taskdef>

      <jrc destdir = ".">
         <src>
            <fileset dir = ".">
               <include name = "*.jrxml" />
            </fileset>
         </src>
         <classpath refid = "classpath" />
      </jrc>

   </target>

</project>

接下来,让我们打开命令行窗口并转到放置 build.xml 的目录。最后,执行以下命令 ant -Dmain-class=com.tutorialspoint.JasperReportFill (viewFullReport 是默认目标) -

C:\tools\jasperreports-5.0.1\test>ant -Dmain-class=com.tutorialspoint.JasperReportFill
Buildfile: C:\tools\jasperreports-5.0.1\test\build.xml

clean-sample:
   [delete] Deleting directory C:\tools\jasperreports-5.0.1\test\classes
   [delete] Deleting: C:\tools\jasperreports-5.0.1\test\jasper_report_template.jasper

compile:
   [mkdir] Created dir: C:\tools\jasperreports-5.0.1\test\classes
   [javac] C:\tools\jasperreports-5.0.1\test\baseBuild.xml:28:
   warning: 'includeantruntime' was not set, defaulting to
   [javac] Compiling 3 source files to C:\tools\jasperreports-5.0.1\test\classes

compilereportdesing:
   [jrc] Compiling 1 report design files.
   [jrc] log4j:WARN No appenders could be found for logger
   (net.sf.jasperreports.engine.xml.JRXmlDigesterFactory).
   [jrc] log4j:WARN Please initialize the log4j system properly.
   [jrc] log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig
      for more info.
   [jrc] File : C:\tools\jasperreports-5.0.1\test\jasper_report_template.jrxml ... OK.

run:
   [echo] Runnin class : com.tutorialspoint.JasperReportFill
   [java] log4j:WARN No appenders could be found for logger
   (net.sf.jasperreports.extensions.ExtensionsEnvironment).
   [java] log4j:WARN Please initialize the log4j system properly.

viewFillReport:
   [java] log4j:WARN No appenders could be found for logger (
   net.sf.jasperreports.extensions.ExtensionsEnvironment).
   [java] log4j:WARN Please initialize the log4j system properly.

BUILD SUCCESSFUL
Total time: 20 minutes 53 seconds

作为上述编译的结果,一个 JasperViewer 窗口会打开,如以下给出的屏幕截图所示 -

report crosstab example

在这里,我们看到每个国家和名称都被制成表格。

JasperReports - Internationalization

有时,我们需要不同语言的报表。针对每种不同的语言编写相同的报表意味很多冗余工作。只有不同于不同语言的文本部分才应该单独编写,并在运行时根据语言环境设置加载到文本元素中。这就是报表国际化的目的。一旦编写了国际化报表,就可以在任何地方运行。

在下面的步骤中,我们列出了如何用不同的语言生成报表以及报表国际化的其他一些特性 -

  1. 将资源包 java.util.ResourceBundle 与报表模板相关联。有两种方法可以将 java.util.ResourceBundle 对象与报表模板关联。在设计时,通过将报表模板对象的 resourceBundle 属性设置为目标资源包的基名称。通过在填充报表时提供 java.util.ResourceBundle 对象作为 REPORT_RESOURCE_BUNDLE 参数的值,可以进行动态/运行时关联。如果需要以不同于当前语言环境的语言环境生成报表,则可以使用内置的 REPORT_LOCALE 参数在填充报表时指定运行时语言环境。

  2. 为了方便报表国际化,报表表达式中提供了特殊语法 $R{} 来引用放置在与报表关联的 java.util.ResourceBundle 对象中的 java.lang.String 资源。 $R{} 字符语法根据必须放在括号内的键从资源包中提取特定于语言环境的资源 -

<textFieldExpression>
   $R{report.title}
</textFieldExpression>

上面的文本字段通过基于运行时提供的语言环境和 report.title 键从与报表模板关联的资源包中提取 String 值来显示报表的标题。

  1. 根据报表语言环境用不同语言格式化消息,reports net.sf.jasperreports.engine.fill.JRCalculator 内部有一个内置方法。此方法提供与 java.text.MessageFormat 类类似的功能。此方法 msg() 有三个方便的签名,允许你在消息中使用最多三个消息参数。

  2. 内置 str() 方法(相当于报表表达式中的 $R{} 语法),它根据报表语言环境访问资源包内容。

  3. 对于日期和时间格式化,可以使用内置的 REPORT_TIME_ZONE 参数来确保正确的时间转换。

  4. 在生成的输出中,该库会保留有关文本运行方向的信息,以便可以正确呈现用从右到左书写的语言(如阿拉伯语和希伯来语)生成的文档。

  5. 如果应用程序依赖于内置 Swing 查看器来显示生成的报表,那么需要通过调整按钮 ToolTips 或其他显示的文本来对其进行国际化。由于查看器依赖于预定义的资源包来提取特定于语言环境的信息,因此这样很容易。此资源包的基名称为 net.sf.jasperreports.view.viewer。

Example

为了演示国际化,让我们编写新的报表模板(jasper_report_template.jrxml)。JRXML 的内容如下所示。将其保存到 C:\tools\jasperreports-5.0.1\test 目录。

<?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 = "jasper_report_template" language = "groovy" pageWidth = "595"
   pageHeight = "842" columnWidth = "555" leftMargin = "20" rightMargin = "20"
   topMargin = "20" bottomMargin = "20" resourceBundle = "localizationdemo">

   <title>
      <band height = "552">

         <textField>
            <reportElement positionType = "Float" x = "150" y = "20"
               width = "400" height = "50"/>

            <textElement>
               <font size = "24"/>
            </textElement>

            <textFieldExpression class = "java.lang.String">
               <![CDATA[$P{REPORT_LOCALE}.getDisplayName ($P{REPORT_LOCALE})]]>
            </textFieldExpression>
         </textField>

         <textField isStretchWithOverflow = "true" isBlankWhenNull = "true">
            <reportElement positionType = "Float" x = "20" y = "125"
               width = "530" height = "20"/>

            <textElement textAlignment = "Justified">
               <font size = "14"/>
            </textElement>

            <textFieldExpression class = "java.lang.String">
               <![CDATA[$R{localization.text1}]]>
            </textFieldExpression>

         </textField>

      </band>
   </title>

</jasperReport>

在上面的文件中,<jasperReport> 元素的 resourceBundle 属性告诉 JasperReports 到哪里去获取供报表使用的本地化字符串。我们需要创建一个属性文件,其根名称与该属性值相匹配。填充报表时,此文件必须存在于 CLASSPATH 中的任意位置。在此示例中,属性文件 localizationdemo.properties 保存到目录 C:\tools\jasperreports-5.0.1\test 下。此文件的内容如下 -

localization.text1 = This is English text.

要使用不同的语言环境,该文件的文件名必须是 localizationdemo[locale].properties。在此,我们为西班牙语语言环境编写一个文件。将此文件另存为 - C:\tools\jasperreports-5.0.1\test\localizationdemo_es.properties 。此文件的内容如下 -

localization.text1 = Este texto es en Español.

获取 resourceBundle 属性值的语法为 $R{key}。

为了让 JasperReports 知道我们希望使用的语言环境,我们需要给内置参数分配一个值。此参数的名称定义为一个常量 REPORT_LOCALE,此常量在 net.sf.jasperreports.engine.JRParameter 类中定义。此常量的值必须是 java.util.Locale 的一个实例。此逻辑被纳入到用于填充和生成报表的 Java 代码中。让我们将此文件 JasperReportFillI18.java 保存到目录 C:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint 下。该文件的内容如下 -

package com.tutorialspoint;

import java.util.HashMap;
import java.util.Locale;

import net.sf.jasperreports.engine.JREmptyDataSource;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRParameter;
import net.sf.jasperreports.engine.JasperFillManager;

public class JasperReportFillI18 {

   public static void main(String[] args) {
      String sourceFileName = "C://tools/jasperreports-5.0.1/test/"
         + "jasper_report_template.jasper";
      HashMap parameterMap = new HashMap();
      if (args.length > 0) {
         parameterMap.put(JRParameter.REPORT_LOCALE, new Locale(args[0]));
      }
      try {
         JasperFillManager.fillReportToFile(sourceFileName, null,
            new JREmptyDataSource());
      } catch (JRException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
      }

   }
}

Report Generation

我们将使用常规 ANT 构建流程编译并执行上述文件。build.xml 文件(保存在 C:\tools\jasperreports-5.0.1\test 目录下)的内容如下。

导入文件 - baseBuild.xml 从第 Environment Setup 章中获取,并应放置在与 build.xml 相同的目录中。

<?xml version = "1.0" encoding = "UTF-8"?>

<project name = "JasperReportTest" default = "viewFillReport" basedir = ".">
   <import file = "baseBuild.xml" />

   <target name = "viewFillReport" depends = "compile,compilereportdesing,run"
      description = "Launches the report viewer to preview the report stored
      in the .JRprint file.">

      <java classname = "net.sf.jasperreports.view.JasperViewer" fork = "true">
         <arg value = "-F${file.name}.JRprint" />
         <classpath refid = "classpath" />
      </java>
   </target>

   <target name = "compilereportdesing" description = "Compiles the JXML file and
      produces the .jasper file.">

      <taskdef name = "jrc" classname = "net.sf.jasperreports.ant.JRAntCompileTask">
         <classpath refid="classpath" />
      </taskdef>

      <jrc destdir = ".">
         <src>
            <fileset dir = ".">
               <include name = "*.jrxml" />
            </fileset>
         </src>
         <classpath refid = "classpath" />
      </jrc>

   </target>

</project>

接下来,让我们打开命令行窗口并转到放置 build.xml 的目录。最后,执行命令 ant -Dmain-class=com.tutorialspoint.JasperReportFillI18 (viewFullReport 是默认目标),如下所示 -

C:\tools\jasperreports-5.0.1\test>ant  -Dmain-class=com.tutorialspoint.JasperReportFillI18
Buildfile: C:\tools\jasperreports-5.0.1\test\build.xml

clean-sample:
   [delete] Deleting directory C:\tools\jasperreports-5.0.1\test\classes
   [delete] Deleting: C:\tools\jasperreports-5.0.1\test\jasper_report_template.jasper
   [delete] Deleting: C:\tools\jasperreports-5.0.1\test\jasper_report_template.jrprint

compile:
   [mkdir] Created dir: C:\tools\jasperreports-5.0.1\test\classes
   [javac] C:\tools\jasperreports-5.0.1\test\baseBuild.xml:28:
   warning: 'includeantruntime' was not set, defaulting to
   [javac] Compiling 1 source file to C:\tools\jasperreports-5.0.1\test\classes
   [javac] Note: C:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint\
      JasperReportFillI18.java
   uses unchecked or u
   [javac] Note: Recompile with -Xlint:unchecked for details.

compilereportdesing:
   [jrc] Compiling 1 report design files.
   [jrc] log4j:WARN No appenders could be found for logger
   (net.sf.jasperreports.engine.xml.JRXmlDigesterFactory).
   [jrc] log4j:WARN Please initialize the log4j system properly.
   [jrc] log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig
      for more info.
   [jrc] File : C:\tools\jasperreports-5.0.1\test\jasper_report_template.jrxml ... OK.

run:
   [echo] Runnin class : com.tutorialspoint.JasperReportFillI18
   [java] log4j:WARN No appenders could be found for logger
   (net.sf.jasperreports.extensions.ExtensionsEnvironment).
   [java] log4j:WARN Please initialize the log4j system properly.

viewFillReport:
   [java] log4j:WARN No appenders could be found for logger
   (net.sf.jasperreports.extensions.ExtensionsEnvironment).
   [java] log4j:WARN Please initialize the log4j system properly.

BUILD SUCCESSFUL
Total time: 3 minutes 28 seconds

作为上述编译的结果,一个 JasperViewer 窗口会打开,如以下给出的屏幕截图所示 -

report i18 example