需求:
报表数量过多,但功能类似,所以出于效率做一个可以配置页面
数据来源:
从ztree树中让用户去配置(如下图)
取到的数据即为ztree树的数据格式(如下图)
模拟数据:
var data=[ {name:'AA',value:2.3,id:'101',pid:'000'}, {name:'BB',value:2.3,id:'102',pid:'000'}, {name:'CC',value:2.3,id:'101101',pid:'101'}, {name:'DD',value:2.3,id:'101102',pid:'101'}, {name:'EE',value:2.3,id:'101101101',pid:'101101'}, {name:'FF',value:2.3,id:'101101102',pid:'101101'}, {name:'GG',value:2.3,id:'101102101',pid:'101102'}, {name:'HH',value:2.3,id:'101102102',pid:'101102'}, {name:'II',value:2.3,id:'102101',pid:'102'}, {name:'JJ',value:2.3,id:'102101101',pid:'102101'}, {name:'KK',value:2.3,id:'102101102',pid:'102101'}, {name:'MM',value:2.3,id:'102101103',pid:'102101'}, {name:'NN',value:2.3,id:'102101104',pid:'102101'}, {name:'LL',value:2.3,id:'102101105',pid:'102101'}, ];
实现步骤:
1、将获取到的ztree数据进行分组,按照节点id的长度进行分组得出数据{3:[],6:[],9:[]}
//分组 function group(data){ var obj={}; for(var i=0;i<data.length;i++){ var _l=data[i].id.length; if(obj[_l]===undefined){ obj[_l]=[data[i]]; }else{ obj[_l].push(data[i]) } } return obj; }
2、得出排序的规则,从id长的向短的遍历得出数组[9,6,3]
//获得排序信息 function getList(obj){ return Object.keys(obj).sort(function(a,b){return Number(b)-Number(a)}); }
3、核心部分
原理:从后面往前面遍历,遍历最后一列的时候就能够得出他的直接父级单元格的行合并,同时可以得出当前单元格拼接的str,再依次往后面遍历,遍历到第一列的时候就得出整个表格了,需要特别注意的是,除了最后一列,可以得出第二组的行合并已经第三组的str
遍历第三组的时候得出
{ 101101:{ l:2, str:'<td>101101101</td><td>101101102</td></tr>' }, 101102:{ l:2, str:'<td>101102101</td><td>101102102</td></tr>' } }
在遍历第二组的时候就需要注意了,此时需要
代码示例
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style> table { border-collapse: collapse; border-spacing: 0; 800px; margin:auto; } td{ border:1px solid #ddd; padding:3px 10px; text-align: center; } </style> </head> <body> <div id="table"> </div> <script> var data=[ {name:'AA',value:2.3,id:'101',pid:'000'}, {name:'BB',value:2.3,id:'102',pid:'000'}, {name:'CC',value:2.3,id:'101101',pid:'101'}, {name:'DD',value:2.3,id:'101102',pid:'101'}, {name:'EE',value:2.3,id:'101101101',pid:'101101'}, {name:'FF',value:2.3,id:'101101102',pid:'101101'}, {name:'GG',value:2.3,id:'101102101',pid:'101102'}, {name:'HH',value:2.3,id:'101102102',pid:'101102'}, {name:'II',value:2.3,id:'102101',pid:'102'}, {name:'JJ',value:2.3,id:'102101101',pid:'102101'}, {name:'KK',value:2.3,id:'102101102',pid:'102101'}, {name:'MM',value:2.3,id:'102101103',pid:'102101'}, {name:'NN',value:2.3,id:'102101104',pid:'102101'}, {name:'LL',value:2.3,id:'102101105',pid:'102101'}, ]; creatTable(data); //分组 function group(data){ var obj={}; for(var i=0;i<data.length;i++){ var _l=data[i].id.length; if(obj[_l]===undefined){ obj[_l]=[data[i]]; }else{ obj[_l].push(data[i]) } } return obj; } //获得排序信息 function getList(obj){ return Object.keys(obj).sort(function(a,b){return Number(b)-Number(a)}); } //计算 function creatTable(data){ var d=group(data); var arr=getList(d); var obj={}; for(var i=0,len=arr.length;i<len;i++){ for(var k=0;k<d[arr[i]].length;k++){ var o=d[arr[i]][k]; if(obj[o.pid]===undefined){ obj[o.pid]={l:0,s:0,str:''}; } //如果为表格的最后一列 if(i==0){ obj[o.pid].l++; obj[o.pid].s+=o.value; obj[o.pid].str+=(obj[o.pid].str==''?'':'<tr>')+"<td>"+o.name+"</td><td>"+o.value+"</td></tr>";//结尾都有tr }else{ var str=''; //如果为表格的第一列 if(!((i+1)<len)){ str="<tr>"; }else{ str=obj[o.pid].str==''?'':'<tr>'; obj[o.pid].l+=obj[o.id].l; } str+="<td rowspan='"+obj[o.id].l+"'>"+o.name+"</td><td rowspan='"+obj[o.id].l+"'>"+o.value+"</td>"; obj[o.pid].s+=obj[o.id].s; obj[o.pid].str+=(str+obj[o.id].str); } } } document.getElementById('table').innerHTML="<table>"+obj['000'].str+"</table>"; //i<d[arr[arr.length-1]].length } </script> </body> </html>
效果: