报表工具iReport+JasperReport总结

报表工具iReport+JasperReport总结

1、 报表工具简介
1) iReport:可视化的报表设计工具
2) JasperReport:一个可以生成报表的Java第三方插件
3) 两者经常和Struts2整合使用
2、 iReport的使用
1) 安装
打开iReport-3.7.4-windows-installer.exe,按提示安装完成即可,注意iReport是需要JDK/JRE环境的,因此确保相关环境变量配置正确。
2) 第一个单查询报表
点“文件”——“New”,打开新建报表窗口。为了简便,这里选择一个coffee模板,点击“Launch Report Wizard”,下一步设定存储的文件名和路径,下一步选择数据库连接,并设计SQL语句;
如果还没有连接,则点击“New”新建一个JDBC连接,例如连接MySQL,则输入相关MySQL的连接信息;这里我们创建一张person表,有四个字段:id, name, age, weight。
选择连接后,点击“Design Query”,在新窗口中选择要查询的表和列,完成后点“OK”;
下一步将要设置报表的Field字段集,这里点击“>>”,将所有SQL查询字段添加至Field中。
下一步设定是否进行分组,这里暂不进行。
最后点击完成,即可完成报表的初步设计,呈现出图1所示的样式。

图1  第一个报表样式
直接点击“Preview”按钮,即可查看报表预览,同时打开Windows的PDF工具进行预览。但是,读者可能会发现,包含中文的字段却不能显示,或者显示成方框,这就是说明iReport还没有配置支持中文,下一节就来设置。
3) 中文乱码处理
要使iReport正确显示中文,则必须按如下步骤进行:
A、 工具——选项——classpath选项卡,右侧点击add jars, 将iTextAsian.jar包添加进来,如图2所示:

图2  Classpath选项卡
B、 点Fonts选项卡,在底部的复选框中,将iTextAsian项打上勾,如图3所示:

图3  Fonts选项卡
C、 点确定,并重启iReport
D、 选中需要设置中文的列字段 (在这里要使用Text Field组件,在图1中,就要选中”$F{person_name}”),在右侧属性框中设置如下四个属性:
Font Name = 宋体
Pdf font name = STSong-Light;
Pdf embedded = 【Checked】
Pdf encoding = UniGB-UCS2-H (Chinese Simplified)
再次预览后,不论是iReport还是PDF工具预览,都能正常显示中文。
4) 格式化输出
多数情况下,要对列字段的值进行格式化,比如限制小数位数,这里以图1为例,假设要对$F{person_weight}字段设置仅保留一位小数,则右击该字段,选择“Field Pattern”,在图4的弹出窗口中,设置Decimal Places为1即可。

图4  Field Pattern设置窗口
当然,其他属性同样可以设置。比如要将小数数字显示成为百分数形式,则点击左侧的“Percentage”项,进行设置即可。
5) 分组统计
实际的报告中经常会出现分组,也同时要进行分组统计,比如计算某一组某一个字段的和、平均值、最大最小值等等。这里以上述报告为例,按年龄进行分组之后计算每组的平均体重,那么需要按下述步骤进行:
A、 新建报表,在查询时选择分组,Group By字段选择“年龄”;
B、 在窗口左侧“report inspector“栏中找到”Variables“,右击选择”添加Variable“,然后在右侧属性栏中设置如下:
Name:avg_weight(变量名随意)
Variable Class::java.lang.Double
Calculation:Average
Reset Type:Group
Reset Group:person_age
Variable Expression:$F{person_weight}
C、 在报表的“person_age Group Footer 1“栏中添加一个Text Field组件,右键选择”Edit Expression“,按图5设置:

图5  选择Variables的窗口
点击“Apply“,预览后即可显示出每一组的平均体重。最终设计视图如图6所示:

图6  带分组统计的报表样式

6) 子报表
iReport对于一个PDF文件(主报表)只能有一个查询数据源,而多数情况下,我们需要在同一个PDF文件中显示多个数据源的数据,那么该如何实现呢?这就要用到子报表的功能。子报表就是在主报表中某一位置嵌入的一个报表,iReport提供了这个功能。
我们接着上述报表,在报表底部添加一个子报表。一般而言,子报表需要添加在主报表的Summary区段,图6中似乎看不到Summary区段,其实是存在的,不过是隐藏罢了,在左侧右击“Summary“,选择”Maximize Band Height“,发现Summary出来了,然后在其中添加一个”Subreport“组件,弹出一个新窗口对子报表进行设置。这里省略设置了,基本上和之前的创建报表差不多,其他选项也都使用默认设置就可以了,最终完成后将会创建一个新的子报表,可以直接对子报表进行Preview,当然调整Subreport组件在主报表中Summary的位置,然后预览主报表,看看,怎么样,两个数据源都显示出来了吧。最终设计图如下所示(此窗口布局是拖动的结果):

图7  带子报表的报表样式
图中上侧为子报表,下侧为主报表,在主报表的Summary区段有一个Subreport组件关联子报表。
7) 传递参数
报表中除了能显示数据库中的数据外,还能够显示从外界接收来的参数。在iReport中,可以右键“Parameters“,选择”添加Parameter“,然后再右侧进行设置相关属性:类型(Parameter Class)和默认表达式(Default Value Expression)以及运行时输入提示(Use as a prompt),等。设置完成后在报表某一位置添加一个Text Field,其Field Expression为”$P{parameter_name}”,然后点预览,则会提示输入参数,确认后则在Text Field中显示出刚才输入的信息。
通过传递参数,使得Java程序能够将数据传入报表文件来生成报表,在下一章节与Struts2的整合中将详细介绍。
8) 编译
在左侧“report inspector“栏中,右键报表名,选择”Compile Report“,观察底部控制台的输出结果,如果没有提示错误则编译成功。编译成功后将生成.jasper文件,它也存放在报表工作区目录,这个jasper文件就可以被jasperReport插件解析,实现报表的生成。下一张将介绍在Struts2中整合JasperReport的方法。
3、 JasperReport与Struts2的整合
1) 创建工程
用Eclipse创建Web工程,配置Struts2的环境,添加如下的JAR文件。很多JAR文件都能在Spring的发布包中找到。

在web.xml中配置Struts2过滤器,并创建struts.xml文件。这里省略。
2) Struts.xml文件的设置
由于是要生成报表,因此package的extends属性就不能是struts-default了,而应该改成jasperreports-default,result标签的type类型也不是dispatcher,而是jasper,同时要指定参数。代码示例如下:
<package name="report" namespace="/" extends="jasperreports-default">
<action name="actionName" class="actionClass">
<result type="jasper">
<param name="location">/template/my.jasper</param>
<param name="format">PDF</param>
<param name="dataSource">personList</param>
<param name="reportParameters">params</param>
<param name="contentDisposition">inline</param>
<param name="documentName">myreport</param>
</result>
</action>
</package>

代码说明:<param>用于为报表生成传递参数:
 location: 指定jasper文件的路径,且只能写一个路径;
 format: 指定生成的报表格式,有PDF、HTML、XML等;
 dataSource: 指定主报表中数据源的Collection集合,要求Action中必须包含getXXX方法,如public List<Person> getPersonList()方法,同时注意报表中的列字段名必须和Person类的属性名完全一致;
 reportParameters: 传递给报表本身的参数。这个参数名params必须为一个Map类型,并在Action中创建getParams()方法。它的键名应该与报表中$P{}中的名字完全一致,值类型也应该与$P{}的类型一致,这样能保证传递参数正确。由于是Map类型,所以可传递多个参数为报表中的参数赋值;
 contentDisposition: 报表生成方式,有inline和attachment两个值。inline表示使用浏览器在线预览,attachment表示弹出下载窗口提示下载。
 documentName: 如果是下载方式,则为默认下载的文件名,不用带.pdf后缀。
3) iReport的路径问题
为了能够实现功能强大的报表,这里我们在主报表中嵌入子报表,同时主报表中包含图片,一起来进一步完善我们的报表。
iReport的一个很棘手的问题就是它使用的路径都是绝对路径(如图片路径和子报表路径),这将导致我们若将编译好的jasper拷贝至Struts中运行时,它仍然指向的是最初编译所在的路径(即iReport的工作目录)而会发生资源找不到的错误。为了能够可移植jasper文件,我们将在报表中添加一个参数如$P{BasePath}表示根路径,在报表中出现绝对路径的地方都将根路径用$P{BasePath}替代。待Struts程序生成报表之前,为jasper文件传递当前路径给这个参数BasePath,这样报表中就能得到当前的绝对路径了,进而就能加载图片和子报表了。
现在就来创建这个参数。按照2.7节的步骤创建一个名为SUBREPORT_DIR的Parameter,这个参数是创建子报表后自动产生的,为了能够保证编译成功,在default Value Expression中输入iReport的工作目录,同时将User as a prompt选项勾上,这样运行时可修改参数值,然后切换到XML视图查看jrxml文件的源代码。参数定义的代码如下:
<parameter name="SUBREPORT_DIR" class="java.lang.String">
<defaultValueExpression><![CDATA["H:\\iReport\\"]]>
</defaultValueExpression>
</parameter>

然后找到图片定义和子报表定义的代码,都改成带参数的路径,如图片部分的代码如下。(子报表的修改下一节介绍)
<image>
<reportElement x="36" y="12" width="72" height="50"/>
<imageExpression class="java.lang.String">
<![CDATA[$P{SUBREPORT_DIR} + "coffee.jpg"]]>
</imageExpression>
</image>
报表文件在编译时自动将图片文件和子报表全部生成出来,因此在项目中,要拷贝主报表jasper、子报表jasper和图片文件。
4) 对子报表进行修改
一般而言,整合Struts后,子报表的数据源也是从程序中获得的,和主报表一样。而在报表设计中,我们通常是将子报表和主报表使用同一个JDBC连接并各自设置查询,整合到程序中这种方法就不合适了。这里我们也将一个Collection/List集合传给子报表作为数据源,由于struts.xml文件中的dataSource数据源只能有一个,所以就必须按照如下方法为子报表传递数据:
选中子报表,在右侧属性栏中Subreport Expression属性设置为带参数的路径;Expression Class为java.lang.String;Connection Type属性为Use a datasource expression;DataSource Expression属性为:
new net.sf.jasperreports.engine.data. JRBeanCollectionDataSource($P{subList})
/* 上述代码的大致意思为运行时从JavaBean或Action中调用get方法获得Collection类型的数据源,从而便于与Struts2的整合 */
接着按照2.3节的步骤将struts2-jasperreport-plugin-x.x.jar文件添加到iReport的Classpath中,并且创建一个参数subList,其类型为java.util.Collection。这样子报表的修改工作就完成了,查看xml代码如下:
<subreport isUsingCache="true" runToBottom="false">
<reportElement x="0" y="0" width="555" height="41"/>
<dataSourceExpression><![CDATA[new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($P{productList})]]></dataSourceExpression>
<subreportExpression class="java.lang.String"><![CDATA[$P{SUBREPORT_DIR}+ "subreport.jasper"]]></subreportExpression>
</subreport>

5) 编写Action
进行完上述几步较麻烦的设计工作,我们终于可以编写java程序了。现在的主要工作就是为报表传递参数了,这些数据源将从数据库中获得,读者可以使用任意一种数据访问方式:JDBC、Hibernate、iBatis等,这里省略实现,只要最终是Collection类型及其子类型List即可。
在Action中必须要为主报表和子报表的Collection对象创建get方法,并且为Map类型的参数params创建get方法。然后读者可仿照3.2节struts.xml的配置样例进行设置。最终测试程序是否能够运行,报表是否能够生成。

笔者信息:
QQ:932215832
Email:[email protected]

你可能感兴趣的:(mysql,xml,ibatis,struts,嵌入式)