一:折叠报表两种实现方案
折叠报表在BS项目有着广泛的应用,在公司内部,报表工具在解决折叠报表时通常有两种方案:
1) 利用报表 工具的隐藏行属性,通过传递参数刷新报表实现。
2) 通过jQuery的show(),hide()方法对报表进行tr的显示,隐藏操作。
二:两种折叠方案的对比
第一种折叠方案:
优点:js方法比较简单。
缺点:无法进行填报,每次折叠打开的操作都是对报表的刷新重运算,效率比较低。适合小数据量的展示报表。
第二种折叠方案:
优点:利用jQuery的方法对报表对象初始化以及tr的显示和隐藏,折叠打开的操作不需要刷新计算,故可填报,性能比较高。
缺点:需要学习jQuery,对js的要求比较高,第一次展示是对报表的运算以及初始化,故数据量太大第一次加载也会比较慢。
近期在给客户解决问题时,经常会遇到折叠报表的性能问题,还有的客户希望报表即可填报又可折叠。发现大家普遍还在使用第一种折叠报表的方案,故请教了郑谷川,希望通过文章,推广jQuery实现折叠报表的方案。
三:JQuery 实现润乾的折叠报表
1:制作一张填报表,如下图所示:
其中,B3的左主格为A2,C4左主格为B3
2:设置A2,B3,C4单元格的html事件
A2单元格:“iddata=’”+value()+”‘ piddata=””
B3单元格:“iddata=’”+value()+”‘ piddata=’”+A2+”‘”
C4单元格:“iddata=’”+value()+”‘ piddata=’”+B3+”‘”
3:初始化报表数
var ReportTreeManager = new function(){
this.version = ’1.0′;
this.map = {};
this.ge = function(id){
return document.getElementById(id);
};
this.get = function(id){
if(this.map.hasOwnProperty(id)) return this.map[id];
else return null;
};
this.put = function(id, tree){
this.map[id] = tree;
};
/**
* 初始化报表树
*/
this.init = function(id){
var t = this.ge(id);
var tree = new ReportTree(t);
tree.init();
this.put(id, tree);
};
};
var ReportTree = function(t){
this.table = t;
this.nodes = null;
this.init = function(){
$(this.table).find(‘td’).each(function(){
//设置点击时鼠标的样式
$(this).css(‘cursor’, ‘default’);
//attr(name)访问jQuery对象里第一个匹配元素的name属性值
var id = $(this).attr(‘iddata’);
if(typeof(id)!=’undefined’) {
$(this).parent().attr(‘iddata’, id);
$(this).parent().attr(‘keycell’, $(this).attr(‘cellIndex’));
}
var pid = $(this).attr(‘piddata’);
if(typeof(pid)!=’undefined’) {
$(this).parent().attr(‘piddata’, pid);
}
$(this).removeAttr(‘iddata’);
$(this).removeAttr(‘piddata’);
});
this.nodes = new Array();
this.travel(”, 0);
};
this.travel = function(pid, lvl){
var ns = new Array();
var rs = $(this.table).find(‘tr[piddata='+pid+']‘).get();
for(var i=0; i<rs.length; i+=1){
var id = $(rs[i]).attr(‘iddata’);
if(typeof(id)==’undefined’){continue;}
$(rs[i]).attr(‘treelvl’,lvl);
var n = new ReportTreeNode(rs[i]);
n.id = id;
n.level = lvl;
ns.push(n);
var kc = $(rs[i]).find(‘td[cellIndex='+$(rs[i]).attr(‘keycell’)+’]');
var subs = this.travel(id, lvl+1);
if(subs!==null && subs.length>0){
n.children = subs;
kc.css(‘cursor’,'pointer’);
kc.addClass(‘button plus’);
kc.click(this.clickhandler);
}
else{
$(rs[i]).removeAttr(‘iddata’);
$(rs[i]).removeAttr(‘treelvl’);
}
$(rs[i]).removeAttr(‘keycell’);
$(rs[i]).removeAttr(‘piddata’);
if(lvl>0) {$(n.row).hide();}
}
if(ns.length > 0){
this.nodes = this.nodes.concat(ns);
}
return ns;
};
this.getnode = function(id, lvl){
// alert(lvl);
var node = null;
for(var i=0; i<this.nodes.length; i+=1){
node = this.nodes[i];
if(node.id==id && node.level==lvl) break;
}
return node;
};
this.clickhandler = function(evt){
var tid = $(this).parents().find(‘table’).attr(‘id’);
var tree = ReportTreeManager.get(tid);
if(tree === null) return;
var id = $(this).parent().attr(‘iddata’);
var lvl = $(this).parent().attr(‘treelvl’);
var node = tree.getnode(id, lvl);
if(node.expand){
$(this).removeClass(‘minus’);
$(this).addClass(‘plus’);
node.expand = false;
tree.collapse(node);
}
else{
$(this).removeClass(‘plus’);
$(this).addClass(‘minus’);
node.expand = true;
tree.expand(node);
}
};
this.collapse = function(node){
//隐藏
var subs = node.children;
for(var i=0; subs!==null && i<subs.length; i+=1){
this.collapse(subs[i]);
$(subs[i].row).hide();
}
};
this.expand = function(node){
//显示
if(!node.expand) return;
var subs = node.children;
for(var i=0; subs!==null && i<subs.length; i+=1){
$(subs[i].row).show();
this.expand(subs[i]);
}
};
};
var ReportTreeNode = function(r){
this.row = r;
this.id = null;
this.level = NaN;
this.children = null;
this.expand = false;
};
4:CSS控制报表样式
/* 折叠报表相关的样式 */
td.button{background-position:4px center;background-repeat:no-repeat;padding-left:20px;text-align:left;}
td.plus{background-p_w_picpath:url(‘plus.png’)}
td.minus{background-p_w_picpath:url(‘minus.png’)}
5:编写jsp发布
<%@ page language=”java” import=”java.util.*” pageEncoding=”UTF-8″%>
<%@taglib uri=”/WEB-INF/runqianReport4.tld” prefix=”report” %>
<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN”>
<html>
<% request.setCharacterEncoding(“UTF-8″);%>
<head>
<title>订单填报表</title>
<meta http-equiv=”pragma” content=”no-cache”>
<meta http-equiv=”cache-control” content=”no-cache”>
<meta http-equiv=”expires” content=”0″>
<!– 引入样式文件 –>
<link rel=”stylesheet” href=”../style/default.css” type=”text/css”/>
</head>
<body>
<center>
<jsp:include page=”../reportJsp/toolbar.jsp” flush=”false” />
<report:html name=”report1″
srcType=”file”
reportFileName=”b.raq”
funcBarLocation=”"
width=”-1″
height=”-1″
/>
</center>
</body>
<!– 引入js文件,必须按下列顺序引入 –>
<script type=”text/javascript” src=”../js/jquery.js”></script>
<script type=”text/javascript” src=”../js/report_tree.js”></script>
<script type=”text/javascript”>
// 将指定报表渲染为折叠报表
$(document).ready(function(){
ReportTreeManager.init(‘report1′);
});
</script>
</html>
6:效果展示:
填报前如图:
折叠再打开后报表不会刷新,点击提交后:
可见,利用jQuery可以实现折叠报表的填报。
四:客户生产环境下报表展示
结论:利用jQuery实现报表的折叠,只需要进行一次报表的运算,折叠打开仅仅是对tr的隐藏显示操作。这种方法不仅提高了报表展示的性能,还可以进行填报,值得大家研究使用。