上次項目中,碰到了需要將取出的數據進行行轉列的操作,然后顯示出來的問題,當時是吧這個問題交給了前端小姐姐,麻煩她來處理了,但是后來抽空自己研究了一下,發現其實有三種實現方式,下面直接上代碼一一說明,以供參考
(一)、直接在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>
最后,附上轉換后的圖
(三)、原數據取出后,在后台進行轉換(也是最合理的一種方式,但具體問題具體分析)
下面的方式,筆者以封裝好了在一個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,特此記錄!)