目前在項目中我們用到的是datatable插件。在官網中有一定的例子介紹的是複雜的合併表頭。並沒有具體的說怎麼去動態的合併tbody下的單元格
查閱資料有一下幾種,統計幾篇可行的文章先做記錄,再行研究 防止原博主博文刪除:
第一種:
<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也是這樣的思想。