datatables 合并单元格(rowspan)

目前在项目中我们用到的是datatable插件。在官网中有一定的例子介绍的是复杂的合并表头。并没有具体的说怎么去动态的合并tbody下的单元格

查阅资料有一下几种,统计几篇可行的文章先做记录,再行研究 防止原博主博文删除:

第一种:

DataTables实现rowspan思路

<table id="example" class="display table table-bordered" cellspacing="0" width="600" style="margin-top: 50px">
    <thead>
    <tr>
        <th>Name</th>
        <th>Position</th>
        <th>Age</th>
    </tr>
    </thead>
</table>
var dataSet = [
        [ "Tiger Nixon",  "Edinburgh",20,1  ],
        [ "Garrett Winters", "Tokyo",22,2],
        [ "Ashton Cox", "Tokyo",21,0 ]
            ];

    $('#example').DataTable({
        data: dataSet,
        paging: true,
        searching:false, //搜索栏
        lengthChange : false, //是否允许改变每页显示的数据条数
        ordering:false,
        columnDefs: [{
            targets: 1,
            createdCell: function (td, cellData, rowData, row, col) {
                var rowspan = rowData[3];
                if (rowspan > 1) {
                    $(td).attr('rowspan', rowspan)
                }
                if (rowspan == 0) {
                    $(td).remove();
                }
            }
        }]
    });

说明一下:要实现rowspan/colspan这样的特殊效果需要用到createdCell回调函数,此函数可配置在columns配置中,亦可配置在columnDefs中,此例采用columnDefs配置实现。具体原理是,在创建单元格cell的是否控制怎样渲染,后台需要定义好rowspan的值,这个需要后台想办法给出这个值。

后台给出rowspan的思路:

将需要分组的属性构造Map<key,count> map,遍历list得到map,再遍历list设置rowspan=map.get(key),get过的key设置0再get, OK,  搞定

具体实现:

http://www.cnblogs.com/hdwang/p/7169255.html

效果图如上。

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 分页参数对象

/**
 * Created by hdwang on 2017/6/22.
 * 分页参数
 */
public class PageParam {

    /**
     * 第几次绘画(前端标识)
     */
    private int draw;

    /**
     * 起始记录(从0开始),mysql也是从0开始,吻合,good!
     */
    private int start;

    /**
     * 页大小
     */
    private int length;

    public int getDraw() {
        return draw;
    }

    public void setDraw(int draw) {
        this.draw = draw;
    }

    public int getStart() {
        return start;
    }

    public void setStart(int start) {
        this.start = start;
    }

    public int getLength() {
        return length;
    }

    public void setLength(int length) {
        this.length = length;
    }

    /**
     * 第几页(0-n)
     */
    public int getPage(){
        return this.start/this.length;
    }
}

3.2 数据返回对象

import java.util.List;

/**
 * Created by hdwang on 2017/6/22.
 * 表格数据(datatables)
 */
public class TableData<T> {

    /**
     * 第几次绘画(前端标识)
     */
    private int draw;

    /**
     * 行过滤(不知道干嘛的)
     */
    private int recordsFiltered;

    /**
     * 总行数
     */
    private int recordsTotal;

    /**
     * 行数据
     */
    private List<T> data;

    /**
     * 起始记录(用于前端初始化序列号用的)
     */
    private int start;

    /**
     *  错误信息
     */
    private String error;

    public int getDraw() {
        return draw;
    }

    public void setDraw(int draw) {
        this.draw = draw;
    }

    public int getRecordsFiltered() {
        return recordsFiltered;
    }

    public void setRecordsFiltered(int recordsFiltered) {
        this.recordsFiltered = recordsFiltered;
    }

    public int getRecordsTotal() {
        return recordsTotal;
    }

    public void setRecordsTotal(int recordsTotal) {
        this.recordsTotal = recordsTotal;
    }

    public List<T> getData() {
        return data;
    }

    public void setData(List<T> data) {
        this.data = data;
    }

    public int getStart() {
        return start;
    }

    public void setStart(int start) {
        this.start = start;
    }

    public String getError() {
        return error;
    }

    public void setError(String error) {
        this.error = error;
    }
}

3.3 数据实体对象

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.4 导出相关类

/**
 * Created by hdwang on 2017/7/14.
 */
public class ExcelData {
    private String value;//单元格的值
    private int colSpan = 1;//单元格跨几列
    private int rowSpan = 1;//单元格跨几行
    private boolean alignCenter;//单元格是否居中,默认不居中,如果选择是,则水平和上下都居中
    public boolean isAlignCenter() {
        return alignCenter;
    }
    public void setAlignCenter(boolean alignCenter) {
        this.alignCenter = alignCenter;
    }
    public String getValue() {
        return value;
    }
    public void setValue(String value) {
        this.value = value;
    }
    public int getColSpan() {
        return colSpan;
    }
    public void setColSpan(int colSpan) {
        this.colSpan = colSpan;
    }
    public int getRowSpan() {
        return rowSpan;
    }
    public void setRowSpan(int rowSpan) {
        this.rowSpan = rowSpan;
    }
}
package com.xincheng.cpm.common;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFFont;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.util.List;

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


    /**
     * 生成excel工作簿
     * @param sheetTitle sheet名称
     * @param titles 标题
     * @param rows 行数据
     * @return 工作簿
     */
    public XSSFWorkbook execute(String sheetTitle,String[] titles,List<List<ExcelData>> rows) {
        //定义工作簿
        XSSFWorkbook workbook = new XSSFWorkbook();

        //th样式
        CellStyle titleStyle = workbook.createCellStyle();
        titleStyle.setBorderBottom((short) 1);
        titleStyle.setBorderRight((short)1);
        titleStyle.setBorderLeft((short)1);
        titleStyle.setBorderTop((short)1);
        titleStyle.setVerticalAlignment((short)1);
        titleStyle.setAlignment((short)2);
        XSSFFont font = workbook.createFont();
        font.setBold(true);
        titleStyle.setFont(font);
        //td样式
        CellStyle style = workbook.createCellStyle();
        style.setBorderBottom((short)1);
        style.setBorderRight((short)1);
        style.setBorderLeft((short)1);
        style.setBorderTop((short)1);
        style.setVerticalAlignment((short)1);

        //创建工作表
        XSSFSheet sheet = workbook.createSheet(sheetTitle);
        sheet.setDefaultRowHeightInPoints(20.0F);

        //创建标题行
        XSSFRow titleRow = sheet.createRow(0);


        for(int col=0;col<titles.length;col++) { //遍历列
            Cell cell = titleRow.createCell(col);
            cell.setCellStyle(titleStyle);
            cell.setCellValue(titles[col]);

            for(int row=0;row<rows.size();row++){ //遍历行
                int rowIndex = row+1;
                XSSFRow contentRow = sheet.getRow(rowIndex);
                if(contentRow == null){
                    contentRow = sheet.createRow(rowIndex);
                }
                ExcelData data = rows.get(row).get(col);
                Cell contentRowCell = contentRow.createCell(col);
                contentRowCell.setCellStyle(style);
                contentRowCell.setCellValue(data.getValue());
                //合并单元格
                if (data.getColSpan() > 1 || data.getRowSpan() > 1) {
                    CellRangeAddress cra = new CellRangeAddress(rowIndex, rowIndex + data.getRowSpan() - 1, col, col + data.getColSpan() - 1);
                    sheet.addMergedRegion(cra);
                }
            }
        }

        return workbook;
    }
}

3.5 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";
    }


    @RequestMapping(value="/query",method= RequestMethod.POST)
    @ResponseBody
    public TableData<Member> getUserByPage(PageParam pageParam, User user){
        Page<Member> userPage = this.getMembers(pageParam);
        TableData<Member> datas = new TableData<>();
        datas.setDraw(pageParam.getDraw());
        datas.setStart(pageParam.getStart());
        datas.setData(userPage.getContent());
        datas.setRecordsFiltered((int)userPage.getTotalElements());
        datas.setRecordsTotal((int)userPage.getTotalElements());
        return datas;
    }

    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;
    }


    @RequestMapping("/export")
    public void export(HttpServletResponse response) throws IOException {
        List<Member> members = this.getMembersFromDb();
        this.countRowspan(members);

        List<List<ExcelData>> rows = new ArrayList<>();
        for(Member member:members){
            List<ExcelData> row = new ArrayList<>();
            ExcelData col1 = new ExcelData();
            col1.setValue(member.getArea());
            col1.setRowSpan(member.getAreaRowSpan());
            row.add(col1);

            ExcelData col2 = new ExcelData();
            col2.setValue(member.getCompany());
            col2.setRowSpan(member.getCompanyRowSpan());
            row.add(col2);

            ExcelData col3 = new ExcelData();
            col3.setValue(member.getDepartment());
            col3.setRowSpan(member.getDepartmentRowSpan());
            row.add(col3);

            ExcelData col4 = new ExcelData();
            col4.setValue(member.getUserName());
            row.add(col4);

            rows.add(row);
        }

        OutputStream outputStream = response.getOutputStream();
        try {
            String filename = URLEncoder.encode("员工" + ".xlsx", "UTF-8");
            response.setContentType("application/vnd.ms-excel");
            response.addHeader("Content-Disposition", "octet-stream;filename=" + filename);

            ExcelUtil excelUtil = new ExcelUtil();
            XSSFWorkbook workbook = excelUtil.execute("sheet1",new String[]{"地区","公司","部门","员工姓名"},rows);
            workbook.write(outputStream);
        } finally {
            if (outputStream != null) outputStream.close();
        }
    }




}

导出excel功能使用poi类库实现。至此,页面展示和导出均OK!

以上参考链接:https://www.cnblogs.com/hdwang/p/7115835.html

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

https://blog.csdn.net/u011974797/article/details/77983645

 

第二种:(第二篇文章)

原文地址:https://github.com/ssy341/datatables-cn/issues/211#issuecomment-372928301

"drawCallback": function (settings) {//
                    var api = this.api();
                    var rows = api.rows({ page: 'current' }).nodes();
 
 
                    // console.log('idx = ' + rows[0].cells.length);
 
 
                    var idx = 0;    // 第一列进行合并
                    var last = null;
                    var tr = null;
                    var ltd = null;
 
 
                    api.column(idx, { page: 'current' }).data().each(function (group, i) {
                        tr = $(rows[i]);
                        var td = $("td:eq(" + idx + ")", tr);
                        if (last !== group) {
                            td.attr("rowspan", 1);
                            td.text(group);
                            ltd = td;
                            last = group;
                            td.css("vertical-align", "middle");
                        } else {
                            ltd.attr("rowspan", parseInt(ltd.attr("rowspan")) + 1);
                            td.remove();
                        }
                    });
                    idx = 1//稍微修改了一下。根据项目需要完成第一列和第二列前五行的单元格合并
                    last = null;
                    tr = null;
                    ltd = null;
                    api.column(idx, { page: 'current' }).data().each(function (group, i) {
                        tr = $(rows[i]);
                        var td = $("td:eq(" + idx + ")", tr);
                        if (last !== group) {
                            td.attr("rowspan", 1);
                            td.text(group);
                            ltd = td;
                            last = group;
                            td.css("vertical-align", "middle");
                            idx = 0;
                        } else {
                            ltd.attr("rowspan", parseInt(ltd.attr("rowspan")) + 1);
                            td.remove();
                            if (parseInt(ltd.attr("rowspan")) === 5) {
                                idx = 1;//第二个五行
                            }
                        }
                    });
                },

第三种(篇):datatables 多列 行合并

原文地址:https://www.jianshu.com/p/ff094dc360f4

1、行合并想要的样式如下,需要合并4列的行,如下图(数据为模拟数据,如有雷同,纯属人品爆发)

 

##controller代码:

// 计算计划类型的合并的planRowSpan

int tiefaRowSpan = Integer.parseInt(String.valueOf(statisticsTieFaConList.size()));

int tiedaoRowSpan = Integer.parseInt(String.valueOf(statisticsTieDaoConList.size()));

// 客户所在位置下标

int logFlag = 0;

// 客户名称1,是判断标准

String logName1 = "";

// 客户名称2,随着循环变化

String logName2 = "";

// 客户的合并的行数

int logRowSpan = 1;

// 供应商所在位置下标

int supFlag = 0;

// 供应商名称1,是判断标准

String supName1 = "";

// 供应商名称2,随着循环变化

String supName2 = "";

// 供应商的合并的行数

int supRowSpan = 1;

// 货票号所在位置下标

int cargoFlag = 0;

// 货票号1,是判断标准

String cargoName1 = "";

// 货票号2,随着循环变化

String cargoName2 = "";

// 货票号的合并的行数

int cargoRowSpan = 1;

// 计算行的合并的rowspan的值 1、planRowSpan:计划类型,2、logRowSpan:客户公司,3、supRowSpan:运输公司,4、cargoRowSpan:货票号

for (int i=0; i < resultList.size(); i++) {

// 因为铁发和铁到是按照类别分开的,所以按照铁发的数量进行判断的分割

if (i == 0) {

resultList.get(i).put("planRowSpan", tiefaRowSpan);

logFlag = i;

logName1 = String.valueOf(resultList.get(i).get("logCompany"));

supFlag = i;

supName1 = String.valueOf(resultList.get(i).get("supCompany"));

cargoFlag = i;

cargoName1 = String.valueOf(resultList.get(i).get("cargobillCode"));

} else if (i < tiefaRowSpan){

resultList.get(i).put("planRowSpan", 0);

} else if (i == tiefaRowSpan) {

resultList.get(i).put("planRowSpan", tiedaoRowSpan);

resultList.get(supFlag).put("supRowSpan", supRowSpan);

resultList.get(cargoFlag).put("cargoRowSpan", cargoRowSpan);

supFlag = i;

supName1 = String.valueOf(resultList.get(i).get("supCompany"));

cargoFlag = i;

cargoName1 = String.valueOf(resultList.get(i).get("cargobillCode"));

} else if (i > tiefaRowSpan) {

resultList.get(i).put("planRowSpan", 0);

}

// 取物流商的名称进行对比

if (i != 0 && i != tiefaRowSpan) {

logName2 = String.valueOf(resultList.get(i).get("logCompany"));

supName2 = String.valueOf(resultList.get(i).get("supCompany"));

cargoName2 = String.valueOf(resultList.get(i).get("cargobillCode"));

if (logName1.equals(logName2)) {

logRowSpan = logRowSpan + 1;

resultList.get(i).put("logRowSpan", 0);

if (supName1.equals(supName2)) {

supRowSpan = supRowSpan + 1;

resultList.get(i).put("supRowSpan", 0);

if (cargoName1.equals(cargoName2)) {

cargoRowSpan = cargoRowSpan + 1;

resultList.get(i).put("cargoRowSpan", 0);

} else {

resultList.get(cargoFlag).put("cargoRowSpan", cargoRowSpan);

cargoFlag = i;

cargoRowSpan = 1;

cargoName1 = String.valueOf(resultList.get(i).get("cargobillCode"));

cargoName2 = "";

}

} else {

resultList.get(supFlag).put("supRowSpan", supRowSpan);

supFlag = i;

supRowSpan = 1;

supName1 = String.valueOf(resultList.get(i).get("supCompany"));

supName2 = "";

resultList.get(cargoFlag).put("cargoRowSpan", cargoRowSpan);

cargoFlag = i;

cargoRowSpan = 1;

cargoName1 = String.valueOf(resultList.get(i).get("cargobillCode"));

cargoName2 = "";

}

} else {

resultList.get(logFlag).put("logRowSpan", logRowSpan);

logFlag = i;

logRowSpan = 1;

logName1 = String.valueOf(resultList.get(i).get("logCompany"));

logName2 = "";

resultList.get(supFlag).put("supRowSpan", supRowSpan);

supFlag = i;

supRowSpan = 1;

supName1 = String.valueOf(resultList.get(i).get("supCompany"));

supName2 = "";

resultList.get(cargoFlag).put("cargoRowSpan", cargoRowSpan);

cargoFlag = i;

cargoRowSpan = 1;

cargoName1 = String.valueOf(resultList.get(i).get("cargobillCode"));

cargoName2 = "";

}

} else if (i == tiefaRowSpan) {

resultList.get(logFlag).put("logRowSpan", logRowSpan);

logFlag = i;

logRowSpan = 1;

logName1 = String.valueOf(resultList.get(i).get("logCompany"));

logName2 = "";

resultList.get(supFlag).put("supRowSpan", supRowSpan);

supFlag = i;

supRowSpan = 1;

supName1 = String.valueOf(resultList.get(i).get("supCompany"));

supName2 = "";

resultList.get(cargoFlag).put("cargoRowSpan", cargoRowSpan);

cargoFlag = i;

cargoRowSpan = 1;

cargoName1 = String.valueOf(resultList.get(i).get("cargobillCode"));

cargoName2 = "";

}

}

resultList.get(logFlag).put("logRowSpan", logRowSpan);

resultList.get(supFlag).put("supRowSpan", supRowSpan);

resultList.get(cargoFlag).put("cargoRowSpan", cargoRowSpan);



##js代码:



"ordering" : false,

// 按照最新下发的订单,订单编码是升序的排列顺序

// order: [[ 5, "desc" ]],

columnDefs: [{

targets: [0,1,2,3], //第1,2,3列

createdCell: function (td, cellData, rowData, row, col) {

var rowspan = 1;

if(col == 0){

rowspan = rowData.planRowSpan;

}

if(col == 1){

rowspan = rowData.logRowSpan;

}

if(col == 2){

rowspan = rowData.supRowSpan;

}

if(col == 3){

rowspan = rowData.cargoRowSpan;

}

if (rowspan > 1) {

$(td).attr('rowspan', rowspan)

}

if (rowspan == 0) {

$(td).remove();

}

}

}],

第四篇文章 datatables 分多行  合并单元格:http://blog.sina.com.cn/s/blog_b92442710102wfhu.html

function Deployment_map_DataTable2() {    //datatables的数据请求
    //重绘
    if ( $.fn.dataTable.isDataTable( '#Deployment_point_datatables1bottom' ) ) {
       var table1 = $('#Deployment_point_datatables1bottom').DataTable();
       table1.destroy();
      $('#Deployment_point_datatables1bottom').empty();
       $('#Deployment_point_datatables1bottom').after(' ');
       console.log(3);
    }
    //重绘
    if ( $.fn.dataTable.isDataTable( '#Deployment_point_datatables2bottom' ) ) {
       var table2 = $('#Deployment_point_datatables2bottom').DataTable();
       table2.destroy();
      $('#Deployment_point_datatables2bottom').empty();
       console.log(4);
    }
    var dataSet=[
       ['2','东小口镇','256','大望村','300'],
       ['2','东小口镇','256','大望村','300'],
       ['2','东小口镇','256','大望村','300'],
       ['3','东小口镇','256','大望村','300'],
       ['3','东小口镇','256','大望村','300'],
       ['3','东小口镇','256','大望村','300'],
    ]
    var t = $('#Deployment_point_datatables2bottom').DataTable( {
          "bAutoWidth":false,
          "processing": true,
          "bProcessing": true,
          "searching":false,
          "oLanguage" :{
                 "sLengthMenu": "每页显示 _MENU_ 条",
                 "sZeroRecords": "抱歉, 没有找到",
                 "sInfo": "从 _START_ 到 _END_ /共 _TOTAL_ 条数据",
                 "sInfoEmpty": "没有数据",
                 "sInfoFiltered": "(从 _MAX_ 条数据中检索)",
                 "sZeroRecords": "没有检索到数据",
                  "sSearch": "搜索",
                 "oPaginate": {
                 "sFirst": "首页",
                 "sPrevious": "前一页",
                 "sNext": "后一页",
                 "sLast": "尾页"
            }
         },
          "scrollY": "300px",
         "scrollCollapse": "true",
          "paging": "false",
         "lengthMenu": [[10, 25, 50, -1], [10, 25, 50, "All"]],
          "data": dataSet,
          rowsGroup: [
              0,
              1,
              2
           ],
           "columns": [
              { "title": "排名" },
              { "title": "名称" },
              { "title": "PM2.5" },
              { "title": "区域监点" },
              { "title": "PM2.5" }
           ]
       } );
};

第五篇:

我的需求与这种相似 都需要多列的单元格合并 并且比这种稍微复杂 一列合并一个单元格后还得分两列

 

然后贴上代码吧。

首先是模拟的数据。

var  returnData=[
    {id:"item_1",name:"财务管理流程",comp:"支付管理",Pjtime:"2015年-2017年",Tjtime:"2017-10-15",main:"1.获取测试期间内付款申请样本、月度资金计划及合同等支持性文件;2.检查付款申请事项是否在月度资金计划内",mode:"控制测试",choose:"是",proof:"查看",details:"查看",merge:3,imerge:1},
    {id:"item_2",name:"财务管理流程",comp:"支付管理",Pjtime:"2015年-2017年",Tjtime:"2017-10-15",main:"检查付款信息是否正确,主要包括:收款单位名称、申请支付金额和支付摘要等;",mode:"控制测试",choose:"否",proof:"查看",details:"查看",merge:0,imerge:2},
    {id:"item_3",name:"财务管理流程",comp:"支付管理",Pjtime:"2015年-2017年",Tjtime:"2017-10-15",main:"1.获取测试期间内付款申请样本、月度资金计划及合同等支持性文件;2.检查付款申请事项是否在月度资金计划内",mode:"控制测试",choose:"是",proof:"查看",details:"查看",merge:0,imerge:0},
    {id:"item_4",name:"财务管理流程",comp:"支付管理",Pjtime:"2015年-2017年",Tjtime:"2017-10-15",main:"检查付款信息是否正确,主要包括:收款单位名称、申请支付金额和支付摘要等;",mode:"控制测试",choose:"是",proof:"查看",details:"查看",merge:3,imerge:1},
    {id:"item_5",name:"财务管理流程",comp:"支付管理",Pjtime:"2015年-2017年",Tjtime:"2017-10-15",main:"检查付款信息是否正确,主要包括:收款单位名称、申请支付金额和支付摘要等;",mode:"控制测试",choose:"是",proof:"查看",details:"查看",merge:0,imerge:2},
    {id:"item_6",name:"财务管理流程",comp:"支付管理",Pjtime:"2015年-2017年",Tjtime:"2017-10-15",main:"检查付款信息是否正确,主要包括:收款单位名称、申请支付金额和支付摘要等;",mode:"控制测试",choose:"是",proof:"查看",details:"查看",merge:0,imerge:0}
];$('#lx_namePj_table').dataTable(    data: returnData, //模拟的数据

    sDom: '"top"i',
    pageLength: 6,//每页显示的条数
    autoWidth: false,
    destroy: true,
    info: true,
    scrollX:true, //横向滚动条
    columns: [
        {"data": null,     title: "序号",     "width": "8%"},
        {"data": "id",     visible:false},
        {"data": "name", title: "一级流程", "width": "15%"},
        {"data": "comp",   title: "末级流程", "width": "15%"},
        {"data": "Pjtime",title: "控制点编号",   "width": "15%"},
        {"data": "Tjtime",title: "控制点描述",   "width": "15%"},
        {"data": "main",title: "评价要点",   "width": "40%"},
        {"data": "mode",title: "测试方式",   "width": "15%"},
        {"data": "choose",title: "是否存在缺陷",   "width": "15%"},
        {"data": "proof",title: "佐证",   "width": "15%"},
        {"data": "details",title: "缺陷详情",   "width": "15%"}
    ],

    "fnDrawCallback": function () {
        this.api().column(0).nodes().each(function (cell, i) {
            cell.innerHTML = i + 1;
        });
    },
    "columnDefs": [{     //重要的部分
        targets: [2,3], //要合并的列数(第1,2,3列)
        createdCell: function (td, cellData, rowData, row, col) { //重要的操作可以合并列的代码
            var rowspan = rowData.merge;//这里主要是利用了模拟数据中的merge来控制
            if (rowspan > 1) { //这里做的判断。相信大家也能看懂的。
                $(td).attr('rowspan', rowspan)
            }
            if (rowspan == 0) {
                $(td).remove();
            }
        },
        "data": "culture_title",
        "render": function (data, type, full) {
            return "<span title='" + data + "'>" + data + "</span>";
        }
    },{
        targets: [7,8,9,10], //第1,2,3列    //这块是另外一模块的合并。所以是写成了对象的形式。
        createdCell: function (td, cellData, rowData, row, col) { //和上面一样的思想
            var rowspan = rowData.imerge;
            if (rowspan > 1) {
                $(td).attr('rowspan', rowspan)
            }
            if (rowspan == 0) {
                $(td).remove();
            }
        }
    }]

});

最后来说下数据中的merge和imerge代表的意思

merge是第一次要合并的数据值 3.是代表的要合并的行数、如果要合并的话。就在具体的行数上写合并的行数。例如:3.不合并的写1.但在合并的行后边要写上0.也就是不合并的意思。

imerge也是这样的思想。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值