工具:IReport3.0.0 , jdk7
教程:
1. 使用IReport制作模板:
a.新建文档,此时生成的是jrxml格式,其实这个就相当于java中的源码一样,而我们最终使用的是编译后的.jasper文件。注意红框内可直接先设置好要打印的报表大小,如果后期需要修改纸张打下,可以“编辑”->”报表属性”
b. 此时可以看到文档分为几个板块,作用分别如下:
title:只在整个报表的第一页的最上面部分显示,除了第一页外,不管报表有几个页面,其余的页面都不会再出现该部分的内容。
pageHeader:将会在整个报表中的每一个页面中都会出现,显示在位置在页面的上部,如果是报表的第一页,pageHeader 中的内容将显示在title段下面,除了第一页以外的其他所有页面中pageHeader 中的内容将在显示在页面的最上端。
- columnHeader:针对detail段的表头段,一般情况下在这个段中画报表中列的列标题。每页均会出现一次。从字面意思就可以理解这是一个表格的表格头。
- detail:报表内容段,在这个段中设计报表中需要重复出现的内容,detail 段中的内容每页都会出现。
- columnFooter:detail段的结尾,每页只会出现一次。
- pageFooter:显示在所在页面的最下端,每页都显示,最后一页由lastPageFooter替代。
- lastPageFooter:最后一页页尾段内容,只在最后一页出现一次。
- summary:表格的合计段,出现在整个报表的最后一页中的detail段的后面,一般用来统计报表中某个或某几个字段的合计值。
c.下面先来设置下数据源
Data->”连接/资料来源”
可以看到支持多种数据源,本人还是比较喜欢javaBean这种的。
点击next,键入name。之后可以test
关闭后options—>classpath,”添加文件夹”,选择myeclipse中class的文件夹所在位置。
这个路径是为了下一步找到javaBean而设置的。
之后,Data->”报表查询”,“JavaBean Data Source”,下边的className输入javaBean所在的位置(刚刚设置的classPath之后的路径部分即可),点击”Read attributes”,可读取javaBean中的属性,注意javaBean的属性只支持基本数据类型(或者其包装类)和List。
之后就可以看到左边Fields就有了javaBean中的属性了。数据源设置成功!
d. 模板制作
界面顶部的工具栏足可使用,我的习惯是多用title、detail和summary板块,当需要属性的时候从 左边栏的Fields中直接拖过来就可以了,但是要注意,字段的框的大小决定显示文字的多少,如果字段内容比较多,最好框设的大些。下边是以前项目的一个模板,上中下分别在title、detail和summary中:
注意:如果打印的是pdf格式,那些字段应该设置字体属性,不然打印的时候不显示,右键“属性”,这些文本类型为Font->PDF Font Name->STSong-Light,PDF Encoding->UniGB-UCS2-H (Chinese Simplified)。如果属性值为null而又不想让其在纸张上显示“null”,则勾选“Text Field”->”Blank when null”即可。
如果出现了net.sf.jasperreports.engine.JRRuntimeException:Could not load the following font的exception,则是因为缺少iTextAsian.jar,如果引入了还是会出现这种情况,看下是不是版本不对,因为这个jar包是一个亚洲语言包。
e.保存编译预览
编译 第一个按钮,之后第二个为预览按钮,预览有多种预览方式,但是要先设置预览时启动的软件,options->’选项’->’External Programs’
之后在“建立”中有各种预览选项。jrxml文件编译完后就可以点击预览按钮预览了。
f.子报表的设计
点击子报表按钮画出子报表的框,一般放在detail中,此时出现灰色区域,双击这个灰色区域,就出现子报表的设置
subreport选项卡中需要设置”connection/data source expression”为”user data source expression”(此处根据个人需要设置),下边需要new一个JRBeanCollectionDataSource对象,这个地方作用是将数据源传递给子报表。
new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource(
Fgoods),括号中的
F{goods}是Fields中的List。
subreport(other)选项卡应设置子报表路径,”subreport expression”内容为“
PSUBREPORTDIR+"customerGood.jasper",其中
P{SUBREPORT_DIR}是一个parameter,是下一步要新增的,”customerGood.jasper”是子报表编译后的文件。目的为指定子报表的位置。
新增subreport_dir,此时新增的这个dir是预览的时候可以用,也可以在程序中当作参数传进来,在程序中设定这个dir。
之后就可以作子报表的模板了,步骤是一样的,而子报表的data source是母报表传进来数据源的类型,比如foods是List,那么子报表的data source就导入GoodBean就ok了。
如果需要子报表往母报表中返回数据怎么办呢?
比如我们需要返回一个sum,那么可以新增一个variable,设置如下:
calculation Type 中有很多计算方法,如求平均值,求和,求最低、最高等。
variable expression的值为要求和的字段。
在母报表中,sum就是一个variable了,如图:
如果我们想有一个列为自增的序列怎么做呢?
比如我们想有一个”序号”列,可以像设置sum一样新增variable,但是计算方式设置为count,variable expression为new Integer(“1”)(像java一样,其实本质就是java)
注意:子报表的纸张上下左右边界决定了两条数据之间的距离,如上下边界越大,那么母报表中的两条数据离得就越远。
报表制作完毕。
2.java代码
javaBean:
public class PrintCustomerOrderBean {
private String orderNumber ; //订单编号
private String creatTime ; //下单时间
private String receiveName ; //收货人姓名
private String phone ; //联系电话
private String sendMethod ; //送货方式
private String address ; //收获地址
private List<CustomerGoodBean> goods ; //商品信息,此处为传递给子报表的数据源
private String payMethod ; //结款方式
private String wuliuFee ; //物流费
private String pagMoney ; //实付金额
private String ps ; //备注
private String cardMoney ; //优惠券金额
//getter和setter此处省略
}
打印方法(struts2):
//打印客户订单
public String printCustomerOrder() throws Exception{
List<PrintCustomerOrderBean> listBean = new ArrayList<PrintCustomerOrderBean>() ; //这个list是最后塞入的数据,必须为List类型
log.info("***************打印客户订单***************");
//组装订单的商品信息
List<CustomerGoodBean> listGoods = new ArrayList<CustomerGoodBean>() ;
List<OrderGood> listGood = orderGoodService.listAll(id) ;
/*for(int i=0;i<20;i++){ //测试超过一页纸时使用
CustomerGoodBean customerGoodBean = new CustomerGoodBean("测试"+i, //商品名称
"2",//商品数量
"1.2",//售价
10.0) ; //小计
listGoods.add(customerGoodBean);
}
此处可以写自己的业务逻辑!!!
*/
listBean.add(printCustomerOrderBean) ;
String rootpath = ServletActionContext.getRequest().getRealPath("/");
String realPath = rootpath + "jasper/customerOrder.jasper" ;
//得到jasper文件
File reportFile = new File(realPath);
Map<String, String> parameters = new HashMap<String, String>();
parameters.put("SUBREPORT_DIR", rootpath + "jasper/"); //这里将路径当作参数传入
//把搞好的模板load一下
JasperReport jasperReport = (JasperReport) JRLoader.loadObject(reportFile) ;
//把bean转成jasper的数据源用来下边塞给报表
JRDataSource dataSource = new JRBeanCollectionDataSource(listBean) ;
//因模版上没有传入参数,所以此处第二个参数为空 现在已经把数据塞进去了
JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, dataSource);
//整成pdf格式的
JRAbstractExporter exporter = new JRPdfExporter() ;
exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
ServletOutputStream out = response.getOutputStream();
exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, out);
//导出
exporter.exportReport();
log.info("*******************打印完毕*************************");
return null ;
}
也许会出现的问题:请参考链接,侵删http://topmanopensource.iteye.com/blog/1851336
作者只是了解点皮毛,如果有错误的地方请各位指正,谢谢!