行轉列的三種實現方式


上次項目中,碰到了需要將取出的數據進行行轉列的操作,然后顯示出來的問題,當時是吧這個問題交給了前端小姐姐,麻煩她來處理了,但是后來抽空自己研究了一下,發現其實有三種實現方式,下面直接上代碼一一說明,以供參考

(一)、直接在SQL語句里面轉,返回經過轉換,想要的數據格式

                         這里推薦一位大神的(很詳細)

(二)、取出原數據后,傳到前端用JS轉——筆者這種轉的想法來自基於行列式的轉置矩陣的實現原理(是不是后悔大學沒好好學哈0.0)

這里方便大家看懂,多嘮叨幾句,這是需要進行轉換的表格數據

下面是實現行轉列的主要JS代碼:

//點擊按鈕實現行列轉換
    $('#changeBtn').on('click', function(e) {
        
        //先把原表格的內容存進數組set(有種簡單的,吧表頭的th標簽全部改成td,但表頭的字體會失去樣式)
        var set = [];
        $('table tr').each(function() {
            var row = [];
            
            $(this).find('th').each(function() {
                row.push($(this).text());
            });
            
            $(this).find('td').each(function() {
                row.push($(this).text());
            });
            
            set.push(row);
        });
        
        //$("#testDiv").after("一行二列:"+set[0][1]);
        //$("#testDiv").after("二行五列:"+set[1][4]);
        var seted = [];
        //確定新數組有多少行
        for(var i=0;i<set[1].length;i++){
         seted[i] = [];
        }
        //遍歷原數組,動態添加數據(並實現行列轉換)
        for(var i=0;i<set.length;i++){
            
            for(var j=0;j<set[i].length;j++){
                seted[j][i] = set[i][j];
            }
            
        }
        
        //把轉換后的新數組的內容,顯示出來
        var reShow = "<table class='table table-striped table-bordered dt-responsive nowrap order-column'><tbody>";
        $.each(seted, function(index, itr){
            reShow += "<tr>";
            
            $.each(itr, function(index, itd){
                reShow += '<td>'+itd+'</td>';
            })
            
            reShow += "</tr>";
        })
        reShow += "</tbody></table>";
        
        $("#testDiv").after(reShow);
    });

下面是主要的HTML代碼,有強迫症的小伙伴可以參考下:

<table id="datatable" class="table table-striped table-bordered dt-responsive nowrap order-column" cellspacing="0" width="100%">
                      <thead>
                        <tr>
                          <th>網站</th>
                          <th></th>
                          <th></th>
                          <th></th>
                          <th>端口</th>
                          <th>登陸人數</th>
                          <th>在線時長</th>
                          <th>活躍點數</th>
                          <th>獲取經驗</th>
                          <th>水晶消費</th>
                          <th>充值人數</th>
                        </tr>
                      </thead>
                      <tbody>
                          <#list initData as app>
                          <tr data-id='666'>
                          <td>${app.webName}</td>
                          <td>${app.year}</td>
                          <td>${app.month}</td>
                          <td>${app.week}</td>
                          <td>${app.portName}</td>
                          <td>${app.loginNum}</td>
                          <td>${app.onlineTime}</td>
                          <td>${app.activePoint}</td>
                          <td>${app.addExp}</td>
                          <td>${app.consume}</td>
                          <td>${app.recharge}</td>
                        </tr>
                        </#list>
                      </tbody>
                    </table>
                    
                    <!-- <table id="testTable" class="table table-striped table-bordered dt-responsive nowrap order-column" cellspacing="0" width="100%">
                      <thead id="testThead">
                      </thead>
                      <tbody id="testTbody">
                      </tbody>
                    </table> -->
                    
                    <div class="row"><button class="btn btn-default closed" id="changeBtn">行列轉換</button></div>
                    <div class="x_panel">測試DIV
                    <div id="testDiv"></div>
                    </div>
HTML Code

最后,附上轉換后的圖

(三)、原數據取出后,在后台進行轉換(也是最合理的一種方式,但具體問題具體分析)

下面的方式,筆者以封裝好了在一個main()函數里,可以直接copy過去,查看效果,不過記得導入相應的包

public class Row2Line {

    public static void main(String[] args) throws IntrospectionException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {  
        //你提供的對象列表,需要轉換的原數據 
        List<StudentGrand> StudentGrandList = getStudentGrandList();  
        //實現行轉列的算法
        List<List<String>> convertedTable = convert(StudentGrandList);
        //打印轉換后的集合,查看結果
        print(convertedTable);  
        //剩下的可以根據實際需求,將轉換好的集合傳給前端、或隨意處理
    }  
  
    private static List<List<String>> convert(List<StudentGrand> StudentGrandList)  
            throws IntrospectionException, IllegalAccessException, InvocationTargetException {//取得StudentGrand的屬性,當然你也可以用list = {"id", "name", ...}  
        Field[] declaredFields = StudentGrand.class.getDeclaredFields();
          
        List<List<String>> convertedTable = new ArrayList<List<String>>();  
          
        //多少個屬性表示多少行,遍歷行  
        for (Field field : declaredFields) {
            field.setAccessible(true);  
            ArrayList<String> rowLine = new ArrayList<String>();
            //list<T>多少個StudentGrand實體類表示有多少列,遍歷列
            for (int i = 0, size = StudentGrandList.size(); i < size; i++) {
                //每一行的第一列對應StudentGrand字段名  
                //所以新table的第一列要設置為字段名
                if(i == 0){  
                    rowLine.add(field.getName());  
                }  
                //新table從第二列開始,某一列的某個值對應舊table第一列的某個字段
                else{  
                    StudentGrand StudentGrand = StudentGrandList.get(i);  
                    String val = (String) field.get(StudentGrand);//grand為int會報錯
                    System.out.println(val);
                    rowLine.add(val);  
                }  
            }  
            convertedTable.add(rowLine);  
        }  
        return convertedTable;  
    }
    //測試用數據,實際應該從數據庫查詢,傳過來的
    private static List<StudentGrand> getStudentGrandList () {  
        List<StudentGrand> list = new ArrayList<StudentGrand>();
        list.add(new StudentGrand("001", "toni", "語文", "98"));
        list.add(new StudentGrand("001", "toni", "數學", "98"));
        list.add(new StudentGrand("001", "toni", "外語", "98"));
        list.add(new StudentGrand("001", "toni", "體育", "98"));
        list.add(new StudentGrand("006", "amy", "語文", "98"));
        list.add(new StudentGrand("006", "amy", "數學", "98"));
        list.add(new StudentGrand("006", "amy", "外語", "98"));
        list.add(new StudentGrand("006", "amy", "體育", "98"));
        list.add(new StudentGrand("003", "安東尼", "語文", "98"));
        list.add(new StudentGrand("003", "安東尼", "數學", "98"));
        list.add(new StudentGrand("003", "安東尼", "外語", "98"));
        list.add(new StudentGrand("003", "安東尼", "體育", "98"));
        return list;  
    }  
    //打印查看結果
    private static void print(List<List<String>> convertedTable) {
        //String json = JSONArray.formObject(convertedTable).toString();
        for (List<String> list : convertedTable) { 
            for (String string : list) {
                System.out.print(string+"  ");  
            }  
            System.out.println();  
        }  
    }  
}

這里結果是控制台打印出來的(想想還是附上截圖吧)

下面是自定義的學生成績實體類

public class StudentGrand {
    
    private String id;
    
    private String name;
    
    private String subject;
    
    private String grang;

  //get和set方法,main()中的構造方法這里省略了
}

 

最后,針對第三種實現方式,目前行轉列的字段必須都是String類型的,這點如何兼容其他數據類型,比如上面例子中,學生成績應該是int字段才更合理,忘高手不吝賜教

 

 

 

(昨天RNG2:3惜敗SKT、今天WE1:3輸SSG,特此記錄!)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM