注 : 使用的是静态HTML,只是为了偷个懒,和页面模板渲染效果一样。本文章会不定期更新,如果有什么疑问,可以在下面提出来。如果本篇对你有所帮助,希望可以给个赞。
1. 准备工作
有序的数据
比如下面这些数据:
2. 页面展示
上面的数据会展示成如下效果:
3. 页面代码
原理:
1. 首先先确定要比较什么,比如我们第一次比较的是地区列,这里肯定是用的for循环和冒泡算法来比较,
但是下一次,要比较的是行业那一列,所以需要递归去替换要比较的列,用一个参数来保存当前比较的那一列。
2. 需要一个数组用于保存接下来要比较的列,比较的时候弹出来,比较完之后将该列加入已经比较完成的数组中。
3. 在每次比较当前列的同时,比较已经完成的列是否一致,一致就将跨行计数+1,否则不做操作。
说明在下面
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.bootcss.com/jquery/1.12.4/jquery.min.js"></script>
<!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css"
integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js"
integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
</head>
<body style="padding-top: 50px;">
<div class="container">
<table class="table table-bordered">
<thead>
<th>地区</th>
<th>行业</th>
<th>行业人数</th>
<th>行业男生人数比例</th>
<th>行业女生人数比例</th>
</thead>
<tbody>
<tr>
<td class="rowSpan_in">上海</td>
<td class="rowSpan_merge1">餐饮</td>
<td class="rowSpan_merge2">111</td>
<td class="rowSpan_merge3">80%</td>
<td class="rowSpan_merge4">20%</td>
</tr>
<tr>
<td class="rowSpan_in">上海</td>
<td class="rowSpan_merge1">餐饮</td>
<td class="rowSpan_merge2">111</td>
<td class="rowSpan_merge3">80%</td>
<td class="rowSpan_merge4">16%</td>
</tr>
<tr>
<td class="rowSpan_in">上海</td>
<td class="rowSpan_merge1">物流</td>
<td class="rowSpan_merge2">111</td>
<td class="rowSpan_merge3">90%</td>
<td class="rowSpan_merge4">10%</td>
</tr>
<tr>
<td class="rowSpan_in">北京</td>
<td class="rowSpan_merge1">物流</td>
<td class="rowSpan_merge2">222</td>
<td class="rowSpan_merge3">90%</td>
<td class="rowSpan_merge4">10%</td>
</tr>
<tr>
<td class="rowSpan_in">北京</td>
<td class="rowSpan_merge1">IT</td>
<td class="rowSpan_merge2">111</td>
<td class="rowSpan_merge3">90%</td>
<td class="rowSpan_merge4">10%</td>
</tr>
</tbody>
</table>
</div>
</body>
<script>
/*
这是一个递归函数
rowSpanInClass 代表当前要合并的class 列,有多个dom节点,
比如第一次递归的值是地区那一列,第二次递归是行业那一列
rowSpan_merge 代表后续要合并的class,rowSpanInClass变,它就会减少
beforeClass 代表比较数组,随着递归次数增加,里面的元素个数也会增加,每次个数+1
*/
function superRowspan(rowSpanInClass,rowSpan_merge,beforeClass) {
var rowSpanInList = $(rowSpanInClass);
//遍历需要合并的dom元素,用到冒泡算法
for(var i=0;i<rowSpanInList.length;i++){
var num = 1;
//遍历需要的合并的dom列
for (var j=i+1;j< rowSpanInList.length;j++){
var rowi = rowSpanInList.eq(i);
var rowj = rowSpanInList.eq(j);
//判断当前要合并的class的dom元素的内容是否一致,
if (rowi.text() == rowj.text()) {
var flag = true;
//如果一致,就判断前面的比较数组中内容是否一致
for (var m = 0; m < beforeClass.length; m++) {
var beforei = $(beforeClass[m]).eq(i);
var beforej = $(beforeClass[m]).eq(j);
//如果不一致,就设置标志位,跳出比较数组中的比较
if (beforei.text() != beforej.text()) {
flag = false;
break;
}
}
//如果比较数组都一致,那么就将跨行计数++
if (flag) {
num++;
//因为html中的rowspan是放在第一个元素的属性里面的
//j比i大,所以删除j元素,将i元素置为更新跨行
rowj.addClass("delete_span");
rowi.addClass("update_span");
rowi.attr("r", num);
}
}else{
//如果i中途与某个比较不一样,就终止i的比较,并且将i的值置位不一样的值
i = j-1;
break;
}
}
}
//如果是第一次递归,那么beforeClass的长度一定为1,执行下面操作
if(beforeClass.length == 1){
while(1){
//弹出下一个需要合并的class
var shift = rowSpan_merge.shift();
if(shift != undefined) {
//如果有,就把它放到比较数组中,进行再次的遍历
beforeClass.push(shift);
superRowspan(shift,rowSpan_merge,beforeClass);
}else{
break;
}
}
}
}
$(function() {
var rowSpan_in = ".rowSpan_in";
var rowSpan_merge = [
".rowSpan_merge1"
,".rowSpan_merge2"
,".rowSpan_merge3"
,".rowSpan_merge4"
,".rowSpan_merge5"
,".rowSpan_merge6"
,".rowSpan_merge7"
];
superRowspan(rowSpan_in,rowSpan_merge,[rowSpan_in]);
//当遍历完要合并的元素,就可以把该删除的dom节点删除,
$(".delete_span").remove();
//更新dom元素跨行属性
$(".update_span").each(function () {
$(this).attr("rowspan",$(this).attr("r"));
});
});
</script>
</html>
4. 页面代码说明
JS代码说明
HTML 使用说明
5. 结尾
PS : 后续更新如何给导出的EXCEL合并单元格,和页面效果一样。