常规开发后台管理系统中遇到的列表查询,都是用到最基本的数据网格,不包括单元格合并,多列页眉,冻结列和页脚等需求。类似如下这个列表
实现也很简单,引入相关的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');//隐藏
}
});
}
}
我这种方法,不管怎么调,就算我当前使用的浏览器显示正常了,不不能保证其他显示器、浏览器不会错误。这个问题暂时没有想到办法,如果你恰好看到我这篇文章,有思路解决这个问题,欢迎给我留言,谢谢。