HTML:
html
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title></title>
<script src="~/Scripts/jquery-1.6.4.min.js"></script>
<script src="~/Scripts/jquery.table2excel.js?a=@DateTime.Now.ToString("yyyyMMddHHmmssff")"></script>
</head>
<body hidden>
<table id="table" border="1" width="100%">
<thead>
<tr>
<th colspan="14">客户基础信息</th>
<th colspan="10">跟踪维护信息</th>
</tr>
<tr>
<th>客户名称</th>
<th>联系人</th>
<th>联系电话</th>
<th>客户喜好</th>
<th>纪念日/生日</th>
<th>项目标题</th>
<th>项目信息</th>
<th>项目状态</th>
<th>项目等级</th>
<th>核心诉求</th>
<th>诉求应答</th>
<th>预成交金额(万元)</th>
<th>需要的支持</th>
<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 id="tbody">
@if (ViewBag.TrackExport != null)
{
for (int i = 0; i < ViewBag.TrackExport.Count; i++)
{
<tr>
<td>@ViewBag.TrackExport[i].CUSTOMER_NAME </td>
<td>@ViewBag.TrackExport[i].CONTACT_LINK </td>
<td>@ViewBag.TrackExport[i].CONTACT_PHONE </td>
<td>@ViewBag.TrackExport[i].HOBBIES </td>
<td>@ViewBag.TrackExport[i].BIRTHDAY </td>
@* 利用<b>标签包含不同内容进行二次分组,分组后移除<b>标签 *@
<td>@ViewBag.TrackExport[i].PROJECT_TITLE <b>@ViewBag.TrackExport[i].SALES_OPPORTUNITY_PROJECT_SID</b></td>
<td>@ViewBag.TrackExport[i].PROJECT_INFO <b>@ViewBag.TrackExport[i].SALES_OPPORTUNITY_PROJECT_SID</b></td>
<td>@ViewBag.TrackExport[i].PROJECT_STATUS_NAME <b>@ViewBag.TrackExport[i].SALES_OPPORTUNITY_PROJECT_SID</b></td>
<td>@ViewBag.TrackExport[i].PROJECT_LEVEL_NAME <b>@ViewBag.TrackExport[i].SALES_OPPORTUNITY_PROJECT_SID</b></td>
<td>@ViewBag.TrackExport[i].NEEDS <b>@ViewBag.TrackExport[i].SALES_OPPORTUNITY_PROJECT_SID</b></td>
<td>@ViewBag.TrackExport[i].RESPONSE <b>@ViewBag.TrackExport[i].SALES_OPPORTUNITY_PROJECT_SID</b></td>
<td>@ViewBag.TrackExport[i].EST_AMOUNT <b>@ViewBag.TrackExport[i].SALES_OPPORTUNITY_PROJECT_SID</b></td>
<td>@ViewBag.TrackExport[i].NEED_SUPPORT <b>@ViewBag.TrackExport[i].SALES_OPPORTUNITY_PROJECT_SID</b></td>
<td>@ViewBag.TrackExport[i].REMARKS <b>@ViewBag.TrackExport[i].SALES_OPPORTUNITY_PROJECT_SID</b></td>
<td>@ViewBag.TrackExport[i].FIRST_MANAGE_DATE </td>
<td>@ViewBag.TrackExport[i].LAST_MANAGE_DATE </td>
<td>@ViewBag.TrackExport[i].SINCE_DAYS </td>
<td>@ViewBag.TrackExport[i].MANAGE_DATE.ToString("yyyy-MM-dd") </td>
<td>@ViewBag.TrackExport[i].MANAGE_TYPE_NAME </td>
<td>@ViewBag.TrackExport[i].MANAGE_CONTENT_NAME </td>
<td>@ViewBag.TrackExport[i].FOLLOW_FOCUS </td>
<td>@ViewBag.TrackExport[i].NEXT_DATETIME </td>
<td>@ViewBag.TrackExport[i].SALES_MAN </td>
<td>@ViewBag.TrackExport[i].CREATED_TIME.ToString("yyyy-MM-dd HH:mm:ss") </td>
</tr>
}
}
</tbody>
</table>
<script>
//合并相同行
function mergeFunc(tableId, maxCol, groupColumn) {
var tab = document.getElementById(tableId);
if (!tab) return;
groupColumn = groupColumn === undefined ? 0 : groupColumn;
for (var col = maxCol - 1; col >= 0; col--) {
var count = 1;
for (var i = 0; i < tab.rows.length; i++) {
if (i > 0) {
var groupSame = tab.rows[i].cells[groupColumn].innerHTML == tab.rows[i - 1].cells[groupColumn].innerHTML;
var colSame = tab.rows[i].cells[col].innerHTML == tab.rows[i - 1].cells[col].innerHTML;
if (groupSame && colSame) {
count++;
} else {
if (count > 1) {
var start = i - count;
tab.rows[start].cells[col].rowSpan = count;
for (var j = start + 1; j < i; j++) {
tab.rows[j].removeChild(tab.rows[j].cells[col]);
}
count = 1;
}
}
}
}
if (count > 1) {
start = i - count;
tab.rows[start].cells[col].rowSpan = count;
for (var j = start + 1; j < i; j++) {
tab.rows[j].removeChild(tab.rows[j].cells[col]);
}
}
}
$('#' + tableId +' td b').remove();//移除<td>内的<b>标签
}
//初始化加载
$(function () {
//合并相同行
mergeFunc("tbody", 17, 0);
//导出excel弹窗
setTimeout(() => {
Export();
}, 1000);
});
//导出Excel
function Export() {
$('#table').table2excel({
filename: 'CRM_' + new Date().getTime(), //文件名称
});
// 导出后延迟 3000ms 再关闭页面
setTimeout(() => {
window.close();
}, 3000);
}
</script>
</body>
</html>
jquery.table2excel.js
javascript
/* 调用方法:
* $('#test_table').table2excel({//'#test_table' table的id
* subtotal: 1,//可选参数(可删除此行),默认值:0
* width:200,//导出excel表格的宽度百分比的值(不含%号),可删除此行(默认100%)
* filename: 'excel_' + new Date().getTime() + '.xls', //excel文件名称,扩展名:.xlsx 或者.xls
* });
*/
(function ($, window, document, undefined) {
var pluginName = "table2excel",
defaults = {
exclude: ".noExl",
name: "Table2Excel",
filename: "table2excel",
fileext: ".xls",
exclude_img: true,
exclude_links: true,
exclude_inputs: true,
preserveColors: false,
subtotal: 0,//"合计"行所在的行号(不包括标题行),0表示没有合计行...
width: 100,//表格宽度百分比,默认100%
};
//插件配置
function Plugin(element, options) {
this.element = element;
this.settings = $.extend({}, defaults, options);
this._defaults = defaults;
this._name = pluginName;
this.init();
}
Plugin.prototype = {
init: function () {
var e = this;
var w = getWidth(e.settings);//导出EXCEL表格的宽度,默认100%
var utf8Heading = "<meta http-equiv=\"content-type\" content=\"application/vnd.ms-excel; charset=UTF-8\">";
e.template = {
head: "<html xmlns:o=\"urn:schemas-microsoft-com:office:office\" xmlns:x=\"urn:schemas-microsoft-com:office:excel\" xmlns=\"http://www.w3.org/TR/REC-html40\">" + utf8Heading + "<head><!--[if gte mso 9]><xml><x:ExcelWorkbook><x:ExcelWorksheets>",
sheet: {
head: "<x:ExcelWorksheet><x:Name>",
tail: "</x:Name><x:WorksheetOptions><x:DisplayGridlines/></x:WorksheetOptions></x:ExcelWorksheet>"
},
mid: "</x:ExcelWorksheets></x:ExcelWorkbook></xml><![endif]--></head><body>",
table: {
head: " <table border='1' style='width:" + w + "%;'>",//<table>的边框&宽度
tail: " </table>"
},
foot: "</body></html>"
};
e.tableRows = [];
//读取原始表
var rowNumber = 0;//行号
$(e.element).each(function (i, o) {
var tempRows = "";//table的html
$(o).find("tr").not(e.settings.exclude).each(function (i, p) {
//<tr>的样式
var trStyles = "";//整行样式
//开始创建一行表格
if (trStyles) {
tempRows += "<tr align='center' style='" + trStyles + "'>";//内容居中:align='center'
}
else {
tempRows += "<tr align='center'>";//内容居中:align='center'
}
//读取原始<table>的<th>表头行(表头必须是<th>!表头如果是<td>的话则会当做普通数据行处理...)
$(p).find("th").not(e.settings.exclude).each(function (i, q) {
//<th>的样式:
var thStyles = "";//background-color: cornflowerblue; color:white;
var rc = {
rows: $(this).attr("rowspan"),
cols: $(this).attr("colspan"),
flag: $(q).find(e.settings.exclude)
};
if (rc.flag.length > 0) {
tempRows += "<td> </td>"; //空格!
} else {
tempRows += "<td";
if (rc.rows > 0) {
tempRows += " rowspan='" + rc.rows + "' ";//跨行
}
if (rc.cols > 0) {
tempRows += " colspan='" + rc.cols + "' ";//跨列
}
if (thStyles) {
tempRows += " style='" + thStyles + "'";//样式
}
tempRows += ">" + $(q).html() + "</td>";//内容
}
});
//读取原始<table>的<td>数据行
$(p).find("td").not(e.settings.exclude).each(function (i, q) {
//<td>的样式
var tdStyles = "background-color:yellow;";//合计行的样式
var rc = {
rows: $(this).attr("rowspan"),
cols: $(this).attr("colspan"),
flag: $(q).find(e.settings.exclude)
};
if (rc.flag.length > 0) {
tempRows += "<td> </td>"; //空格!
} else {
tempRows += "<td ";
if (rc.rows > 0) {
tempRows += " rowspan='" + rc.rows + "' ";//跨行
}
if (rc.cols > 0) {
tempRows += " colspan='" + rc.cols + "' ";//跨列
}
var subtotal = getSubtotal(e.settings);//获取"合计"行所在的行号(不包括标题行)
if (rowNumber == subtotal) {//if(当前行行号 == 合计行行号)
if (tdStyles) {
tempRows += " style='mso-number-format:\"\@\"; " + tdStyles + "' ";//样式
}
else {
tempRows += " style='mso-number-format:\"\@\";' ";//纯文本
}
}
else {
tempRows += " style='mso-number-format:\"\@\";' ";//纯文本
}
tempRows += ">" + $(q).html() + "</td>";
}
});
tempRows += "</tr>";//生成一行结束
rowNumber++;//行号+1
});
// exclude img tags
if (e.settings.exclude_img) {
tempRows = exclude_img(tempRows);
}
// exclude link tags
if (e.settings.exclude_links) {
tempRows = exclude_links(tempRows);
}
// exclude input tags
if (e.settings.exclude_inputs) {
tempRows = exclude_inputs(tempRows);
}
e.tableRows.push(tempRows);
});
e.tableToExcel(e.tableRows, e.settings.name, e.settings.sheetName);
},
tableToExcel: function (table, name, sheetName) {
var e = this, fullTemplate = "", i, link, a;
e.format = function (s, c) {
return s.replace(/{(\w+)}/g, function (m, p) {
return c[p];
});
};
sheetName = typeof sheetName === "undefined" ? "Sheet" : sheetName;
e.ctx = {
worksheet: name || "Worksheet",
table: table,
sheetName: sheetName
};
fullTemplate = e.template.head;
if ($.isArray(table)) {
Object.keys(table).forEach(function (i) {
//fullTemplate += e.template.sheet.head + "{worksheet" + i + "}" + e.template.sheet.tail;
fullTemplate += e.template.sheet.head + sheetName + i + e.template.sheet.tail;
});
}
fullTemplate += e.template.mid;
if ($.isArray(table)) {
Object.keys(table).forEach(function (i) {
fullTemplate += e.template.table.head + "{table" + i + "}" + e.template.table.tail;
});
}
fullTemplate += e.template.foot;
for (i in table) {
e.ctx["table" + i] = table[i];
}
delete e.ctx.table;
var isIE = navigator.appVersion.indexOf("MSIE 10") !== -1 || (navigator.userAgent.indexOf("Trident") !== -1 && navigator.userAgent.indexOf("rv:11") !== -1); // this works with IE10 and IE11 both :)
//if (typeof msie !== "undefined" && msie > 0 || !!navigator.userAgent.match(/Trident.*rv\:11\./)) // this works ONLY with IE 11!!!
if (isIE) {
if (typeof Blob !== "undefined") {
//use blobs if we can
fullTemplate = e.format(fullTemplate, e.ctx); // with this, works with IE
fullTemplate = [fullTemplate];
//convert to array
var blob1 = new Blob(fullTemplate, { type: "text/html" });
window.navigator.msSaveBlob(blob1, getFileName(e.settings));
} else {
//otherwise use the iframe and save
//requires a blank iframe on page called txtArea1
txtArea1.document.open("text/html", "replace");
txtArea1.document.write(e.format(fullTemplate, e.ctx));
txtArea1.document.close();
txtArea1.focus();
sa = txtArea1.document.execCommand("SaveAs", true, getFileName(e.settings));
}
} else {
var blob = new Blob([e.format(fullTemplate, e.ctx)], { type: "application/vnd.ms-excel" });
window.URL = window.URL || window.webkitURL;
link = window.URL.createObjectURL(blob);
a = document.createElement("a");
a.download = getFileName(e.settings);
a.href = link;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
}
return true;
}
};
//获取excel文件名
function getFileName(settings) {
return (settings.filename ? settings.filename : "table2excel");
}
//获取"合计"行所在的行号(不包括标题行)
function getSubtotal(settings) {
return (settings.subtotal ? settings.subtotal : 0);//默认值0
}
//导出Excel的表格宽度百分比的值(不含%号),默认100%
function getWidth(settings) {
return (settings.width ? settings.width : 100);
}
// Removes all img tags
function exclude_img(string) {
var _patt = /(\s+alt\s*=\s*"([^"]*)"|\s+alt\s*=\s*'([^']*)')/i;
return string.replace(/<img[^>]*>/gi, function myFunction(x) {
var res = _patt.exec(x);
if (res !== null && res.length >= 2) {
return res[2];
} else {
return "";
}
});
}
// Removes all link tags
function exclude_links(string) {
return string.replace(/<a[^>]*>|<\/a>/gi, "");
}
// Removes input params
function exclude_inputs(string) {
var _patt = /(\s+value\s*=\s*"([^"]*)"|\s+value\s*=\s*'([^']*)')/i;
return string.replace(/<input[^>]*>|<\/input>/gi, function myFunction(x) {
var res = _patt.exec(x);
if (res !== null && res.length >= 2) {
return res[2];
} else {
return "";
}
});
}
$.fn[pluginName] = function (options) {
var e = this;
e.each(function () {
if (!$.data(e, "plugin_" + pluginName)) {
$.data(e, "plugin_" + pluginName, new Plugin(this, options));
}
});
// chain jQuery functions
return e;
};
})(jQuery, window, document);
图示:

Layui-table 参考:
javascript
<script type="text/javascript">
//初始化
$(function () {
PageList();
});
//重置
function Reset() {
window.location.reload();
}
//查询
function PageList() {
var START_DATE = $("#START_DATE").val();
var END_DATE = $("#END_DATE").val();
var CUSTOMER_NAME = $("#TXT_CUSTOMER_NAME").val();
var CONTACT_LINK = $("#TXT_CONTACT_LINK").val();
var PROJECT_STATUS = $("#TXT_PROJECT_STATUS").val();
var PROJECT_LEVEL = $("#TXT_PROJECT_LEVEL").val();
layui.use(['table'], function () {
var table = layui.table;
table.render({
elem: '#table'//对应着Table的ID
//, width: '100%'
, method: 'POST'
, url: '/SalesOpportunity/SalesOpportunityTrackPage'//URL为数据接口的地址
, where: { //where就是ajax的data,但不包括分页条件
"START_DATE": START_DATE,
"END_DATE": END_DATE,
"CUSTOMER_NAME": CUSTOMER_NAME,
"CONTACT_LINK": CONTACT_LINK,
"PROJECT_STATUS": PROJECT_STATUS,
"PROJECT_LEVEL": PROJECT_LEVEL,
}
, request: { //分页条件: page limit
pageName: 'page', //页码的参数名称,默认:page 或者 index、pageIndex
limitName: 'size' //每页数据量的参数名,默认:limit 或者 size、pageSize
}
, parseData: function (res) {
return {
"code": 0,//数据类型,必须的
"count": res.total,//总记录数,用于分页
"data": res.data,//必须的
}
}
, cols: [
[
/* { title: '操作', toolbar: '#barDemo', width: 80, align: 'center', rowspan: 2 },*/
{
field: 'SALES_OPPORTUNITY_SID', title: '操作', width: 80, align: 'center', rowspan: 2
, templet: function (d) {
//return d.SALES_OPPORTUNITY_SID;
return `<button class="layui-btn layui-btn-xs layui-btn-radius layui-form-button-blue" onclick="OpenEdit(` + d.SALES_OPPORTUNITY_SID + `)">详情<span hidden>` + d.SALES_OPPORTUNITY_SID + `</span></button>`;
}
},
{ title: '客户基础信息', colspan: 14, align: 'center' },
{ title: '跟踪维护信息', colspan: 10, align: 'center' },
],
[
{ field: 'CUSTOMER_NAME', title: '客户名称', width: 200, align: 'center' },
{ field: 'CONTACT_LINK', title: '联系人', width: 100, align: 'center' },
{ field: 'CONTACT_PHONE', title: '联系电话', width: 150, align: 'center' },
{ field: 'HOBBIES', title: '客户喜好', width: 150, align: 'center' },
{
field: 'BIRTHDAY', title: '纪念日/生日', width: 200, align: 'center'
, templet: function (d) {
if (d.BIRTHDAY) {
return d.BIRTHDAY.replace(",", ",<br>");
}
else {
return "";
}
}
},
{ field: 'PROJECT_TITLE', title: '项目标题', width: 250, align: 'center' },
{ field: 'PROJECT_INFO', title: '项目信息', width: 250, align: 'center' },
{
field: 'PROJECT_STATUS', title: '项目状态', width: 100, align: 'center'
, templet: function (d) {
if (d.PROJECT_STATUS == 0) return "进行中<span hidden>" + d.SALES_OPPORTUNITY_PROJECT_SID + "</span>";
else if (d.PROJECT_STATUS == 1) return "<font color='green'>完成</font><span hidden>" + d.SALES_OPPORTUNITY_PROJECT_SID + "</span>";
else if (d.PROJECT_STATUS == 2) return "<font color='red'>中止</font><span hidden>" + d.SALES_OPPORTUNITY_PROJECT_SID + "</span>";
else return "<span hidden>" + d.SALES_OPPORTUNITY_PROJECT_SID + "</span>";
}
},
{
field: 'PROJECT_LEVEL', title: '项目等级', width: 100, align: 'center'
, templet: function (d) {
if (d.PROJECT_LEVEL == 0) return "D<span hidden>" + d.SALES_OPPORTUNITY_PROJECT_SID + "</span>";
else if (d.PROJECT_LEVEL == 1) return "C<span hidden>" + d.SALES_OPPORTUNITY_PROJECT_SID + "</span>";
else if (d.PROJECT_LEVEL == 2) return "B<span hidden>" + d.SALES_OPPORTUNITY_PROJECT_SID + "</span>";
else if (d.PROJECT_LEVEL == 3) return "A<span hidden>" + d.SALES_OPPORTUNITY_PROJECT_SID + "</span>";
else return "<span hidden>" + d.SALES_OPPORTUNITY_PROJECT_SID + "</span>";
}
},
{ field: 'NEEDS', title: '核心诉求', width: 250, align: 'center' },
{ field: 'RESPONSE', title: '诉求应答', width: 250, align: 'center' },
{ field: 'EST_AMOUNT', title: '预成交金额(万元)', width: 150, align: 'center' },
{ field: 'NEED_SUPPORT', title: '需要的支持', width: 250, align: 'center' },
{ field: 'REMARKS', title: '备注', width: 250, align: 'center' },
{
field: 'FIRST_MANAGE_DATE', title: '首次维护时间', width: 150, align: 'center'
, templet: function (d) {
if (d.FIRST_MANAGE_DATE) {
return dateToDateString(d.FIRST_MANAGE_DATE);
}
else {
return '';
}
}
},
{
field: 'LAST_MANAGE_DATE', title: '最近维护时间', width: 150, align: 'center'
, templet: function (d) {
if (d.LAST_MANAGE_DATE) {
return dateToDateString(d.LAST_MANAGE_DATE);
}
else {
return '';
}
}
},
{ field: 'SINCE_DAYS', title: '未跟进时间(天)', width: 150, align: 'center' },
{
field: 'MANAGE_DATE', title: '维护日期', width: 150, align: 'center'
, templet: function (d) {
if (d.MANAGE_DATE) {
return timestampToDateString(d.MANAGE_DATE);
} else {
return '';
}
}
},
{
field: 'MANAGE_TYPE', title: '维护方式', width: 100, align: 'center'
, templet: function (d) {
if (d.MANAGE_TYPE == 0) return "电话";
else if (d.MANAGE_TYPE == 1) return "微信";
else if (d.MANAGE_TYPE == 2) return "面谈";
else if (d.MANAGE_TYPE == 3) return "邮件";
else if (d.MANAGE_TYPE == 4) return "其他";
else return "";
}
},
{
field: 'MANAGE_CONTENT', title: '维护类型', width: 100, align: 'center'
, templet: function (d) {
if (d.MANAGE_CONTENT == 0) return "需求";
else if (d.MANAGE_CONTENT == 1) return "反馈";
else if (d.MANAGE_CONTENT == 2) return "问候";
else if (d.MANAGE_CONTENT == 3) return "其他";
else return "";
}
},
{ field: 'FOLLOW_FOCUS', title: '内容/跟进重点', width: 250, align: 'center' },
{ field: 'NEXT_DATETIME', title: '下次跟进时间', width: 150, align: 'center' },
{ field: 'SALES_MAN', title: '销售人员', width: 100, align: 'center' },
{
field: 'CREATED_TIME', title: '本记录时间', width: 180, align: 'center', templet: function (d) {
if (d.CREATED_TIME) {
return timestampToTimeString(d.CREATED_TIME);
} else {
return '';
}
}
},
]],
page: true,//开启分页功能
limit: 25,//当前每页条数
limits: [25, 50, 100],//每页条数集合
done: function (res, curr, count) {
$('.layui-table-cell').css('height', 'auto'); // 暴力刷新
mergeCell('table', ['SALES_OPPORTUNITY_SID', 'SALES_OPPORTUNITY_SID'], 'SALES_OPPORTUNITY_SID');
mergeCell('table', ['SALES_OPPORTUNITY_SID', 'SALES_OPPORTUNITY_PROJECT_SID'], 'CUSTOMER_NAME');
mergeCell('table', ['SALES_OPPORTUNITY_SID', 'SALES_OPPORTUNITY_PROJECT_SID'], 'CONTACT_LINK');
mergeCell('table', ['SALES_OPPORTUNITY_SID', 'SALES_OPPORTUNITY_PROJECT_SID'], 'CONTACT_PHONE');
mergeCell('table', ['SALES_OPPORTUNITY_SID', 'SALES_OPPORTUNITY_PROJECT_SID'], 'PROJECT_TITLE');
mergeCell('table', ['SALES_OPPORTUNITY_SID', 'SALES_OPPORTUNITY_PROJECT_SID'], 'PROJECT_INFO');
mergeCell('table', ['SALES_OPPORTUNITY_SID', 'SALES_OPPORTUNITY_PROJECT_SID'], 'PROJECT_STATUS');
mergeCell('table', ['SALES_OPPORTUNITY_SID', 'SALES_OPPORTUNITY_PROJECT_SID'], 'PROJECT_LEVEL');
mergeCell('table', ['SALES_OPPORTUNITY_SID', 'SALES_OPPORTUNITY_PROJECT_SID'], 'HOBBIES');
mergeCell('table', ['SALES_OPPORTUNITY_SID', 'SALES_OPPORTUNITY_PROJECT_SID'], 'BIRTHDAY');
mergeCell('table', ['SALES_OPPORTUNITY_SID', 'SALES_OPPORTUNITY_PROJECT_SID'], 'NEEDS');
mergeCell('table', ['SALES_OPPORTUNITY_SID', 'SALES_OPPORTUNITY_PROJECT_SID'], 'RESPONSE');
mergeCell('table', ['SALES_OPPORTUNITY_SID', 'SALES_OPPORTUNITY_PROJECT_SID'], 'EST_AMOUNT');
mergeCell('table', ['SALES_OPPORTUNITY_SID', 'SALES_OPPORTUNITY_PROJECT_SID'], 'NEED_SUPPORT');
mergeCell('table', ['SALES_OPPORTUNITY_SID', 'SALES_OPPORTUNITY_PROJECT_SID'], 'REMARKS');
mergeCell('table', ['SALES_OPPORTUNITY_SID', 'SALES_OPPORTUNITY_PROJECT_SID'], 'FIRST_MANAGE_DATE');
mergeCell('table', ['SALES_OPPORTUNITY_SID', 'SALES_OPPORTUNITY_PROJECT_SID'], 'LAST_MANAGE_DATE');
mergeCell('table', ['SALES_OPPORTUNITY_SID', 'SALES_OPPORTUNITY_PROJECT_SID'], 'SINCE_DAYS');
},
});
});
}
// 合并规则:N个主列 + 副列 都相同 → 才合并【副列】
// tableId:表格ID
// mainFields:主字段数组(支持多个,如 ['SALES_OPPORTUNITY_SID','SALES_OPPORTUNITY_PROJECT_SID'])
// subField:要合并的字段(联系人)
function mergeCell(tableId, groupFields, mergeField) {
const $tbody = $('#' + tableId + ' + div .layui-table-body tbody');
const $trs = $tbody.find('tr');
if ($trs.length <= 1) return;
let startRow = 0;
let spanCount = 1;
for (let i = 1; i < $trs.length; i++) {
const $prevTr = $trs.eq(startRow);
const $currTr = $trs.eq(i);
// ======================================
// 【关键】判断所有分组列是否完全一样
// ======================================
let groupSame = true;
for (const field of groupFields) {
const t1 = $prevTr.find('td[data-field="' + field + '"]').text().trim();
const t2 = $currTr.find('td[data-field="' + field + '"]').text().trim();
if (t1 !== t2) {
groupSame = false;
break;
}
}
// 判断要合并的列是否一样
const m1 = $prevTr.find('td[data-field="' + mergeField + '"]').text().trim();
const m2 = $currTr.find('td[data-field="' + mergeField + '"]').text().trim();
const mergeSame = m1 === m2;
// 分组相同 + 合并列相同 → 合并
if (groupSame && mergeSame) {
spanCount++;
$currTr.find('td[data-field="' + mergeField + '"]').hide();
} else {
// 设置合并
$prevTr.find('td[data-field="' + mergeField + '"]').attr('rowspan', spanCount);
startRow = i;
spanCount = 1;
}
}
// 最后一行处理
$trs.eq(startRow).find('td[data-field="' + mergeField + '"]').attr('rowspan', spanCount);
}
//时间戳转日期
function timestampToDateString(dateTime) {
if (!dateTime) return "";
// 提取时间戳
var timestampStr = dateTime.replace("/Date(", "").replace(")/", "");
var timestamp = parseInt(timestampStr);
const date = new Date(timestamp);
// 获取 年/月/日
var year = date.getFullYear();
var month = (date.getMonth() + 1).toString().padStart(2, '0'); // 月补0
var day = date.getDate().toString().padStart(2, '0'); // 日补0
// 返回标准格式:2025-04-05
return year + "-" + month + "-" + day;
}
//时间戳转时间
function timestampToTimeString(dateTime) {
if (!dateTime) return "";
// 提取时间戳(兼容 /Date(xxx)/ 格式)
var timestampStr = dateTime.replace("/Date(", "").replace(")/", "");
var timestamp = parseInt(timestampStr);
const date = new Date(timestamp);
// 获取 年/月/日
var year = date.getFullYear();
var month = (date.getMonth() + 1).toString().padStart(2, '0');
var day = date.getDate().toString().padStart(2, '0');
// 获取 时/分/秒 + 自动补0
var hour = date.getHours().toString().padStart(2, '0');
var minute = date.getMinutes().toString().padStart(2, '0');
var second = date.getSeconds().toString().padStart(2, '0');
// 返回格式:2025-04-05 14:05:09
return year + "-" + month + "-" + day + " " + hour + ":" + minute + ":" + second;
}
//日期转日期
function dateToDateString(dateTime) {
if (!dateTime) return "";
const date = new Date(dateTime);
// 获取 年/月/日
var year = date.getFullYear();
var month = (date.getMonth() + 1).toString().padStart(2, '0'); // 月补0
var day = date.getDate().toString().padStart(2, '0'); // 日补0
// 返回标准格式:2025-04-05
return year + "-" + month + "-" + day;
}
</script>
