首页 > 代码库 > 如何用easyui+JAVA 实现动态拼凑datagrid表格

如何用easyui+JAVA 实现动态拼凑datagrid表格

先给大家看一看效果,最近一段时间都在研究这个东西。

技术分享

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

技术分享

看到了吧,哈哈,这个日期都是动态生成的,下面就来跟大家分享一下这个的实现方法。

本人是用JAVA EE的后台实现的,

先来贴HTML代码:

技术分享
 1 <div>站点:<input class="easyui-combobox" width="200px" id="stnmCombo">&nbsp; 2 起始时间:<input id="StartTime" class="easyui-datebox"  editable="false" /> 3 &nbsp; 结束时间:<input id="EndTime" class="easyui-datebox" editable="false" /> 4 <a id="btnSearch" href="http://www.mamicode.com/#" class="easyui-linkbutton" data-options="iconCls:‘icon-search‘">查询</a> &nbsp; 5 <a id="export" href="http://www.mamicode.com/#" class="easyui-linkbutton" data-options="iconCls:‘icon-search‘">导出</a>  6 </div> 7  8 <div class="easyui-layout" fit="true"> 9     <table id="dg"></table>10 </div>
View Code

HTML代码非常的简单,其中关键的datagrid只有一个TABLE,其实关键在于JS代码哦

下面就把代码发出来:

我来给大家解释下几个关键的地方以及思路吧,代码不是特别的复杂。

  1. formLoader.load(param1,param2,function(s){})这个方法第一个参数就是controller的RequestMapping的名字,因为是用的MVC三层构架弄的,第二个参数可以是字符串的,也可以是一个JSON对象,此方法返回的是一个JSON对象,如果alert(s)就会看到结果,这个公司框架的一个方法,所以大家不用再找,我只是分享思路。
  2. 本例子主要是后台构造动态列,使用得比较多的是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",                onl oadSuccess: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中去,然后再返回。

如何用easyui+JAVA 实现动态拼凑datagrid表格