DataTables合并单元格(rowspan)的实现思路(多分组分类的情况)

思路:首先利用DataTables的重构功能,后台计算出td跨多少行


1.先看看效果



2.html代码,含js代码

2.1 common.js

/**
 * Created by hdwang on 2017/6/23.
 */
var language = { "search": "", "sSearch" : "搜索", "sUrl" : "", "sProcessing" : "正在加载数据...", "sLengthMenu" : "显示_MENU_条 ", "sZeroRecords" : "没有您要搜索的内容",
    "sInfo" : "从_START_ 到 _END_ 条记录——总记录数为 _TOTAL_ 条", "sInfoEmpty" : "记录数为0", "sInfoFiltered" : "(全部记录数 _MAX_  条)", "sInfoPostFix" : "",
    "oPaginate": { "sFirst" : "第一页", "sPrevious" : " 上一页 ", "sNext" : " 下一页 ", "sLast" : " 最后一页 " }
};

/**
 * 将参数对象转换成url查询参数
 * @param params 参数对象
 * @returns {string} url查询参数
 */
function getUrlParams(params) {
    var queryStr = '';
    var isFirstParam = true;
    for(var key in params){
        if(isFirstParam){
            queryStr += key + '=' + params[key];
            isFirstParam = false;
        }else{
            queryStr += '&' + key + '=' + params[key];
        }
    }
    return queryStr;
}

2.2 home.ftl

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
    <title>cpm system</title>

    <!-- Bootstrap -->
    <link href="/thirdlib/bootstrap/css/bootstrap.min.css" rel="stylesheet">

    <!-- datatables -->
    <link href="/thirdlib/datatables/css/jquery.dataTables.min.css" rel="stylesheet"/>

    <link href="/css/common.css" rel="stylesheet" />
</head>
<body>


<div id="tableArea" style="padding: 100px;">

<div>
    <a href="/home/export">导出</a>
</div>


    <table id="rowspanTable" class="table table-bordered">
        <thead>
            <th>地区</th>
            <th>公司</th>
            <th>部门</th>
            <th>员工姓名</th>
        </thead>
    </table>

</div>

</body>

<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="/thirdlib/jquery/jquery-2.0.3.min.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="/thirdlib/bootstrap/js/bootstrap.min.js"></script>

<!-- datatables -->
<script src="/thirdlib/datatables/js/jquery.dataTables.min.js"></script>

<script src="/js/common.js"></script>

<script type="text/javascript">
    $(function(){

        $('#rowspanTable').dataTable( {
            "paging": true,
            "processing": true,
            "serverSide": true,
            "searching":false, //搜索栏
            "lengthChange" : false, //是否允许改变每页显示的数据条数
            "pageLength": 10, //每行显示记录数
            "info":true, //开启Datatables信息显示(记录数等)
            "ordering":false, //全局定义是否启用排序,优先级比columns.orderable高
            "language": language,
            "ajax": {
                "url": "/home/query",
                "type": "POST"
            },
            "columns": [
                {"data":"area", "orderable": false,"searchable": false},
                { "data": "company", "orderable": false ,"searchable": false},
                { "data": "department", "orderable": false,"searchable": false },
                { "data": "userName", "orderable": false ,"searchable": false}
            ],
            "columnDefs": [{
                targets: [0,1,2], //第1,2,3列
                createdCell: function (td, cellData, rowData, row, col) {
                    var rowspan = 1;
                    if(col == 0){
                        rowspan = rowData.areaRowSpan;
                    }
                    if(col ==1){
                        rowspan = rowData.companyRowSpan;
                    }
                    if(col ==2){
                        rowspan = rowData.departmentRowSpan;
                    }

                    if (rowspan > 1) {
                        $(td).attr('rowspan', rowspan)
                    }
                    if (rowspan == 0) {
                        $(td).remove();
                    }
                }
            }]
        } );


    });

</script>

</html>


3.后台代码

3.1数据实体对象

package com.xincheng.cpm.common;

import java.io.Serializable;

/**
 * Created by hdwang on 2017/7/14.
 */
public class Member{

    private String area;
    private String company;
    private String department;
    private String userName;

    private Integer areaRowSpan;
    private Integer companyRowSpan;
    private Integer departmentRowSpan;


    public Member(String area,String company,String department,String userName){
        this.area = area;
        this.company = company;
        this.department = department;
        this.userName = userName;
    }

    public String getArea() {
        return area;
    }

    public void setArea(String area) {
        this.area = area;
    }

    public String getCompany() {
        return company;
    }

    public void setCompany(String company) {
        this.company = company;
    }

    public String getDepartment() {
        return department;
    }

    public void setDepartment(String department) {
        this.department = department;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public Integer getAreaRowSpan() {
        return areaRowSpan;
    }

    public void setAreaRowSpan(Integer areaRowSpan) {
        this.areaRowSpan = areaRowSpan;
    }

    public Integer getCompanyRowSpan() {
        return companyRowSpan;
    }

    public void setCompanyRowSpan(Integer companyRowSpan) {
        this.companyRowSpan = companyRowSpan;
    }

    public Integer getDepartmentRowSpan() {
        return departmentRowSpan;
    }

    public void setDepartmentRowSpan(Integer departmentRowSpan) {
        this.departmentRowSpan = departmentRowSpan;
    }
}


3.2 controller层(核心代码

package com.xincheng.cpm.controller;

import com.chenrd.common.excel.ExportExcel;
import com.xincheng.cpm.common.*;
import com.xincheng.cpm.entity.cpm.User;
import com.xincheng.cpm.service.UserService;
import com.xincheng.cpm.vo.IncomeDailyVO;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.*;

/**
 * Created by hdwang on 2017/6/19.
 */
@Controller
@RequestMapping("/home")
public class HomeController {

    @Autowired
    UserService userService;

    @RequestMapping("")
    public String index(HttpSession session, ModelMap map, HttpServletRequest request){
        User user = (User) session.getAttribute("user");
        map.put("user",user);
        return "home";
    }

    private Page<Member> getMembers(PageParam pageParam) {
        //1.模拟数据库查询
        Pageable pageable = new PageRequest(pageParam.getPage(), pageParam.getLength());
        long count = 6;
        List<Member> members = getMembersFromDb();

        //2.计算rowspan
        this.countRowspan(members);


        Page<Member> memberPage = new PageImpl<Member>(members,pageable,count);
        return memberPage;
    }

    private void countRowspan(List<Member> members) {
        Map<String,Integer> propertyCountMap = this.countPropertyCount(members);
        List<String> hadGetKeys = new ArrayList<>(); //曾经取过的key
        for(Member member:members){
            String areaKey = member.getArea();
            String companyKey = areaKey+member.getCompany();
            String departmentKey = companyKey+ member.getDepartment();

            Integer areaCount = propertyCountMap.get(areaKey);
            if(areaCount == null){
                member.setAreaRowSpan(1);
            }else{
                if(hadGetKeys.contains(areaKey)){
                    member.setAreaRowSpan(0); //曾经取过
                }else{
                    member.setAreaRowSpan(areaCount); //第一次取
                    hadGetKeys.add(areaKey);
                }
            }

            Integer companyCount = propertyCountMap.get(companyKey);
            if(companyCount == null){
                member.setCompanyRowSpan(1);
            }else {
                if(hadGetKeys.contains(companyKey)){
                    member.setCompanyRowSpan(0);
                }else{
                    member.setCompanyRowSpan(companyCount);
                    hadGetKeys.add(companyKey);
                }
            }

            Integer departmentCount = propertyCountMap.get(departmentKey);
            if(companyCount == null){
                member.setDepartmentRowSpan(1);
            }else {
                if(hadGetKeys.contains(departmentKey)){
                    member.setDepartmentRowSpan(0);
                }else{
                    member.setDepartmentRowSpan(departmentCount);
                    hadGetKeys.add(departmentKey);
                }
            }
        }
    }

    private List<Member> getMembersFromDb() {
        Member member1 = new Member("安徽","A","人力资源部"," 小红");
        Member member2 = new Member("安徽","B","人力资源部"," 小明");
        Member member3 = new Member("浙江","C","人力资源部"," 小君");
        Member member4 = new Member("浙江","C","技术部"," 小王");
        Member member5 = new Member("浙江","D","技术部"," 小李");
        Member member6 = new Member("浙江","D","人力资源部"," 小刚");
        List<Member> members = new ArrayList<>();
        members.add(member1);
        members.add(member2);
        members.add(member3);
        members.add(member4);
        members.add(member5);
        members.add(member6);
        return members;
    }

    /**
     * 统计每个字段的每组成员个数
     * @param rows  记录
     * @return 每个字段的每组成员个数
     */
    private Map<String,Integer> countPropertyCount(List<Member> rows){

        Map<String,Integer> propertyCountMap = new HashMap<>();

        for(Member member:rows){
            // "area": 无父级分组
            String area = member.getArea();
            if(propertyCountMap.get(area) == null){
                propertyCountMap.put(area,1);
            }else{
                int count = propertyCountMap.get(area);
                propertyCountMap.put(area,count+1);
            }

            // "company":有area父组
            String company = member.getCompany();
            String uniqueParent = member.getArea();
            String key = uniqueParent + company;
            if(propertyCountMap.get(key) == null){
                propertyCountMap.put(key,1);
            }else{
                int count = propertyCountMap.get(key);
                propertyCountMap.put(key,count+1);
            }

            // "department": 有area,company这两个父组
            String department = member.getDepartment();
            uniqueParent = member.getArea()+member.getCompany();
            key = uniqueParent + department;
            if(propertyCountMap.get(key) == null){
                propertyCountMap.put(key,1);
            }else{
                int count = propertyCountMap.get(key);
                propertyCountMap.put(key,count+1);
            }
        }

        return propertyCountMap;
    }


}

原文:http://www.cnblogs.com/hdwang/p/7169255.html?utm_source=itdadao&utm_medium=referral

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值