JasperReports_3.5_ch03

JasperReports_3.5_ch03

2023年7月13日发(作者:)

3

创建第一份报表

本章我们将创建、编译、预览我们的第一份报表。

通过本章学习,我们将能够:

创建一份简单的JRXML报表模板

用JasperReports自定义ANT目标来预览报表模板

编译JRXML文件生成Jasper二进制报表模板

编写从JasperReports模板生成报表的代码

通过JaspreReports提供的工具浏览生成的JasperReports本地格式报表

生成能够显示在web浏览器中的报表

识别与报表中各片段相对应的JRXML元素

创建JRXML报表模板

创建报表的第一步是创建一份JRXML模板,我们在第1章中介绍了,JasperReports的JRXML模板是标准的XML文件。但是,依照惯例,其扩展名为.jrxml,称为JRXML文件或JRXML模板。JRXML模板可以手工编写,也可以使用可视化报表模板生成工具。时下,最流行的JRXML报表模板生成工具是iReport。我们将在第10章中介绍它。

山西老醯儿(FromSX)

·23·所有的JRXML文件都包含一个根元素,它又包含若干子元素。所有的子元素都是可选的。因为而我们在这一章里主要是感受一下怎样设计报表,所以略掉了大多数子元素,而只用了一个名为的子元素。

我们的第一份报表将显示一个静态的字符串,其JRXML如下:

xmlns="/jasperreports"

xmlns:xsi="/2001/XMLSchema-instance"

xsi:schemaLocation="/

jasperreports jasperreports.

/xsd/"

name="FirstReport">

在这个JRXML文件的元素中,有些我们在前面的章节中还没有接触过。例如:

定义了静态文本,它不需要依赖于任何数据源、变量、参数或报表表达式。

定义了元素的位置和宽度。

定义了显示在报表上的实际的静态文本。

在上面的例子中,我们看到了元素。元素只能包含一个单独的元素作为其子元素,而元素可以包含许多不同的元素,用来显示文本、图表、图片或几何图形。本例中,它只包含了一个元素。

山西老醯儿(FromSX)

·24·对于元素和所有元素的子元素,元素都是必需的。中的定

义的x和y相对于包含它的父元素(本例中为)。

预览XML报表模板

JasperReports里有个工具可以用来预览报表的设计效果,它使得报表的设计更加快速。通过它,我们不用编译和填充就能立即对报表进行预览。

该工具是一个独立的Java应用程序,它包含在JasperReports的JAR文件中。需要执行的类是DesignViewer,执行它的最简单方法是把所有需要的库都添加到CLASSPATH中,然后使用ANT目标来运行它,这也是在工程JAR文件中的JasperReports范例所使用的方法,下面的ANT构建文件将加载JasperDesignViewer来预览我们刚完成的报表:

basedir=".">

Previews our First Report XML Design

value="/opt/jasperreports-3.5.2"/>

description="Launches the design viewer to preview the XML

report design.">

山西老醯儿(FromSX)

·25·

fork="true">

这个ANT构建文件必须和JRXML文件保存在相同的目录中,建议把JRXML文件的报表名和文件名使用一致的名称。报表名称在根元素中定义,在这里,我们用FirstReport作为报表名称。因此,建议报表模板的文件名使用。

如果我们保存ANT构建文件为标准名称,就不需要在命令行中再指定构建文件名。此处的示例中,构建文件有一个名为viewDesignXML的目标元素。由于它是缺省的目标,我们就不需要在命令行中指定它。只需要在命令行输入ant,缺省的目标就会被执行,并显示出预览报表。

$ ant

Buildfile:

viewDesignXML:

执行完viewDesignXML目标后,我们会看到一个窗口显示出预览状态的报表模板,其标签名称为JasperDesignViewer。

通过关闭窗口,或在命令行窗口中输入Ctrl-c,这个JasperDesignViewer可以被安全地关闭。

山西老醯儿(FromSX)

·26· 在这个特殊的例子中中,我们能在预览状态下看到全部文本,这是因为此报表只包含了静态文本。如果报表的数据是来源于数据库或报表参数,此处不会显示实际文本,而是显示包含了要显示这是因为JasperDesignViewer不会对数据源

的数据的表达式。或报表参数进行实际访问。

创建二进制报表模板

JRXML不能用来直接生成报表,它们需要被编译成JasperReports的本地二进制格式,编译后的报表模板称为Jasper文件。有两种不同的方法来把JRXML文件编译成Jasper文件:通过编程实现,或通过JasperReports提供的自定义ANT任务来实现。

通过编程来编译JRXML模板

通过调用CompileManager类的compileReportToFile()方法,可以把JRXML模板编译成Jasper文件。eReportToFile()方法有三个重载版本,如下所示:

eReportToFile(String

sourceFileName)

eReportToFile(String

sourceFileName, String destFileName)

eReportToFile(JasperDesign

jasperDesign, String destFileName)

下面的表格对这些方法的参数进行了说明:

参数

String sourceFileName

说明

此参数指定JRXML模板的位置,它被用于编译生成报表模板。它可以是绝对路径,也可以相对路径。编译生成山西老醯儿(FromSX)

·27·的报表模板会以相同的文件名保存到和它相同的位置,并以.jasper作为扩展名。

String destFileName

此参数指定在文件系统中用于保存编译生成的报表模板的文件名,它可以是绝对路径或相对路径。

JasperDesign jasperDesign

这是报表在内存中的存在形式,Design实例可以通过在oader中调用相应的方法来创建。

下面的代码段演示了怎样使用eReportToFile()方法:

package book;

import ption;

import CompileManager;

public class FirstReportCompile

{

public static void main(String[] args)

{

try

{

n("");

eReportToFile(

"reports/");

n("Done!");

}

catch (JRException e)

{

tackTrace();

}

}

}

编译执行上面的代码,我们会得到一个名为的文件。此文件就是编译生成的JasperReports本地格式的模板。在本例中,我们使用前面讨论的第一个版本的eReportToFile()方法,源文件名会被用于编译生成的报表。如果我们希望编译后的报表为不同的文件名,就需要使用第二个版本的山西老醯儿(FromSX)

·28·eReportToFile()方法,并在其第二个参数中指定要生成的名字。

预览编译后的报表模板

前面讨论的DesignViewer可用于预览编译后的报表模板,就象JRXML模板一样。执行此工具的最简单的方法是在ANT目标中封装一个调用。下面,我们在文件中添加第二个ANT目标,并把它命名为viewDesign,它将使我们能够预览编译后的报表。

basedir=".">

Previews and compiles our First Report

value="/opt/jasperreports-3.5.2" />

description="Launches the design viewer to preview the XML

report design.">

fork="true">

description="Launches the design viewer to preview the

compiled report design.">

山西老醯儿(FromSX)

·29·

fork="true">

description="Compiles the XML report design and produces the

.jasper file.">

classname="ompileTask">

description="Launches the report viewer to preview the

report stored in the .jrprint file.">

fork="true">

我们可以从命令行调用这个新目标:

ant viewDesign

调用完成后,我们会看到一个和前面的JRXML模板预览相同的窗口。

用ANT来编译JRXML模板

山西老醯儿(FromSX)

·30·JasperReports包含一个自定义的ANT任务,用它可以来编译报表模板。其编译方式非常便利,我们不需要编写执行编译的代码。然而,对于一些特殊的应用程序,还是需要通过编写相应的代码来编译报表的(比如JRXML文件是在运行时进行才创建的情况)。JasperReports中的自定义ANT任务在ompileTask类中进行定义,名为jrc。下面,让我们在中添加第三个自定义的目标来调用jrc任务。

basedir=".">

Previews and compiles our First Report

value="/opt/jasperreports-3.5.2" />

description="Launches the design viewer to preview the XML

report design.">

fork="true">

description="Launches the design viewer to preview the

compiled report design.">

fork="true">

山西老醯儿(FromSX)

·31·

description="Compiles the XML report design and produces the

.jasper file.">

classname="ompileTask">

可以从命令行来调用这个新目标:

ant compile

编译目标会产生如下的输出:

Buildfile:

compile:

[jrc] Compiling 1 report design files.

[jrc] File :

/home/heffel/NetBeansProjects/Code_8082/jasper_book_

chapter_3/reports/ ... OK.

BUILD SUCCESSFUL

Total time: 3 seconds

目标编译完成后,我们会在文件系统里得到一个文件。

这个文件和通过调用eReportToFile()方法生成的文件是一样的。

山西老醯儿(FromSX)

·32·这里生成的Jasper文件也可以用JasperReports中包含的JasperDesign工具进行预览,其方法和输出与前面章节介绍的是相同的。

生成报表

按照JasperReports的习惯,从报表模板或Jasper文件生成报表的处理过程,称为填充(filling)报表。报表通过编写程序来进行填充,具体调用的是FillManager类的fillReportToFile()方法。此方法会将填充完报表并把它保存到磁盘。

fillReportToFile()方法有六个重载版本,如下所示:

portToFile(JasperReport jasperReport,

String destFileName, Map parameters, Connection connection)

portToFile(JasperReport jasperReport,

String destFileName, Map parameters, JRDataSource

datasource)

portToFile(String sourceFileName, Map

parameters, Connection connection)

portToFile(String sourceFileName, Map

parameters, JRDatasource dataSource)

portToFile(String sourceFileName,

String destFileName, Map parameters, Connection connection)

portToFile(String sourceFileName,

String destFileName, Map parameters, JRDataSource

dataSource)

下面的表格对这些方法的参数进行了说明:

参数 说明

山西老醯儿(FromSX)

·33·JasperReport jasperReport

此参数用于报表模板,Report实例是编译后的报表模板在内存中的存在形式。

String destFileName

Map parameters

指定用于保存报表的目标文件名。

这是一个接口实现类的实例,用于初始化报表模板中定义的所有报表参数。

Connection connection

此参数用于连接数据库,以便执行报表模板中定义的SQL查询。

JRDataSource dataSource

这是一个Source接口实现类的实例。

可以看出,在大多数情况下,我们通过一个实现了Source接口的类实例来传送填充报表的数据。报表模板可以包含内嵌的SQL查询,它们定义在JRXML文件的元素中。包含有SQL查询的报表不会传递JRDataSource,而是传递一个实现了tion接口的类实例。JasperReports再用这个Connection对象执行查询,从数据库获取报表数据。

尽管在报表模板中嵌入SQL查询可以简化开发,但传递JRDataSource还有其它的好处。即相同的报表可以使用不同的数据源,如数据库、CSV文件、Java对象,等等。我们将在第5章中详细讨论JasperReports对其它数据源的支持。

在这里的报表例子中,我们只包含了静态文本,不需要显示动态数据。由于没有JRDataSource或Connection就没办法填充报表,因此JaspreReports提供了一个不包含任何数据的JRDataSoruce实现,其名称为JREmptyDataSource。另外,由于我们这里的报表没有参数,所以只需传递一个p的空实例。我们将遵循JasperReports推荐的方法,把报表命名为与报表模板相同的名字(不包括文件的扩展名)。考虑到所有这些因素,最适当的fillReportToFile()版本是上面列出的第4个,如下所示:

portToFile(String sourceFileName, Map

parameters, JRDataSource dataSource)

下面的Java类将添充报表,并把它保存在磁盘里:

山西老醯儿(FromSX)

·34·package book;

import p;

import yDataSource;

import ption;

import FillManager;

public class FirstReportFill

{

public static void main(String[] args)

{

try

{

n("");

portToFile("reports/",

new HashMap(),

new JREmptyDataSource());

n("Done!");

}

catch (JRException e)

{

tackTrace();

}

}

}

执行这个类,我们会在编译报表模板的目录里得到一个名为t的文件。

查看报表

JasperReports中有个工具名为Viewer的类,可以用来查看生成的报表。和报表设计预览的工具一样,其最简使用方法是:把它包装到ANT目标里。这是JasperReprots内含示例程序所使用的方法,也是我们这里将要使用的方法。现在让我们添加一个新的目标到ANT构建文件中,按照JasperReports范例中的惯例,我们将此目标命名为“view”。

basedir=".">

Previews and compiles our First Report

value="/opt/jasperreports-3.5.2" />

description="Launches the design viewer to preview the XML

report design.">

fork="true">

description="Launches the design viewer to preview the

compiled report design.">

fork="true">

description="Compiles the XML report design and produces the

.jasper file.">

classname="ompileTask">

山西老醯儿(FromSX)

·36·

description="Launches the report viewer to preview the

report stored in the .jrprint file.">

fork="true">

执行这个新的ANT目标,我们将看到一个如下图所示的窗口:

对,就是它!这就是我们成功创建的第一份报表。

在web浏览器中显示报表

前面我们讨论了怎样创建报表,并用JasperReports的本地格式把它保存到磁盘。下面我们介绍如何在web浏览器里显示报表,这需要借助于Servlet API,如下面的例子所示:

package book;

import ption;

import tream;

import riter;

山西老醯儿(FromSX)

·37·import Writer;

import p;

import tException;

import tOutputStream;

import rvlet;

import rvletRequest;

import rvletResponse;

import yDataSource;

import ption;

import RunManager;

public class FirstReportSendToBrowserServlet extends HttpServlet

{

protected void doGet(HttpServletRequest request, HttpServletResponse

response)

throws ServletException, IOException

{

ServletOutputStream servletOutputStream = response.

getOutputStream();

InputStream reportStream =getServletConfig().getServletContext()

.getResourceAsStream("/reports/");

try

{

ortToPdfStream(reportStream,

servletOutputStream,

new HashMap(),

new JREmptyDataSource());

tentType("application/pdf");

();

();

}

catch (JRException e)

{

// display stack trace in the browser

StringWriter stringWriter = new StringWriter();

PrintWriter printWriter = new PrintWriter(stringWriter);

tackTrace(printWriter);

tentType("text/plain");

putStream().print(ng());

}

}

}

山西老醯儿(FromSX)

·38·由于Web浏览器不能显示JasperReports的本地格式的报表(至少在不使用applet的情况下是这样),我们必须把报表导出为浏览器可以识别的格式。JasperReports允许我们把报表导出为PDF等多种格式,由于PDF是最流行的格式之一,我们在此处的示例中就选择它作为导出格式。

上例中的Servlet调用了静态方法ortToPdfStream(),其格式为:

runReportToPdfStream ( tream inputStream,

Stream outputStream,

parameters,

JRDataSource dataSource)

要想在浏览器中显示报表,我们需要在第一个参数中以流的形式传入二进制报表模板,也就是Jasper文件。我们可以通过调用ourceAsStream()方法达到这个目的,它需要传入一个包含Jasper文件位置信息的String作为参数。此方法返回一个tream实例,我们可以把它作为ortToPDFStream()方法的第一个参数。

ortToPDFStream()方法需要一个Stream()实例来对编译后的报表执行写操作。我们可以简单地使用Servlet的缺省的输出流,可以通过调用putStream()方法得到它。

ortToPDFStream()方法的另外两个参数是和JRDataSource,前者用于传递报表的任意参数,后者用于以Source形式传递数据。这个例子中,我们不需要传递任何参数和数据,所以使用一个空的HashMap和JREmptyDataSource。

山西老醯儿(FromSX)

·39·为了确保浏览器正确地显示报表,我们必须把内容类型设置为application/pdf,通过调用tentType()方法可以完成这件事。

最后的示例代码需要部署到一个Servlet容器中,我们可以通过ANT脚本来自动地完成这一过程。该脚本作为本书源代码的一部分,可以从/files/code/8082_下载得到。下面的屏幕截图显示了浏览器中的PDF格式报表:

JRXML报表模板的元素

在前面的袋子中,我们用JRXML报表模板的元素来生成了一个显示静态文本的报表,元素表示报表的主区域。当然,JRXML模板还可以包含许多其它元素,用来在报表中显示次级辅助数据或完成其它一些任务,如:导入Java包、控制数据在报表中如何显示等。

下面就来介绍一下根元素的全部子元素。除个别已特别指出的元素外,大部分的元素都可以在模板中使用多次。

山西老醯儿(FromSX)

·40·此元素用来给报表模板输入任意的信息。

加裁了报表的Java应用程序通过调用perty()方法可以载入这些属性。JRXML模板可以包含零个或多个元素。

此元素用于导入个别的Java类或完整的包。