EasyUI Datagrid跨行跨列的需求

常规开发后台管理系统中遇到的列表查询,都是用到最基本的数据网格,不包括单元格合并,多列页眉,冻结列和页脚等需求。类似如下这个列表

实现也很简单,引入相关的js、css文件,html标签定义展示的列,通过js脚本初始化渲染。

<table id="datagrid">
    <thead>
        <tr>
            <th data-options="field:'realName'" width=10% sortable="true">姓名</th>
            <th data-options="field:'userName'" width=10%  sortable="true" >账号</th>
            <th data-options="field:'loginType'" width=15%>登录方式</th>
            <th data-options="field:'loginTime',formatter:formatLoginTime" width=15% sortable="true">登录时间</th>
            <th data-options="field:'logoutTime',formatter:formatLogoutTime" width=15% sortable="true">登出时间</th>
            <th data-options="field:'requestIp'" width=15%>客户端IP</th>
            <th data-options="field:'loginResult'" width=20%>登录结果</th>
        </tr>
    </thead>
</table>

<script>

function formatLoginTime(val,row){
	return row.loginTimeStr;
}

function formatLogoutTime(val,row){
	return row.logoutTimeStr;
}

//表格查询参数
var queryParams = function () {
    return {
    	searchInput: $("#searchInput").val() || "",
    	loginTimes :$("#loginTimes").val()
    };
}

// 加载表格
var options = {
	url:'${webContext}/basic/loginLog/getAll.json',
	queryParams:queryParams,
	sortName:'loginTime',
	sortOrder:"DESC"
};
var datagrid = new DataGrid("datagrid",options);
function callback(){
	datagrid.refresh();
}

//常规用法
var laydate = layui.laydate;
laydate.render({
    elem: '#loginTimes',
    type: 'datetime',
    range: true
});
</script>

再复杂一点遇到的需求都是表头的跨行跨列、首列冻结,类似下面这样,大都用于统计报表的需求。

这样的数据网格,我们常用的写法;

<table id="datagrid">
    <thead>

    </thead>
</table>
<script>
    var queryParams = function () {
        return {
            year:$('#yearselect').val(),
            halfyear:$('#halfyearselect').val(),
            jd:$('#jdselect').val(),
            mon:$('#monthselect').val(),
            tjsj: $("#ywsj").val()
        };
    }
	function options(){
		return {
		    url: "${webContext}/mydc/stats/ybfltj.json?",
		    fit: true,
		    striped: true,
		    autoRowHeight: true,
		    nowrap: true,
		    pagination: false, //false取消分页
		    rownumbers: true,
		    pageSize: 20,
		    pageList: [10, 20, 30, 40, 50],
		    loadMsg: "数据加载中....",
		    queryParams:queryParams(),
	        onLoadSuccess:function(data){
	            if(data.total==0){
	                //$.messager.alert('提示','查无数据!');
	            }

	        },
            frozenColumns:[[
                {"field":"dwmc","title":"单位",width:'13%'}
            ]],
		    columns:[
		    	[
		    		//设置一个隐藏列,用于导出Excel
		    		{"field":"dwmcyc","title":"单位","rowspan":2,hidden:true},
					{"field":"xb","title":"性别","colspan":2},
		            {"field":"nljd","title":"年龄阶段","colspan":4},
					{"field":"hj","title":"户籍","colspan":3},
					{"field":"jycd","title":"教育程度","colspan":5},
					{"field":"zy","title":"职业分类","colspan":11}
				],[
	            	{"field":"xb1","title":"男","rowspan":1,width:'3%',formatter: function(value,row,index){
	            		row.fieldKey = 'xb1';
                       	return '<span class="num-click-span" Onclick="clickNum('+JSON.stringify(row).replace(/\"/g,"'")+')">'+ value +'</span>'
	            	}},
	             	{"field":"xb2","title":"女","rowspan":1,width:'3%',formatter: function(value,row,index){
	            		row.fieldKey = 'xb2';
                       	return '<span class="num-click-span" Onclick="clickNum('+JSON.stringify(row).replace(/\"/g,"'")+')">'+ value +'</span>'
	            	}},
				 	{"field":"nljd1","title":"16-25岁","rowspan":1,width:'5%',formatter: function(value,row,index){
				 		row.fieldKey = 'nljd1';
                       	return '<span class="num-click-span" Onclick="clickNum('+JSON.stringify(row).replace(/\"/g,"'")+')">'+ value +'</span>'
	            	}},
	            	{"field":"nljd2","title":"26-40岁","rowspan":1,width:'5%',formatter: function(value,row,index){
				 		row.fieldKey = 'nljd2';
                       	return '<span class="num-click-span" Onclick="clickNum('+JSON.stringify(row).replace(/\"/g,"'")+')">'+ value +'</span>'
	            	}},
	            	{"field":"nljd3","title":"41-60岁","rowspan":1,width:'5%',formatter: function(value,row,index){
				 		row.fieldKey = 'nljd3';
                       	return '<span class="num-click-span" Onclick="clickNum('+JSON.stringify(row).replace(/\"/g,"'")+')">'+ value +'</span>'
	            	}},
	            	{"field":"nljd4","title":"60岁以上","rowspan":1,width:'5%',formatter: function(value,row,index){
				 		row.fieldKey = 'nljd4';
                       	return '<span class="num-click-span" Onclick="clickNum('+JSON.stringify(row).replace(/\"/g,"'")+')">'+ value +'</span>'
	            	}},
	            	{"field":"hj1","title":"本地市","rowspan":1,width:'4%',formatter: function(value,row,index){
				 		row.fieldKey = 'hj1';
                       	return '<span class="num-click-span" Onclick="clickNum('+JSON.stringify(row).replace(/\"/g,"'")+')">'+ value +'</span>'
	            	}},
	            	{"field":"hj2","title":"本省其他地市","rowspan":1,width:'5%',formatter: function(value,row,index){
				 		row.fieldKey = 'hj2';
                       	return '<span class="num-click-span" Onclick="clickNum('+JSON.stringify(row).replace(/\"/g,"'")+')">'+ value +'</span>'
	            	}},
	            	{"field":"hj3","title":"外省","rowspan":1,width:'3%',formatter: function(value,row,index){
				 		row.fieldKey = 'hj3';
                       	return '<span class="num-click-span" Onclick="clickNum('+JSON.stringify(row).replace(/\"/g,"'")+')">'+ value +'</span>'
	            	}},
	            	{"field":"jycd1","title":"不识字","rowspan":1,width:'4%',formatter: function(value,row,index){
				 		row.fieldKey = 'jycd1';
                       	return '<span class="num-click-span" Onclick="clickNum('+JSON.stringify(row).replace(/\"/g,"'")+')">'+ value +'</span>'
	            	}},
	            	{"field":"jycd2","title":"小学","rowspan":1,width:'3%',formatter: function(value,row,index){
				 		row.fieldKey = 'jycd2';
                       	return '<span class="num-click-span" Onclick="clickNum('+JSON.stringify(row).replace(/\"/g,"'")+')">'+ value +'</span>'
	            	}},
	            	{"field":"jycd3","title":"中学(含中专、职高、技校)","rowspan":1,width:'6%',formatter: function(value,row,index){
				 		row.fieldKey = 'jycd3';
                       	return '<span class="num-click-span" Onclick="clickNum('+JSON.stringify(row).replace(/\"/g,"'")+')">'+ value +'</span>'
	            	}},
	            	{"field":"jycd4","title":"大专","rowspan":1,width:'3%',formatter: function(value,row,index){
				 		row.fieldKey = 'jycd4';
                       	return '<span class="num-click-span" Onclick="clickNum('+JSON.stringify(row).replace(/\"/g,"'")+')">'+ value +'</span>'
	            	}},
	            	{"field":"jycd5","title":"本科及以上","rowspan":1,width:'5%',formatter: function(value,row,index){
				 		row.fieldKey = 'jycd5';
                       	return '<span class="num-click-span" Onclick="clickNum('+JSON.stringify(row).replace(/\"/g,"'")+')">'+ value +'</span>'
	            	}},
	            	{"field":"zy1","title":"无业","rowspan":1,width:'3%',formatter: function(value,row,index){
				 		row.fieldKey = 'zy1';
                       	return '<span class="num-click-span" Onclick="clickNum('+JSON.stringify(row).replace(/\"/g,"'")+')">'+ value +'</span>'
	            	}},
	            	{"field":"zy2","title":"学生","rowspan":1,width:'3%',formatter: function(value,row,index){
				 		row.fieldKey = 'zy2';
                       	return '<span class="num-click-span" Onclick="clickNum('+JSON.stringify(row).replace(/\"/g,"'")+')">'+ value +'</span>'
	            	}},
	            	{"field":"zy3","title":"务工","rowspan":1,width:'3%',formatter: function(value,row,index){
				 		row.fieldKey = 'zy3';
                       	return '<span class="num-click-span" Onclick="clickNum('+JSON.stringify(row).replace(/\"/g,"'")+')">'+ value +'</span>'
	            	}},
	            	{"field":"zy4","title":"务农","rowspan":1,width:'3%',formatter: function(value,row,index){
				 		row.fieldKey = 'zy4';
                       	return '<span class="num-click-span" Onclick="clickNum('+JSON.stringify(row).replace(/\"/g,"'")+')">'+ value +'</span>'
	            	}},
	            	{"field":"zy5","title":"服务业","rowspan":1,width:'4%',formatter: function(value,row,index){
				 		row.fieldKey = 'zy5';
                       	return '<span class="num-click-span" Onclick="clickNum('+JSON.stringify(row).replace(/\"/g,"'")+')">'+ value +'</span>'
	            	}},
	            	{"field":"zy6","title":"私营业主","rowspan":1,width:'4%',formatter: function(value,row,index){
				 		row.fieldKey = 'zy6';
                       	return '<span class="num-click-span" Onclick="clickNum('+JSON.stringify(row).replace(/\"/g,"'")+')">'+ value +'</span>'
	            	}},
	            	{"field":"zy7","title":"企事业单位","rowspan":1,width:'5%',formatter: function(value,row,index){
				 		row.fieldKey = 'zy7';
                       	return '<span class="num-click-span" Onclick="clickNum('+JSON.stringify(row).replace(/\"/g,"'")+')">'+ value +'</span>'
	            	}},
	            	{"field":"zy8","title":"公务员","rowspan":1,width:'4%',formatter: function(value,row,index){
				 		row.fieldKey = 'zy8';
                       	return '<span class="num-click-span" Onclick="clickNum('+JSON.stringify(row).replace(/\"/g,"'")+')">'+ value +'</span>'
	            	}},
	            	{"field":"zy9","title":"自由职业者","rowspan":1,width:'5%',formatter: function(value,row,index){
				 		row.fieldKey = 'zy9';
                       	return '<span class="num-click-span" Onclick="clickNum('+JSON.stringify(row).replace(/\"/g,"'")+')">'+ value +'</span>'
	            	}},
	            	{"field":"zy10","title":"离退休","rowspan":1,width:'4%',formatter: function(value,row,index){
				 		row.fieldKey = 'zy10';
                       	return '<span class="num-click-span" Onclick="clickNum('+JSON.stringify(row).replace(/\"/g,"'")+')">'+ value +'</span>'
	            	}},
	            	{"field":"zy11","title":"其他","rowspan":1,width:'3%',formatter: function(value,row,index){
				 		row.fieldKey = 'zy11';
                       	return '<span class="num-click-span" Onclick="clickNum('+JSON.stringify(row).replace(/\"/g,"'")+')">'+ value +'</span>'
	            	}}
				]
		    ]
		};
	}

	var datagrid = $('#datagrid').datagrid(options());

    function clickNum(row) {
    	var year = $('#yearselect').val();
    	var halfyear = $('#halfyearselect').val();
    	var jd = $('#jdselect').val();
    	var mon = $('#monthselect').val();
    	var tjsj = $("#ywsj").val();
    	layer.open({
    		type : 2,
    		title : "问卷调查记录列表",
    		shadeClose : false,
    		shade : 0.3,
    		area : ['90%',"90%" ],
    		btn : [ '关闭'],
    		btnAlign : 'c',
    		content : "${webContext}/monitor/mydc/stats/tjwjjl-list.htm?ybfltj=ywfltj&pcscode="+row.pcscode+"&fieldKey="+row.fieldKey+"&yearselect="+year+"&halfyearselect="+halfyear+"&jdselect="+jd+"&monthselect="+mon+"&ywsj="+tjsj,
            end:function(index, layero){
    			layer.close(index);
    		}
    	});
    }
	//导出excel
	function exportExcel() {
		$('#datagrid').datagrid('toExcel', '样本分类统计.xls');
	}

	function refresh() {
		$('#datagrid').datagrid('reload',queryParams());
	}
</script>

最近给客户做一个统计,这个报表要求除表头外,数据行如果特征类型一样,就合并行显示。

我百度找到了类似的案例https://www.pianshen.com/article/25421489926/,上面这个表格的代码如下:

<table id="datagrid">
    <thead>

    </thead>
</table>

<script>
    var queryParams = function () {
        return {
            year:$('#yearselect').val(),
            halfyear:$('#halfyearselect').val(),
            jd:$('#jdselect').val(),
            mon:$('#monthselect').val(),
            tjsj: $("#ywsj").val()
        };
    }
	function options(){
		return {
		    url: "${webContext}/mydc/stats/ybflmydtj.json?",
		    fit: true,
		    striped: true,
		    autoRowHeight: true,
		    nowrap: true,
		    pagination: false, //false取消分页
		    rownumbers: true,
		    pageSize: 20,
		    pageList: [10, 20, 30, 40, 50],
		    loadMsg: "数据加载中....",
		    queryParams:queryParams(),
		    columns:[
		    	[
					{"field":"tz","title":"特征",width:'12%'},
					{"field":"tzz","title":"特征分类",width:'16%'},
		            {"field":"shzamyd","title":"社会治安满意度",width:'18%'},
					{"field":"gadwmyd","title":"公安队伍满意度",width:'18%'},
					{"field":"gackfwmyd","title":"公安窗口服务满意度",width:'18%'},
					{"field":"sqmjmyd","title":"社区民警熟悉度",width:'18%'}
				]
		    ],  
            onLoadSuccess: function (data) {
                if(data.rows.length > 0) {
                    //调用mergeCellsByField()合并单元格
                    mergeCellsByField("datagrid", "tz");
                }
            }
		};
	}

	var datagrid = $('#datagrid').datagrid(options());
	
	function refresh() {
		$('#datagrid').datagrid('reload',queryParams());
	}

	/**
	 * EasyUI DataGrid根据字段动态合并单元格
	  *   参数 tableID 要合并table的id
	  *   参数 colList 要合并的列,用逗号分隔(例如:"name,department,office");
	 */
	function mergeCellsByField(tableID, colList) {
	   var ColArray = colList.split(",");
	   var tTable = $("#" + tableID);
	   var TableRowCnts = tTable.datagrid("getRows").length;
	   var tmpA;
	   var tmpB;
	   var PerTxt = "";
	   var CurTxt = "";
	   var alertStr = "";
	   for (j = ColArray.length - 1; j >= 0; j--) {
	       PerTxt = "";
	       tmpA = 1;
	       tmpB = 0;

	       for (i = 0; i <= TableRowCnts; i++) {
	           if (i == TableRowCnts) {
	               CurTxt = "";
	           }
	           else {
	               CurTxt = tTable.datagrid("getRows")[i][ColArray[j]];
	           }
	           if (PerTxt == CurTxt) {
	               tmpA += 1;
	           }
	           else {
	               tmpB += tmpA;
	               tTable.datagrid("mergeCells", {
	                   index: i - tmpA,
	                   field: ColArray[j],  //合并字段
	                   rowspan: tmpA,
	                   colspan: null
	               });
	               tmpA = 1;
	           }
	           PerTxt = CurTxt;
	       }
	   }
	}
    
	//导出excel
	function exportExcel() {
		//$('#datagrid').datagrid('toExcel', '样本分类满意度统计.xls');
		var index = layer.confirm('确认导出列表数据吗?', {
	    	btn: ['确认','取消'] //按钮
		}, function(){
	 		layer.msg('正在导出,请稍后....', {icon: 1,time:1000});
	     	var params = queryParams();
	    	postExcelFile(params, "${webContext}/mydc/stats/ybflmydtj/exportExcel.json");
	    	layer.close(index);
		}, function(){
	   		layer.close(index);
	   	});
	}
	
	function postExcelFile(params, url) {
	    var form = document.createElement("form");
	    form.style.display = 'none';
	    form.action = url;
	    form.method = "post";
	    document.body.appendChild(form);

	    for(var key in params){
	        if(params[key] instanceof Array){
	            var arr = params[key];
	            for(var i=0;i<arr.length;i++){
	                var input = document.createElement("input");
	                input.type = "hidden";
	                input.name = key+"[]";
	                input.value = arr[i];
	                form.appendChild(input);
	            }
	        }else{
	            var input = document.createElement("input");
	            input.type = "hidden";
	            input.name = key;
	            input.value = params[key];
	            form.appendChild(input);
	        }
	    }
	    form.submit();
	    form.remove();
	}
</script>

数据的跨行合并,是在Datagrid数据加载成功时触发onLoadSuccess函数。

当我尝试将表头第一列和第二列合并时,遇到了样式错误问题。

我也是在onLoadSuccess函数进行操作的代码如下:

onLoadSuccess: function (data) {
    if(data.rows.length > 0) {
        //调用mergeCellsByField()合并单元格
        mergeCellsByField("datagrid", "tz");
                    
        var celltzwidth = $(".datagrid-cell-c1-tz").width();
        var celltzzwidth = $(".datagrid-cell-c1-tzz").width();
        //表头特征跨两列操作
        $(".datagrid-header-row td").each(function(){
            var field = $(this).attr("field");
            if(field == 'tz'){
                $(this).attr("rowspan",1);
                $(this).attr("colspan",2);
                $(this).attr("class","datagrid-td-merged");
                $(this).find("div").css('width',celltzwidth+celltzzwidth+17+'px');
            }else if(field == 'tzz'){
                $(this).css('display','none');//隐藏
            } 
         });
   }
}

我这种方法,不管怎么调,就算我当前使用的浏览器显示正常了,不不能保证其他显示器、浏览器不会错误。这个问题暂时没有想到办法,如果你恰好看到我这篇文章,有思路解决这个问题,欢迎给我留言,谢谢。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

招风的黑耳

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值