不确定分组表头级数的分组报表实现
需求描述:
本例为给友邦保险制作的demo表样,客户具体需求如下:
以网格式报表列举明细,在此基础上可动态选择分组汇总字段,根据用户指定的分组汇总字段,形成不确定分组级数的分组报表,并自动生成分组小计。
如网格式报表结果如下:
在此基础上可对性别Gender(性别),CompanyID(公司),DepartmentID(部门),Grade(级别)等多个指标进行分组汇总,且分组的顺序不一定。比如选择先按照CompanyID,再按照Gender分组得到结果:
实现思路:
1. 确定可能含有的所有分组指标字段数,也就是最多含有的分组级数。利用参数和宏实现包含最大分组级数的报表。
2. 在参数表单中选择分组指标及分组级数,报表展现页面获取参数值,利用API修改报表模板,并用标签展现修改后的报表模板。
具体实现:
1. 报表设计:
假设共含有分组指标字段3个,也就是最多有3级分组表头。设计报表如下:
参数和宏:
参数:group1,group2,group3分别代表由参数模板传递过来的一级分组字段,二级分组字段,三级分组字段。
宏:动态宏,macro1,macro2,macro3是根据参数group1,group2,group3动态生成的宏值。
报表模板设计如下:
其中表头部分的A1,B1,C1分别为分组字段group3,group2,group1。分组单元格A2,B2,C2表达式分别为=ds1.Group(${macro3},false),=ds1.Group(${macro2},false),=ds1.Group(${macro1},false),表示的是分组字段进行分组。分组下方的红,黄,蓝色区域分别是每一层分组的分组统计项。
2. 报表展现页面:
部分代码:
<%
StringBuffer param=new StringBuffer();
String reportFile = “F:\\reportHome\\webapps\\demo\\reportFiles\\友邦保险\\4.raq”;
//获取ReportDefine对象,并对模板进行修改
ReportDefine rd = (ReportDefine)ReportUtils.read( reportFile );
String reportParamsId = request.getParameter(“reportParamsId”); //取得参数缓存的标识号
String group1 = “”;
String group2 = “”;
String group3 = “”;
if(reportParamsId!=null){
Hashtable params = null;
if(!”".equals(reportParamsId) && reportParamsId != null){
params = com.runqian.report4.view.ParamsPool.get( reportParamsId );
}
//分别获取3个分组字段的值
if(params.get(“group1″)!=null){group1 = (String) params.get(“group1″);}
if(params.get(“group2″)!=null){group2 = (String) params.get(“group2″);}
if(params.get(“group3″)!=null){group3 = (String) params.get(“group3″);}
}
//根据接收到的分组字段,删除分组列,若一级分组为空删除第三列,二级分组为空删除第二列,三级分组字段为空删除第一列。注意若一级分组为空,二三级必定为空,故前三列都删除。
if(group1.equals(“”)){rd.removeCol((short)3);}
if(group2.equals(“”)){rd.removeCol((short)2);}
if(group3.equals(“”)){rd.removeCol((short)1);}
//根据接受到的分组字段,删除下放统计项。若三级分组为空删除第5行,二级分组为空删除第四行,一级分组为空删除第三行。注意若一级分组为空,二三级必定为空,故4,5,6行都删除。
if(group3.equals(“”)){rd.removeRow(5);}
if(group2.equals(“”)){rd.removeRow(4);}
if(group1.equals(“”)){rd.removeRow(3);}
//保存为临时raq文件
try {
ReportUtils.write(“F:\\reportHome\\webapps\\demo\\reportFiles\\友邦保险\\4_temp.raq”,rd);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
%>
<table align=”center” width=”100%”>
<tr><td>
<report:html name=”report1″ reportFileName=” 4_temp.raq”
funcBarLocation=”top”
needPageMark=”yes”
generateParamForm=”no”
params=”<%=param.toString()%>”
needSaveAsExcel=”yes”
width=”-1″
/>
</td></tr>
</table>
实现效果:
分组设置参数设置页面:
若分别选择三级分组如下:
得到结果:
若选择分组如下:
得到结果:
若不选择任何分组,直接点击查询,只会生成网格式列表结果。