如何用easyui+JAVA 实现动态拼凑datagrid表格
先给大家看一看效果,最近一段时间都在研究这个东西。

如果我把日期间隔选宽呢?比如5月日到5月5日?下面给大家看看效果,不用担心哦

看到了吧,哈哈,这个日期都是动态生成的,下面就来跟大家分享一下这个的实现方法。
本人是用JAVA EE的后台实现的,
先来贴HTML代码:
<div>站点:<input class="easyui-combobox" width="200px" id="stnmCombo">
起始时间:<input id="StartTime" class="easyui-datebox" editable="false" />
结束时间:<input id="EndTime" class="easyui-datebox" editable="false" />
<a id="btnSearch" href="#" class="easyui-linkbutton" data-options="iconCls:'icon-search'">查询</a>
<a id="export" href="#" class="easyui-linkbutton" data-options="iconCls:'icon-search'">导出</a>
</div> <div class="easyui-layout" fit="true">
<table id="dg"></table>
</div>
HTML代码非常的简单,其中关键的datagrid只有一个TABLE,其实关键在于JS代码哦
下面就把代码发出来:
我来给大家解释下几个关键的地方以及思路吧,代码不是特别的复杂。
- formLoader.load(param1,param2,function(s){})这个方法第一个参数就是controller的RequestMapping的名字,因为是用的MVC三层构架弄的,第二个参数可以是字符串的,也可以是一个JSON对象,此方法返回的是一个JSON对象,如果alert(s)就会看到结果,这个公司框架的一个方法,所以大家不用再找,我只是分享思路。
- 本例子主要是后台构造动态列,使用得比较多的是PUSH方法,用PUSH方法把JSON对象存到数组里面去。
其中有几点需要解释一下:表头名称title,field(JSON对象返回到的对应的Key),field给大家放张图片就知道了
下面是具体的代码:
var gv=$("#dg");
var today=new Date();
//动态生成列
var dynamicCols=[];
var dynamicItems=[];
var dynamicItemsAfter=[];
var dynamicItemsEnd=[];
$(function(){
$("#StartTime").datebox('setValue',today.getFullYear()+"-"+(today.getMonth()+1)+"-"+(today.getDate()-1));
$("#EndTime").datebox('setValue',today.getFullYear()+"-"+(today.getMonth()+1)+"-"+(today.getDate()));
//绑定空数据
gv.datagrid( "dataBind" ,
{
autoHeight : 46 ,
datas : [],
striped:true,
pagination : true,
autoRowHeight:false
});
//绑定空列
gv.datagrid({
columns:[[
{title:'时间',width:150,sortable:true},
{title:'站点1',width:150,sortable:true},
{title:'站点2',width:150,sortable:true},
{title:'站点3',width:500,sortable:true},
]]
});
});
//列元素(动态)
//序号
var stcd={
field: 'Stcd',
title: '序号',
// width: 150,
rowspan:3,
sortable:true
}
//站名
var stnm={
field: 'Stnm',
title: '站名',
// width: 150,
rowspan:3,
sortable:true
}
//平均值
var avg={
title:'平均值',
//width:500,
colspan:2
}
//库水位
var rz={
title:'库水位',
//width:150 /*PS:动态列中不适宜固定宽度,其他同样的*/
}
//库容
var rv={
title:'库容',
width:150
}
//库容(平均)
var rvAvg={
title:'库容',
field:"rvAvg2",
//width:500
formatter:function(value,row,index)
{
return "-";
}
}
//查询按钮
$("#btnSearch").click(function(){
//得到开始日期和结束日期之间的天数之差
var ipt1=$("#StartTime").datebox('getValue');
var ipt2=$("#EndTime").datebox('getValue');
var arr1 = ipt1.split("-");
var arr2 = ipt2.split("-");
var dt1 = new Date();
dt1.setFullYear(arr1[0]);
dt1.setMonth(arr1[1] - 1);
dt1.setDate(arr1[2]);
var dt2 = new Date();
dt2.setFullYear(arr2[0]);
dt2.setMonth(arr2[1] - 1);
dt2.setDate(arr2[2]);
var dif = dt2.getTime() - dt1.getTime();
var days = dif / (24 * 60 * 60 * 1000);
//再次初始化,避免数组的堆积
dynamicCols=[];
dynamicItems=[];
dynamicItemsAfter=[];
dynamicItemsEnd=[];
//前部
dynamicItems.push(stcd);
dynamicItems.push(stnm);
//查询条件数据
var datas={
"Stcd":$("#stnmCombo").combobox('getValue'),
"StartTime":$("#StartTime").datebox('getValue'),
"EndTime":$("#EndTime").datebox('getValue')
}
//查询具体的数据
formLoader.load("querydata",datas,function(s){
//空白SPAN
var blank={
title:' ',
colspan:days*2+4 //动态得到COLSPAN的跨度,根据天数
}
dynamicItems.push(blank);
//var sss = s;
//遍历动态数组
// for(j=0;j<s.length;j++)
// {
//alert(s.DaynamicList[1].z0);
//alert(s[7].DynamicList.z0);
//动态载入库水位数据
//库水位
rz={
title:'库水位',
field:"DynamicList",
formatter:function(value,row,index){
//alert(row);
//return value.z1; //因为这是一个对象DynamicList,所以返回对象的值
//alert(value);
var temp;
$.each(value,function(i,option){
//alert(option);
temp=option;
});
return temp;
}
}
//alert(s);
//拼凑表头
$.each(s[0].DynamicList, function(i,option){
//alert(i);
//alert(i);
rv={
title:'库容',
field:"DynamicList2",
formatter:function(value,row,index)
{
return "-";
}
}
//详细数据
var k=0; //设定一个值,匹配Z0,Z1,Z2。。。。。
var d = new Date($("#StartTime").datebox('getValue'));
do{
//alert(i.substring(1));
d.setDate(d.getDate()+parseInt(i.substring(1))); //转换成INT类型的
var RealDate=d.getFullYear()+"-"+(d.getMonth()+1)+"-"+d.getDate(); //动态得到日期值
var details2={
title:RealDate,
// width:150,
colspan:2
}
dynamicItemsAfter.push(details2);
k+=2;
break; //这里因为会执行i此结果 ,所以 BREAK掉
}while(days>k)
//dynamicItemsAfter.push(details2);
// dynamicItemsEnd.push(rz);
// dynamicItemsEnd.push(rv);
dynamicItemsEnd.push(rz);
dynamicItemsEnd.push(rv);
//dynamicItemsAfter.push(details2);
});
// }
//库水位(平均)
var rzAvg={
title:'库水位',
field:"DynamicList5", //这里随便设一个Field
formatter:function(value,row,index)
{
var k=row.DynamicList;
//alert(k);
//算出平均值
var temp=0;
$.each(k,function(i,option){
//alert(option);
//alert(i);
temp+=Number(option);
//alert(temp);
});
//alert(temp);
//return 0;
//alert(temp);
return temp/(days+1);
}
//width:150
}
//alert(s[0].Stcd);
dynamicItemsAfter.push(avg);
dynamicItemsEnd.push(rzAvg);
dynamicItemsEnd.push(rvAvg);
dynamicCols.push(dynamicItems);
dynamicCols.push(dynamicItemsAfter);
dynamicCols.push(dynamicItemsEnd);
//绑定动态列
gv.datagrid({
columns:dynamicCols,
});
gv.datagrid( "dataBind" ,
{
datas : s,
striped:true,
pagination : true,
pageSize:15
});
//total();
});
});
//得到测站编码
var dataCount=0;
formLoader.load("getstnm","",function(data){
data.unshift({Stnm : "全部" , Stcd : "" });
$("#stnmCombo").combobox({
data:data,
valueField:"Stcd",
textField:"Stnm",
editable:false,
//panelHeight:"auto",
onLoadSuccess:function()
{
//alert('1');
//alert(data[0].Stcd);
$("#stnmCombo").combobox('setValue',data[0].Stcd);
dataCount=data.length;
},
onShowPanel:function()
{
if(dataCount.length>10)
{
$(this).combobox('panel').height(251);
}
}
});
});
本例的难点在于,要构建一个动态的DTO实体类,因为我返回的是一个LIST<DTO的名称>,因为列是不固定的,所以这个是一个难点,这个怎么实现呢?
其实大家细心的注意到了有一个Field叫做DynamicList我们把这个DYNAMICLIST打开看看里面的内部结构。

这里其实是因为我选择了8个日期间隔的时间,所以就有8个元素在里面,如果我选择了4天时间间隔呢?

这个是怎么实现的呢?
下面进入后台时间,其实后台是拼接的SQL,先给大家看看查询SQL是怎么拼凑出来的。
public String querySql(ReservoirDayReportParam param)
{
StringBuffer sb=new StringBuffer();
sb.append("select b.STNM,r.STCD,"); //开始时间和结束时间
String startTime=param.getStartTime();
String endTime=param.getEndTime(); SimpleDateFormat format =new SimpleDateFormat("yyyy-mm-dd");
Calendar start=Calendar.getInstance();
Calendar end=Calendar.getInstance();
try
{
start.setTime(format.parse(startTime));
end.setTime(format.parse(endTime)); }
catch(Exception e)
{
e.printStackTrace();
} //遍历出时间
int count=0;
while(start.compareTo((end))<=0)
{ String time=format.format(start.getTime());
String finalStart=time.concat(" 00:00:00"); //最终获得的每天的开始时间
String finalEnd=time.concat(" 23:59:59"); //最终获得的每天的结束时间 sb.append("max(case when r.TM between '"+finalStart+"' and '"+finalEnd+"' then r.RZ else 0 end) as z"+count+",");
count++;
start.add(Calendar.DAY_OF_MONTH, 1);
//列的别名
}
String tempBuffer=sb.substring(0,sb.length()-1); //把获得的值的最后一个逗号去掉
StringBuffer lastBuff=new StringBuffer(); //新建一个字符串
lastBuff.append(tempBuffer); lastBuff.append(" from ST_RSVR_R r,ST_STBPRP_B b where r.stcd=b.stcd");
if(!param.getStcd().equals(""))
{
lastBuff.append(" and r.STCD='"+param.getStcd()+"'");
} lastBuff.append(" group by b.STNM,r.STCD");
return lastBuff.toString();
}
其中的ReservoirDayReportParam 是一个实体类,代码都有注释的,我就说说关键的,其实的动态列(水位)这一列,其实是根据传入的开始时间和结束时间,来循环去把SQL拼凑出来,代码不是太难,中间使用到了一个count的变量,用来给列起别名,比如z0,z1,z2,z3...等等。 那么这样就实现了动态的拼接SQL,就是我有选择了多少个日期间隔,就会在后台AS出多少个动态列,下面先给大家看看实体模型吧。
//开始时间和结束时间
private String startTime;
private String endTime; public Map getDynamicList() {
return dynamicList;
}
public void setDynamicList(Map dynamicList) {
this.dynamicList = dynamicList;
}
//动态实体类
private Map dynamicList;
其中的dynamicList就是动态的,为什么是Map类型的?那是因为可以添加键值对。把形如z0,z1这样的添加到里面去,这就实现了动态化。
开始已经说过了formLoader方法,那么我们要执行的这个方法,在后台优势什么样呢?
public List<ReservoirDayReportParam> queryData(ReservoirDayReportParam param) {
// TODO Auto-generated method stub
String sql=querySql(param);
List<Object[]> dataFromSTCD=this.daoHelper.findBySql(sql);
List<ReservoirDayReportParam> arrList=new ArrayList<ReservoirDayReportParam>();
List list = new ArrayList();
try
{
for(Object[] obj:dataFromSTCD)
{
ReservoirDayReportParam params=new ReservoirDayReportParam();
Map map=new LinkedHashMap(); //新建一个ARRLIST,用于存放动态列
params.setStnm(String.valueOf(obj[0]));
params.setStcd(String.valueOf(obj[1]));
//把动态列存到Map中去,然后分别设定键值对
for(int i=2;i<dataFromSTCD.get(0).length;i++)
{
map.put("z"+(i-2), obj[i]);
}
params.setDynamicList(map);
arrList.add(params);
}
}
catch(Exception e)
{
e.printStackTrace();
}
return arrList;
}
其中的querySql就是刚才的拼接SQL的方法。
首先得到拼接的SQL,那个findbysql方法是返回一个List集合的方法,公司框架,知道意思就行,大家可以无视。
具体思路就是从List中循环出结果,然后添加到实体类中去,然后再把每个实体类添加到arraylist中去,然后再返回。 具体的注释已经写了,JS代码是主体,大家如果有不懂的地方,可以留言。
如何用easyui+JAVA 实现动态拼凑datagrid表格的更多相关文章
- 如何用easyui+JAVA 实现动态拼凑datagrid表格(续)
前面一段时间写了一篇文章: 如何用easyui+JAVA 实现动态拼凑datagrid表格 这篇文章的话,效果是可以实现,但是经过我反复试验,还是存在一些问题的. 今天这篇文章就是向大家介绍下如何避免 ...
- PHP+Mysql+easyui点击左侧tree菜单对应表名右侧动态生成datagrid加载表单数据(二)
关于tree菜单生成,参考我的另一篇博文地址tree 菜单 实现功能:点击左侧tree菜单中的table,右侧通过datagrid加载出该表对用的所有数据 难点:获取该表的所有列名,动态生成datag ...
- 用Servlet返回JSON文本动态创建DataGrid
<%@ page language="java" pageEncoding="UTF-8"%> <!DOCTYPE HTML PUBLIC & ...
- 雷林鹏分享:jQuery EasyUI 数据网格 - 动态改变列
jQuery EasyUI 数据网格 - 动态改变列 数据网格(DataGrid)列可以使用 'columns' 属性简单地定义.如果您想动态地改变列,那根本没有问题.为了改变列,您可以重新调用dat ...
- jQuery EasyUI中DataGird动态生成列的方法
EasyUI中使用DataGird显示数据列表中,有时需要根据需要显示不同的列,例如,在权限管理中,不同的用户登录后只能查看自己权限范围内的列表字段,这就需要DataGird动态组合列,下面介绍Eas ...
- java的动态代理机制详解
在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的 ...
- java中动态代理实现机制
前言: 代理模式是常用的java设计模式,它的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常会存在关联关系 ...
- Java特性-动态代理
代理在开发中无处不在: 我们完成一个接口开发A,接口下有很多个实现类,这些类有些共同要处理的部分,比如每一个类都定义了接口A中的方法getXX(String name).我现在想把每次调用某个实现类的 ...
- java --- 设计模式 --- 动态代理
Java设计模式——动态代理 java提供了动态代理的对象,本文主要探究它的实现, 动态代理是AOP(面向切面编程, Aspect Oriented Programming)的基础实现方式, 动态代理 ...
随机推荐
- Django数据导入
从网上下载的一些数据,excel表格,xml文件,txt文件等有时候我们想把它导入数据库,应该如何操作呢? 以下操作符合 Django版本为 1.6 ,兼顾 Django 1.7, Django 1. ...
- 一步一步学ROP之linux_x64篇
一步一步学ROP之linux_x64篇 一.序 **ROP的全称为Return-oriented programming(返回导向编程),这是一种高级的内存攻击技术可以用来绕过现代操作系统的各种通用防 ...
- Python黑帽编程2.5 函数
Python黑帽编程2.5 函数 写了几节的基础知识,真心感觉有点力不从心.这块的内容说实话,看文档是最好的方式,本人的写作水平,真的是找不出更好的写法,头疼.简单带过和没写一样,写详细了和本系列教程 ...
- 剑指Offer面试题:4.从尾到头打印链表
一.题目:从尾到头打印链表 题目:输入一个链表的头结点,从尾到头反过来打印出每个结点的值. 到解决这个问题肯定要遍历链表.遍历的顺序是从头到尾的顺序,可输出的顺序却是从尾到头.也就是说第一个遍历到的结 ...
- iOS开发系列--C语言之存储方式和作用域
概述 基本上每种语言都要讨论这个话题,C语言也不例外,因为只有你完全了解每个变量或函数存储方式.作用范围和销毁时间才可能正确的使用这门语言.今天将着重介绍C语言中变量作用范围.存储方式.生命周期.作用 ...
- Linux服务器配置之加载硬盘
Linux服务器配置之加载硬盘 1.修改密码 passwd 2.测试密码是否成功 3.查看硬盘信息 fdisk –l 4.格式化分区 fdisk /dev/vdb 5.查看分区 6.快速格式化/dev ...
- 监控Linux系统性能的工具--nmon(一)
今天看到一资料上写着,nmon可以对linux系统进行性能监控,随手在自己的阿里云上敲了一下这个命令,提示'command not find' 一脸懵~,然后探索了一下如何安装这个工具以及如何更好的查 ...
- 仿h5拖拽
在h5中有个拖拽的声明式命令,就如html属性一样,简单强大. 而在网页上拖拽的功能还是需求很大的,所以对这方面应该去仔细了解一下. 所以仿一一下它的实现.只是仿了它的复制一份到目标容器的功能.它还有 ...
- 斐讯Fir302b救砖教程
首先本人是路由器小白,不算是硬件改装高手,昨天收到了微信活动中的斐讯Fir302b,大概当时得奖的有300人,所以最近肯定很大一批朋友手里有这样的一款路由. 上网查了一下,此款路由可以刷基于tomat ...
- [汇编与C语言关系]5. volatile限定符
现在研究一下编译器优化会对生成的指令产生什么影响,在此基础上介绍C语言的volatile限定符.首先看下面的C程序: /* artificial device registers */ unsigne ...