JasperReports使用Report模型,典型的Report包括title, summary, detail, and page and group headers and footers。
给Report填上数据,首先要编译一下Report的XML定义。编译好的Report以.jasper作为扩展名,并且增加了一些信息,比如自定义的一些表达式等(由于表达式支持beanshell, groovy, java等,这里是否翻译成统一的结构?)。这些编译好的报表可以serialized然后存在硬盘上或者从网上传输。在填充数据的步骤,将重新使用这些编译好的报表。实际上,编译的内容只是一些表达式而已。
net.sf.jasperreports.view.JasperDesigner类就是察看报表模型的类,可以 load 报表定义JRXML或者其编译好的文件(如何?)。虽然他不具有复杂的 GUI 和操作,但是利用它可以使报表模型可视化。
在所有的例子中,共有两个 ANT task :viewDesign and viewDesignXML。第一个可以 load report template ,后缀名是*.jasper;第二个可以 load JRXML , load jrxml 更加有用,因为他是 xml 格式的,可以被编辑(编辑完成后通过 refresh 立即可以看到结果)。
使用net.sf.jasperreports.engine.util.JRSaver将 serializing objects变成文件或者流。从流或者文件中 load ,可以使用net.sf.jasperreports.
engine.util.JRLoader utility类,这个类提供多种 load 方法,可以从文件、 inputstream, url, classpath 资源获得 Report template 。这些方法如:loadObjectFromLocation(String location)。
有些时候需要手工加载 report template 以便使用代码进行修改,这时候,你就需要将JRXML文件变成net.sf.jasperreports.engine.design.JasperDesign类,这个类是没有编译前的报表模型。在net.sf.jasperreports.engine.design.JasperDesign 类中的 load() 方法将一个JRXML文件变成报表模型或者使用类net.sf.jasperreports.engine.xml . JRXmlLoader。使用 writeReport() 方法将 JasperDesign 类写回,或者使用net.sf.jasperreports.engine.xml.JRXmlWrite r 。
编译的动作就是将net.sf.jasperreports.engine.design.JasperDesign变为net.sf.jasperreports.engine.JasperReport。这两个类都继承自net.sf.jasperreports.engine.JRReport接口。
编译动作的执行者是net.sf.jasperreports.engine.design.JRCompiler接口,接口中定义了两个方法:
public JasperReport compileReport(JasperDesign design) throws JRException;
public JREvaluator loadEvaluator(JasperReport jasperReport) throws JRException;
基于Groovy的报表编译器是net.sf.jasperreports.compilers.JRGroovyCompiler;基于 BeanShell 没有打包在核心库中,可以从例子中找到。
/demo/samples/beanshell和/demo/samples/groovy
为了简化编译, Jasper 提供了net.sf.jasperreports.engine.JasperCompileManager,这个类有一些静态方法可以从文件、流或者内存中编译报表。
首先,net.sf.jasperreports.engine.design.JRDefaultCompiler从配置文件中读取net.sf.jasperreports.compiler.class的信息(通过修改这个配置,可以自己定义所需的编译器)。如果没有定义,则使用 DefaultCompiler , DefaultCompiler 首先试图在 classpath 中寻找找到 Eclipse 的JDT compiler,如果找到了,则使用net.sf.jasperreports.engine.design.JRJdtCompiler的实现进行编译,现有版本的 Jasper 随包打有 JDT ,在/lib/jdt-compiler.jar里面。如果 JDT 找不到,则开始尝试使用与JDK 1.3兼容的 Sun 的 Java Compiler ,这个 compiler 在tools.jar中。如果JDK 1.3的compiler也找不到,就开始尝试JDK 1.2兼容的compiler,如果这些都找不到,则使用 javac 进行编译。
使用net.sf.jasperreports.engine.JasperFillManager将报表模板加载数据。 这个类有多种方法可以加载数据,从硬盘上,从流中或者直接从内存中,输出的方式与输入的方式保持一致,也就是说,如果输入的是一个报表文件,则输出的也是一个文件,输入的是一个 inoutstream ,则输出的就是 outputstream 。等等。如果想要不同,则可以使用net.sf.jasperreports.engine.util.JRLoader自己 load ,然后自己转成别的。
JasperReports可以与任何的系统和数据集成,这依靠两个事情:报表参数(report parameters)和数据源( Report d ata source)。 报表参数通常被放在java.util.Map中,参数名就是 key ,参数值就是 value 。
假设有两种的情景:
1 、使用 net.sf.jasperreports.engine.JasperFillManager 接收net.sf.jasperreports.engine.JRDataSource作为数据源;
2 、还可以直接接收一个java.sql.Connection作为数据源,实际上,在直接使用 Connection 的时候, Jasper 自己创建net.sf.jasperreports.engine.JRDataSource;
JasperReports可以使用很多格式的数据作为数据源,因为JRDataSource接口非常简单,他只有两个方法:
1 、next():将指针移动到 tabular data 的下一行;
2 、getFieldValue():或者一行中的每一个列的值;
Jasper 自带很多种的 JRDataSource实现,如collections or arrays of JavaBeans, XML data, Swing table models, or JDBC result sets.
在例子中提供从 HSQLDB 中获取数据。另外,/demo/samples/datasource目录中的例子讲述了如何创建自定义的 data source 。也可以参考/demo/samples/xmldatasource,如果需要以XPath-based形式提供数据。
编译好的报表
编译好的报表就是以像素定位的文档。可以直接 view ,打印和变成其他的格式。编译好的报表就是net.sf.jasperreports.engine.JasperPrint类,是serializable的。也就是说,可以将编译好的报表保存、通过网络传输等。
在最顶层,JasperPrint类包含一些文档定义定西,如文档名称,页面设置,页面方向(横向或者竖向),然后就是一系列的 Page (net.sf.jasperreports.engine.JRPrintPage),每一个 Page 有一系列的 Element 组成,每一个 Element 在 Page 中的定位完全依靠 x,y 像素定位。并且其长宽也依靠像素定义,这些 Element 可能是带有风格定义的线、框、园、椭圆或者文字。
同步的报表数据填充
JasperReports提供net.sf.jasperreports.engine.fill.AsynchronousFillHandle类负责同步报表填充的工作。使用这个类的最大好处是在填充的过程中,用户可以取消操作(如操作持续了太长时间)。可以通过在 GUI 中调用以停止填充。
使用这个类的时候,填充在一个新的线程中进行,并时时通知调用者当前的进度,通知机制是通过net.sf.jasperreports.engine.fill.AsynchronousFillListener接口实现的。这个监听可以获得填充的结果信息,如成功、失败或者用户取消。AsynchronousFillHandle的功能包括:开始新的填充线程,注册监听,相应用户的取消操作。典型的应用为:
1 、创建:AsynchronousFillHandle.createHandle();参数包括 report, parameter 和 data source(connection) ;
2 、一个或者多个监听通过调用addListener()被注册,在 GUI 中,针对不同的监听结果(成功、失败或者用户取消)必须代表一些动作。
填充多列报表的方式:
1 、填充是通过startFill()方法进行的,在 GUI 中,这个方法是通过用户操作触发的。用户可以透过监听获得填充的进度信息。
2 、填充数据的时候,可以调用cancellFill()结束,同样,这个动作是在 GUI 中由用户触发的。
3 、在填充完毕,监听会得到消息,共有三种事件在监听中定义,他们是:
reportFinished(): 在成功结束填充的时候被调用,填充好的 Report 当作一个参数传进来,在 GUI 中,就可以引用这个参数进行如查看、保存等操作了;
reportFillError(): 当填充失败的时候被调用, Exception 被当作参数传递进来;
reportCancelled(): 用户主动取消的时候被调用;