程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> springmvc+easyui實現透視表-動態生成列

springmvc+easyui實現透視表-動態生成列

編輯:C++入門知識

springmvc+easyui實現透視表-動態生成列


項目需求裡面要求實現一個類似於excel裡透視表的功能,大致意思就是選擇對應的數據庫之後,行標簽和列標簽都是可選的,然後在頁面上就生成對應的相關記錄。
例如,我選擇“財務信息”數據庫,列標簽選擇“部門”,行標簽選擇“科目”,頁面上就顯示每個部門在每項科目上的財務信息(這裡就簡單化為支出)。

因為我前台選擇的是easyui框架,一般用於顯示表格都是在datagrid的columns定義filed和title,但是這個需求就無法事先定義好這些屬性,只有在運行時才能裝載這些組件,怎麼辦呢?看了很多網上的信息,發現講的都很模糊,要不就是簡單問題復雜化,要不就是一言帶過,於是就決定自己弄,畢竟看別人的東西只是個啟發。廢話不多說,開始。

難點:
1.前台js動態生成datagrid配置
2.後台json動態裝配

解決辦法:
對於第一個難點,
弄懂核心原理是最重要的,核心就是 重新生成column字符串。意思就是說,原先是前台js事先寫死,但是現在傳一個值過去,格式和原先保持一致就可以了。
既然知道這個原理了,那問題就迎刃而解了,我先調用後台處理方法,再返回對應格式的字符串給前台就行了。即保證前台獲取的json格式如下:

{"total":23,
"rows":[
{"3":0,"2":91940.0,"1":0,"4":50000.0,"detailSubject":"01.1 購置設備費"},
{"3":36000.0,"2":0,"1":80000.0,"4":0,"detailSubject":"01.2 研制設備費"}],
"columns":[[{"field":"detailSubject","width":100,"title":"明細科目"},
{"field":"1","width":100,"title":"D0 材料部"},
{"field":"2","width":100,"title":"D1 工程部"},
{"field":"3","width":100,"title":"D2 軟件部"},
{"field":"4","width":100,"title":"D3 物理部"}]]
}

下面是實現的兩種前台的寫法:
第一種前台寫法:
$(function(){
        //初始化
        $("#pivotTable_datagrid").datagrid({
            type: 'POST',
            pagination:true,
            rownumbers:true,
            fit:true,
            width:1024,  
            height:500,  
            nowrap: false,
            border: false,
            pageSize:10,
            singleSelect:true
        });    
        loadDatagrid();
    });

    function loadDatagrid() {
        $.ajax({
             url: path+'/pivotTable/datagrid',
             type:"POST",  
             success: function(data){
                var options = $("#pivotTable_datagrid").datagrid("options"); //取出當前datagrid的配置     
                var json = decodeURIComponent(data.columns);//解碼
                console.info(json);
                options.columns = eval(json);
                 $('#pivotTable_datagrid').datagrid(options);
                $('#pivotTable_datagrid').datagrid("loadData", data.rows);//實例化之後立刻載入數據源,加載本地數據,舊的行會被移除。
             }
        });
    }

這一種方法主要是把後台傳過來的column對應的json數組通過options賦給datagrid的column屬性,然後再重新.datagrid(),這個方法有個缺陷,就是沒法實現刷新。
因為項目工期比較緊,我就沒有仔細研究為什麼會這樣。下面介紹下另一種寫法,其實原理還是一樣的,從後台獲取column的json配置:
 /**
     * 生成透視表,
     */
    function create() {
        var database = $('#pivotTable_searchForm input[name=database]').val();
        var colTag = $('#pivotTable_searchForm input[name=colTag]').val();
        var rowTag = $('#pivotTable_searchForm input[name=rowTag]').val();
        console.info(database);
        if (database.trim() == "") {
            $.messager.alert('提示', '請先選擇數據源!', 'info');
        }else if(colTag.trim() == "" && rowTag.trim() == ""){
            $.messager.alert('提示', '請至少選擇一個行標簽或者列標簽!', 'info');
        }else if(colTag.trim() == rowTag.trim()){
            $.messager.alert('提示', '親,行標簽和列標簽不能一樣哦!', 'info');
        }else{
            console.info(database);
            console.info(colTag);
            console.info(rowTag);
            var url = path+'/pivotTable/datagrid?database='+database
                +'&colTag='+colTag+'&rowTag='+rowTag;
            $.ajax({
                url : url,
                dateType : 'json',
                type : 'post',
                success : function(r) {
                    console.info(r.columns);
                    $('#pivotTable_datagrid').datagrid({
                        url : url,
                        fit : true,
                        border : false,
                        pagination : true,
                        rownumbers : true,
                        fitColumns : true,
                        columns : r.columns   //這裡提取後台傳過來的json數組裡的columns數據,
                    });
                }
            });
        }
    }

這樣第一個難點就解決了,只要後台傳過來的json格式正確,前台就能顯示對應的界面。那麼問題來了,學挖掘機技術哪家強?好吧,開個玩笑^_^

第二個難點,我怎麼在後台生成動態的column的json?(因為筆者是用java的springmvc寫的,所以可能下面方法只適合javaer)
很簡單,如果實體類的屬性知道,就一個通過java反射獲取,填充到column的field的屬性裡。先看代碼:
後台:

    /**
     * 生成透視表
     * @return
     */
    @ResponseBody
    @RequestMapping("/pivotTable/datagrid"){
        DataGrid dg = new DataGrid();            //這個是用於向前台傳送整個json數據的實體bean
        PageHelper page = new PageHelper();        //用於後台分頁的
        
        List columnList = new ArrayList();
        Map column = new HashMap();
        column.put("applyDate", "日期");
        column.put("proBriefName", "項目簡稱");
        column.put("activityCode", "財務計劃編號");
        column.put("applicant", "申請人");
        column.put("amount", "金額");
        column.put("fundPurpose", "經費用途");
        column.put("loanNo", "借款單號");
        // 獲取實體類的所有屬性,返回Field數組  
        LoanBean t = new LoanBean();
        Field[] field = t.getClass().getDeclaredFields();  
        // 遍歷所有屬性  
        for (int j = 0; j < field.length; j++) {
            DatagridColumn dc = new DatagridColumn();
            // 獲取屬性的名字
            String name = field[j].getName();  
            dc.setField(name);
            dc.setTitle(column.get(name));
            dc.setWidth(80);
            columnList.add(dc);
        }
        String columnJson = JSON.toJSONString(columnList, SerializerFeature.UseSingleQuotes);
        System.out.println("json格式的column為:"+columnJson);
        columnJson = "["+columnJson+"]";
        /*
        //columns需要後台生成
        String columns = "[[";
        columns = columns + "{field:'applyDate',title:'日期',width:80},";
        columns = columns + "{field:'proBriefName',title:'項目簡稱',width:80},";
        columns = columns + "{field:'activityCode',title:'財務計劃編號',width:80},";
        columns = columns + "{field:'applicant',title:'申請人',width:80},";
        columns = columns + "{field:'amount',title:'金額',width:80},";
        columns = columns + "{field:'fundPurpose',title:'經費用途',width:80},";
        columns = columns + "{field:'loanNo',title:'借款單號',width:80}";
        columns = columns + "]]";
        */
        try {
            columnJson = URLEncoder.encode(columnJson,"UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        System.out.println(columnJson);
        //根據條件查詢總數
        Long total = financeService.loanCount(page);
        dg.setTotal(total);
        //根據條件查詢List
        List loanList = financeService.loanList(page);//這裡是重點
        dg.setRows(loanList);
        dg.setColumns(columnJson);
        return dg;
} 

之前都是用實體bean加載記錄數據,再放到datagrid的rows裡面,然後springmvc的jackson自動將其序列化為json數組傳到前台,
但是現在如果實體類的屬性不固定(大多數情況下都是這個),該怎麼辦?我這裡給個思路:
我用了一個ResultBean來加載返回的結果記錄集,這個ResultBean裡有兩個屬性,第一個是記錄的第一列的標題rowTag,第二個屬性就是自第二列之後每一列下的值,因為列數不固定,所以就用了Map data來獲取,後台查出幾個記錄,就put對應的kew,value進去,最後再寫個方法,根據結果集、表頭Title和Field映射Map、行標簽,生成Map類型的rows,這個轉換方法核心就是遍歷map再加載,如下:

   /**
     * 根據結果集、表頭Title和Field映射Map、行標簽,生成Map類型的rows
     * @param rlist
     * @param colMap
     * @param rowTag
     * @return
     */
    public List> getDatagridMap(List rlist,
            Map colMap, String rowTag) {
        List> datagridMap = new ArrayList>();
        for(int i=0;i rMap= new HashMap();
            ResultBean rb = rlist.get(i);
            rMap.put(rowTag, rb.getRowTag());
            //遍歷Map
            Set set1 = rb.getData().keySet();
            Iterator it = set1.iterator();
            while(it.hasNext()){
                String colTitle = it.next();
                if(colMap.containsKey(colTitle)){
                    rMap.put(colMap.get(colTitle), rb.getData().get(colTitle));
                }
            }
            datagridMap.add(rMap);
        }
        return datagridMap;
    }

總之,一句話,原理最重要,後台返回對應的json格式(注意,json格式是最核心的),前台就能生成相應的界面。至於json數據怎麼生成,不同的人有不同的實現方式。哦了!

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved