Jasper学习笔记-第一章至第三章
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.JRLoaderutility类,这个类提供多种load方法,可以从文件、inputstream, url, classpath资源获得Report template。这些方法如:loadObjectFromLocation(Stringlocation)。
?
有些时候需要手工加载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.JRXmlWriter。
?
编译的动作就是将net.sf.jasperreports.engine.design.JasperDesign变为net.sf.jasperreports.engine.JasperReport。这两个类都继承自net.sf.jasperreports.engine.JRReport接口。
?
编译动作的执行者是net.sf.jasperreports.engine.design.JRCompiler接口,接口中定义了两个方法:
public JasperReportcompileReport(JasperDesign design) throws JRException;
public JREvaluatorloadEvaluator(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的JDTcompiler,如果找到了,则使用net.sf.jasperreports.engine.design.JRJdtCompiler的实现进行编译,现有版本的Jasper随包打有JDT,在/lib/jdt-compiler.jar里面。如果JDT找不到,则开始尝试使用与JDK 1.3兼容的Sun的Java Compiler,这个compiler在tools.jar中。如果JDK1.3的compiler也找不到,就开始尝试JDK 1.2兼容的compiler,如果这些都找不到,则使用javac进行编译。
?
使用net.sf.jasperreports.engine.JasperFillManager将报表模板加载数据。这个类有多种方法可以加载数据,从硬盘上,从流中或者直接从内存中,输出的方式与输入的方式保持一致,也就是说,如果输入的是一个报表文件,则输出的也是一个文件,输入的是一个inoutstream,则输出的就是outputstream。等等。如果想要不同,则可以使用net.sf.jasperreports.engine.util.JRLoader自己load,然后自己转成别的。
?
JasperReports可以与任何的系统和数据集成,这依靠两个事情:报表参数(reportparameters)和数据源(Report data 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(): 用户主动取消的时候被调用;
