酉卒之子

导航

行转列的三种实现方式

上次项目中,碰到了需要将取出的数据进行行转列的操作,然后显示出来的问题,当时是吧这个问题交给了前端小姐姐,麻烦她来处理了,但是后来抽空自己研究了一下,发现其实有三种实现方式,下面直接上代码一一说明,以供参考

(一)、直接在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,特此记录!)

posted on 2017-10-29 23:39  酉卒之子  阅读(19017)  评论(0编辑  收藏  举报