20.1MB
1.32MB
JasperReport是一个免费的开源报告生成工具。我们可以通过这个软件制作各种复杂的报表。而且中文版的JasperReport还可以将准备好的报表文件转换成PDF、HTML或者XML格式。该软件是JAVA设计人员经常使用的重要工具之一。
JasperReport是一个强大而灵活的报表生成工具,可以显示丰富的页面内容,并将其转换为PDF、HTML或XML格式。该库完全用Java编写,可用于在各种Java应用程序中生成动态内容,包括J2EE和Web应用程序。
Jasperreport是开源的,给我们带来了很大的便利,但是文档收费,这是可以理解的。
它还有一个相关的开源项目IReport。
IReport是一个图形化的辅助工具,可以弥补JasperReport的缺陷:JasperReport只提供可用的类库,没有提供更好的开发工具。它们一起使用将在更大程度上提高效率。
JasperReport通过XML文档中定义的报表设计来组织数据。
这些数据可能来自不同的数据源,包括关系数据库、集合和java对象数组。
通过实现简单的接口,用户可以将报表库插入到定制的数据源中。
JasperReports的报表模板可以用iReport之类的工具制作。只要报告以XML格式存储,就可以被JasperReport读取,然后编译成一个. jasper文件。
JasperReports是世界上最流行的开源报告引擎。它完全是用Java编写的。它可以使用任何类型数据源的数据,并生成像素级文档,可以以各种文档格式查看、打印或导出,包括HTML、PDF、excel、Openoffice和doc。
步骤1: XML解析
JasperReport使用SAX2.0 API解析XML文件。然而,这不是必须的,用户可以决定使用哪个XML解析器。
JasperReport使用org . XML . sax . helpers . XML reader factory类的createXMLReader()来获取解析器实例。在这种情况下,有必要在运行时将Java系统属性org.xml.sax.driver(该属性的键)的值设置为sax驱动程序类的完全限定名,如SAX2.0文档中所述。用户可以通过两种方式做到这一点,我将在后面一一解释。如果想使用不同的SAX2.0XML解析器,需要指定相应解析器类的名称。
设置系统属性的第一种方法是在启动java虚拟机时在命令行上使用-D开关:Java?dorg . XML . sax . driver = org . Apache . serces . parsers . sax parser mySAXApp sample . XML
在JasperReport提供的所有例子中,ANT构建工具被用来执行不同的任务。我们通过使用内置任务中的元素来提供此系统属性:
设置系统属性的第二种方法是使用java.lang.system.setProperty(字符串键,字符串值)
system . set property(" org . XML . sax . driver "," org . Apache . Xerces . parsers . sax parser ");
Jsp/compile.jsp和we b-INF/class/servlet/compile servlet . Java文件提供了这样的示例。
注意:对于第二种方法,我想说点题外话。有关于JVM的系统属性(我们可以通过system . out . println(system . getproperty(" property key "))来查看),也可以像上面提到的在运行时使用system . set property(" property key "," property value ");来设置它。但是,一旦JVM启动,它的内置系统属性(如user.dir)就不能更改了。奇怪的是,我们仍然可以用System.setProperty()方法设置它,但是当我们用system . out . println(system . getproperty())方法检查它时,发现它的值已经被更改为我们设置的值,而实际上我们设置的值是不会有任何影响的。所以对于内置属性,我们只能通过-D开关在JVM执行之前设置它们。对于org.xml.sax.driver来说,它不是系统的内置属性,所以在JVM启动后仍然可以设置。更多详情请参考威尔逊《Java中的深度冒险》。
步骤2:编译报告设计。
要生成报表,用户需要首先生成报表的设计,要么直接编辑XML文件,要么通过程序生成net . SF . jasper . engine . design . jasper design对象。在本文中,我将主要使用编辑XML文件的方法,因为这种方法是目前使用JasperReport类库的最佳方式,我们有机会更好地了解类库的行为。
如前所述,XML报告设计是JasperReport用来生成报告的原始材料。这是因为XML中的内容需要被编译并加载到JasperDesign对象中,这些对象将在报表引擎填充数据之前被编译。
注:大部分时候,报告的编写被归类为开发期的工作。您需要编译应用程序报告设计,就像编译Java源文件一样。在部署时,您必须在要部署的平台上安装已编译的报告和应用程序。这是因为在大多数情况下,报表设计是静态的,很少用于向用户提供在运行时编译的动态生成的报表。
报告编译过程的主要目的是生成和加载包含所有报告表达式的类的字节码。这个动态生成的类将在加载数据和评估所有报表表达式时使用。例如,如果您使用IReport生成一个名为SimpleSheetTest的报表,它的XML设计文件名为SimpleSheetTest.jrxml,并且在同一个目录下,IReport将自动生成一个名为SimpleSheetTest.jrxml的文件,该文件主要包含一些报表元素,如字段、参数和变量的定义,以及一些求值表达式。当然,如上所述,当您直接使用JasperReport API时,这个文件是不可见的,因为它是在运行时生成的类。查看它的方法是在IDE(JBuilder,Eclipse)中单步调试程序。在报表打印阶段,你将能够跟踪这个类,它的名字是"你的报表名"。java”。根据上面的例子,它是SimpleSheetTest.java,这与IReport是一致的。当然,您也可以在生成该类的临时目录中找到它,如下所述。
在这个类生成过程之前,JasperReport引擎需要验证报表设计的一致性,即使存在验证检查失败的情况,也不会继续运行后面的工作。在接下来的小节中,我将展示报表设计被成功验证后的情况。
对于包含所有报表表达式的这个类的字节码,我们至少需要注意三个方面:
临时工作目录(临时工作目录)
Java编译器的使用:
类路径:
为了编译Java源文件,必须创建这个文件并保存到磁盘上。Java编译过程的输出是一个. class文件。这个包含所有报表表达式的类是在这个工作目录下创建和编译的,这也是JasperReport需要访问这个临时目录的原因。当报表的编译过程结束后,这些临时类文件会被自动删除,生成的字节码会保存在net . SF . jasper . engine . jasper report对象中。如果需要,这个类可以序列化自己并保存到磁盘。IReport就是这么做的。
默认情况下,这个临时工作目录是JVM启动时的当前目录,但是它取决于JVM的系统属性user.dir。通过更改系统属性jasper.report.compile.temp,用户可以轻松地更改这个工作目录。在Web环境中,尤其是当您不希望包含用于启动Web服务器的批处理文件的目录与用于报告编译过程的临时工作目录混合在一起时,您可以修改该属性。
上面提到的第二个方面涉及到用来编译报表表达式类的Java编译器。首先,报告引擎将尝试使用sun.tools.javac.Main类来编译Java源文件。这个类包含在tools.jar中当且仅当这个jar文件在JDK安装目录的bin/目录中或者在类路径中,sun.tools.javac.Main才能正常使用。
如果JasperReport未能成功加载sun.tools.javac.Main文件,程序会动态执行java编译过程,就像我们平时使用命令行一样,使用JDK安装目录的bin/目录下的javac.exe。这就是为什么把JDK安装目录/lib/下的tools.jar文件复制到JasperReport项目的lib/目录下是一个可选的操作。如果tools.jar不在类路径中,JasperReport将显示一条错误消息,并继续上述操作。
编译Java源文件时,最重要的是类路径。如果Java编译器在指定的类路径中找不到它试图编译的所有相关类的源文件,整个过程将失败并停止,错误消息将显示在控制台上。当JasperReport试图编译报表表达式类时,也会发生同样的事情。因此,在运行时为编译过程提供正确的类路径非常重要。例如,我们需要确保在类路径中,我们提供了可以在报告表达式中使用的自定义类。
这方面也有默认的行为。如果没有为编译报告类指定类路径,引擎将使用系统属性java.class.path的值来确定当前的JVM类路径。如果指定系统属性jasper.reports.pile.class.path的值,则可以用定义的类路径覆盖默认行为。
在大多数情况下,编译报告只需要简单地调用jaspercompiler。在JasperReport类库中编译报表(myXML文件名);去做吧。之后,编译后的报告设计将被生成并存储在。jasper文件,该文件将保存在与提供的XML报告设计文件相同的目录中。
第3步:报表设计预览
JasperReport类库没有提供高级GUI工具来辅助设计工作。但是JasperReport本身提供了一个非常有用的可视化组件,帮助报表设计者在编译时预览报表设计(其实不如直接使用IReport方便)。
net . SF . jasper . view . jasper designer是一个基于Swing的Java应用程序,可以加载和显示XML或编译后的报表设计。尽管它不是一个复杂的GUI应用程序,并且缺少诸如拖放可视报告元素之类的高级功能,但它仍然是一个有用的工具。JasperReport项目提供的所有示例都使用了这个crystalreportviewer。
如果你已经安装了ANT(不要告诉我你不知道ANT是什么),想要查看一个简单的报表设计(JasperReport项目带来的例子),只需要在相应的文件夹中输入以下命令即可:
> > ant视图设计XML或> > ant视图设计
如果没有安装ANT的话,要达到上述效果并不容易,因为JasperReport本身还需要一些其他的辅助jar包(在JasperReport的安装目录/lib下)。运行时需要将这些jar包全部包含在你的类路径中,并适当设计系统属性,比如上面提到的org.xml.sax.driver我可以给你看一个windows下的例子:
> java -classpath。/;../../../lib/commons-digester . jar;
../../../lib/commons-bean utils . jar;../../../lib/commons-collections . jar;
../../../lib/Xerces . jar;../../../lib/jasperreports.jar
-dorg . XML . sax . driver = org . Apache . Xerces . parsers . sax parser
dori . jasper . view . jasper design viewer-XML-first jasper . XML
麻烦吗?让我们赶快抓一只蚂蚁。下面是预览后的结果(其实用IReport更好)
第四步:填写报告。
报表填充过程是JasperReport库最重要的功能。它体现了这个软件的主要目标,因为这个过程可以自由地操作数据集,从而可以产生高质量的文档。在填充过程中,有三种材料需要提供给JasperReport作为输入:
报表设计(报表模板)
参数)l
数据源(数据来源)
这一过程的输出通常是最终将被查看、打印或导出为其他格式的单个文档。
为此,我们需要采用net . SF . jasper . engine . jasperfillmanager类。这个类为我们提供了一些加载报表设计的方法。报告设计的源可以是本地磁盘、输入流或内存中已经存在的net . SF . jasper . engine . jasper report类。输出对应输入类型,即如果JasperFillManager接收到一个报表设计的文件名,加载后生成的报表将是磁盘上的一个文件;如果JasperFillManager接收到一个输入流,那么生成的报告将被写入一个输出流。
有时候,JasperFillManager提供的方法不能满足某些特定应用的要求。例如,有人可能希望将他的报告设计用作类路径中的资源,输出报告将作为文件存储在指定的磁盘目录中。在这种情况下,开发人员需要考虑在将报表设计传递给报表加载流程之前,使用net . SF . jasper . engine . util . Jr loader类来加载报表设计对象。这样,他们可以像报表名称一样获得报表设计属性,以便开发人员可以构造结果文档的名称,并将其存储在所需的位置。
现实中报表填报的场景很多,填报管理器只是尽量覆盖最常用的部分。但是对于想要自己定制填充过程的人来说,任何一个开发者只要采用上述方法都可以达到满意的效果。
报表参数通常作为java.util.Map的值提供给加载管理器,参数名是它的键值。
作为灌装过程中需要的第三资源?数据来源,有如下两种情况:
一般情况下,引擎需要处理net . SF . jasper . engine . Jr data source接口的一个实例,通过该实例,引擎可以在加载过程中获取所需的数据。JasperFillManager提供的方法支持所有的JRDataSource对象(这是一个接口,它的通用实现在前一章已经提到了)。
但是,这个管理器还提供了一些方法集,这些方法集接受java.sql.Connection对象作为参数来替换所需的数据源对象。这是因为在许多情况下,生成报告所需的数据来自关系数据库中的一个表。
在报表中,用户可以提供SQL查询语句来从数据库中检索报表数据。在执行时,引擎需要做的唯一事情是获取JDBCconnection对象,并使用它连接到它想要连接的数据库,执行SQL查询并检索报告数据。在后台,引擎将使用一个特殊的JRDataSource对象,但它对调用它的程序是透明的。
JasperReport项目提供了相关的例子,使用了HSQL数据库服务器(在项目文件中,有对应的文件夹)。要运行这些示例,首先需要通过在/demo/hsqldb目录中输入以下命令来启动服务器:> ant或> ant runServer。
如果不安装ANT,那就麻烦了:> java -classpath。/;../../lib/hsqldb . jar org . hsqldb . server
以下代码片段显示了查询示例如何加载数据:
http://准备参数
map parameters = new HashMap();
parameters.put("ReportTitle "," Address Report ");
parameters.put("FilterClause ","波士顿","芝加哥","奥斯陆' ");
parameters.put("OrderClause "," City ");
http://调用填充过程
jasperfillmanager . fillreporttofile(文件名,参数,getConnection());
第5步:查看报告。
报表填充阶段的输出通常是一个JasperPrint对象,如果保存在磁盘上,通常以. jrprint文件的形式存在。JasperReport有一个内置的查看器,可以查看内置XML导出器获得的XML格式的报告文件。这个查看器就是前面提到的net.sf.jasper.niew.JRViewer?一个基于Swing的应用程序组件,用户可以通过继承这个类定制自己需要的查看器。在JasperReport项目附带的示例webapp中,您可以阅读JRViewerPlus类的代码以获得更多内容。
注意:JasperViewer更像是一个演示程序,教人如何使用JRViewer组件。这里需要注意的是,当你调用JasperViewer的viewReport()方法来显示报表时,如果关闭预览框,整个应用程序也随之结束,因为这个函数最后调用system . exit(0);您可以通过继承该类并在查看器中重新注册java.awt.event.WindowListener来避免这种情况。
第六步:打印报告。
JasperReport类库的主要目标是生成可打印的文档。此外,大多数应用程序生成的报告需要在纸上实现(或打印)。我们可以使用net . SF . jasper . engine . jasper print manager来打印JasperReport生成的文档。当然,报告也可以导出为PDF、HTML等其他格式后打印。使用JasperPrintManager提供的方法,我们可以打印整个文档、单个文档或某个范围的文档,可以有也可以没有打印对话框。下面的示例演示了如何在不显示对话框的情况下打印整个文档:jasperprintmanager . print report(my report,false);
这个例子演示了如何打印一个5-11页的文档,同时显示打印对话框:net . SF . jasper . engine . jasperprintmanager . printpages(my report,4,10,true);
第7步:导出报告。
在某些应用程序环境中,将JasperReport生成的文档从其独特的格式导出到其他更流行的格式(如PDF和HTML)非常有用。这样,其他人就可以在不安装JasperReport的情况下查看这些报告,尤其是当这些文档要通过网络发送出去的时候。
JasperReport提供了JasperExportManager类来支持这个函数。该特性将在未来继续增加对新格式的支持。而下面是导出的代码片段:jasperexportmanager . export report HTML文件(我的报表);
注意:希望将其报表导出为其他格式的用户需要实现JRExporter的接口或者继承相应的JRAbstractExporter类。
步骤8:加载并保存对象。
当使用JasperReport时,您经常要处理序列化的对象,比如编译的报表设计或者生成的报表。有时,您需要手动加载从不同来源(如输入流)生成的序列化类,或者使用lib的类库核心功能。JasperReport提供了两个特殊的工具类来提供上述操作的能力。这些类通常由报告引擎本身使用:
net . SF . jasper . engine . util . Jr loader
net . SF . jasper . engine . util . Jr saver
第一个类提供了一些从不同类型的数据源(如文件、URL、输入流和类路径)获取序列化对象的方法。最有趣的方法是loadObjectFormLocation(String)。上一章已经介绍过了,这里就不赘述了。
上面的对象加载工具相对的部分是JRSaver类,可以帮助程序员序列化自己的类并存储在本地磁盘上或者通过Output Stream发送到网络上。
有时,开发人员可能希望加载生成的报表,或者已经导出为XML格式的最终JasperReport文档,这与上面提到的直接加载序列化对象不同。这时候我们需要加载的是编译加载的XML内容,生成JasperPrint对象,而不仅仅是加载序列化的对象。这时,我们可以通过net . SF . jasper . engine . XML . jrprintxmlloader类的一些静态方法,编译从XML文件中读取的内容,在内存中构建一个document对象。