需求:能够根据后端给的数据,导出excel,并且相同车辆合并单元格

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><title>根据需求合并表格</title><script src="js/jquery-2.1.0.min.js"></script><!-- <script type="text/javascript" src="https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js"></script> --><script type="text/javascript" src="xlsx/xlsx.full.min.js"></script>
</head><body><script>let coolTitle = ['车牌号','分区下标','硬盘容量','硬盘加载状态','硬盘DBR状态','硬盘FAT状态','硬盘录像状态','磁盘1容量','磁盘1加载状态','磁盘1DBR状态','磁盘1FAT状态','磁盘1录像状态','磁盘2容量','磁盘2加载状态','磁盘2DBR状态','磁盘2FAT状态','磁盘2录像状态'];let deviceDiskStateArray = [ {deviceId: '18721363239',diskStateInfoArray: [{DiskCapacity: 500107862016,partitions: 4,DiskType: 0,MountType: 0,diskPartitionArray: [{FATState: 1,partitionIndex: 0,DBRState: 0,INDEXFileState: 0},{FATState: 0,partitionIndex: 1,DBRState: 0,INDEXFileState: 0},{FATState: 0,partitionIndex: 2,DBRState: 0,INDEXFileState: 0},{FATState: 0,partitionIndex: 3,DBRState: 0,INDEXFileState: 0}]},{DiskCapacity: 277668662016,partitions: 2,DiskType: 1,MountType: 0,diskPartitionArray: [{FATState: 1,partitionIndex: 0,DBRState: 0,INDEXFileState: 0},{FATState: 0,partitionIndex: 1,DBRState: 0,INDEXFileState: 0},{FATState: 0,partitionIndex: 2,DBRState: 0,INDEXFileState: 0},{FATState: 0,partitionIndex: 3,DBRState: 0,INDEXFileState: 0}]},{DiskCapacity: 788662016,partitions: 2,DiskType: 2,MountType: 0,diskPartitionArray: [{FATState: 1,partitionIndex: 0,DBRState: 0,INDEXFileState: 0},{FATState: 0,partitionIndex: 1,DBRState: 0,INDEXFileState: 0}]}]},{deviceId: '122334455669',diskStateInfoArray: [{DiskCapacity: 500107862016,partitions: 4,DiskType: 0,MountType: 0,diskPartitionArray: [{FATState: 1,partitionIndex: 0,DBRState: 0,INDEXFileState: 0},{FATState: 0,partitionIndex: 1,DBRState: 0,INDEXFileState: 0}]},{DiskCapacity: 277668662016,partitions: 2,DiskType: 1,MountType: 0,diskPartitionArray: [{FATState: 1,partitionIndex: 0,DBRState: 0,INDEXFileState: 0}]}]}];let array = [];array.push(coolTitle)deviceDiskStateArray.map(item => {let arr = [], arr2 = [], arr3 = [], obj = {};obj.deviceId = item.deviceId;item.diskStateInfoArray.map(value => {if (value.DiskType === 0) {obj.ypRL = toFixed(getGB(value.DiskCapacity), 2) + 'G';obj.ypLoading = constrAbx(value.MountType, 4);value.diskPartitionArray.map(node => {if (node.partitionIndex === 0) {node.partitionIndex = '0';}let ypObj = ['', node.partitionIndex, '', '', constrAbx(node.DBRState, 4), constrAbx(node.FATState, 4), constrAbx(node.INDEXFileState, 4)];arr.push(ypObj);});} else if (value.DiskType === 1) {obj.s1RL = toFixed(getGB(value.DiskCapacity), 2) + 'G';obj.s1Loading = constrAbx(value.MountType, 4);value.diskPartitionArray.map(node => {if (node.partitionIndex === 0) {node.partitionIndex = '0';}let s1Obj = ['', node.partitionIndex, '', '', constrAbx(node.DBRState, 4), constrAbx(node.FATState, 4), constrAbx(node.INDEXFileState, 4)];arr2.push(s1Obj);});} else if (value.DiskType === 2) {obj.s2RL = toFixed(getGB(value.DiskCapacity), 2) + 'G';obj.s2Loading = constrAbx(value.MountType, 4);value.diskPartitionArray.map(node => {if (node.partitionIndex === 0) {node.partitionIndex = '0';}let s2Obj = ['', node.partitionIndex, '', '', constrAbx(node.DBRState, 4), constrAbx(node.FATState, 4), constrAbx(node.INDEXFileState, 4)];arr3.push(s2Obj);});}});let addD = [[],[],[],[]];if (arr.length !== 0) {console.log(arr)arr.map((value,index) => {addD[index][0] = obj.deviceId ? obj.deviceId : '';addD[index][2] = obj.ypRL ? obj.ypRL : '';addD[index][3] = obj.ypLoading ? obj.ypLoading : '';addD[index][1] = value[1] ? value[1] : '';addD[index][4] = value[4] ? value[4] : '';addD[index][5] = value[5] ? value[5] : '';addD[index][6] = value[6] ? value[6] : '';});}if (arr2.length !== 0) {arr2.map((value, index) => {addD[index][0] = obj.deviceId ? obj.deviceId : '';addD[index][7] = obj.s1RL ? obj.s1RL : '';addD[index][8] = obj.s1Loading ? obj.s1Loading : '';addD[index][1] = value[1] ? value[1] : '';addD[index][9] = value[4] ? value[4] : '';addD[index][10] = value[5] ? value[5] : '';addD[index][11] = value[6] ? value[6] : '';});}if (arr3.length !== 0) {arr3.map((value, index) => {addD[index][0] = obj.deviceId ? obj.deviceId : '';addD[index][12] = obj.s2RL ? obj.s2RL : '';addD[index][13] = obj.s2Loading ? obj.s2Loading : '';addD[index][1] = value[1] ? value[1] : '';addD[index][14] = value[4] ? value[4] : '';addD[index][15] = value[5] ? value[5] : '';addD[index][16] = value[6] ? value[6] : '';});}addD.map(item => {if (item[0] !== undefined) {array.push(item);}});});console.log(array);getTableXlsx(array, 'diskInfo.xlsx');// 导出xlsxfunction getTableXlsx(aoa, filename) {let colData = aoa[0][0];var countedNames = aoa.reduce((obj, name) => {if (name[0] != colData) {if (name[0] in obj) {obj[name[0]]++} else {obj[name[0]] = 1}}return obj}, {})console.log(countedNames)let number = [];Object.keys(countedNames).forEach((key) => {number.push(countedNames[key])})console.log(number);let merges = [];let ac = 0;for (let i = 0; i < number.length; i++) {let a = number[i], b = 0, c = 1, d = 0;if (i == 0) {let obj = { s: { c: 0, r: c }, e: { c: 0, r: a + b } };merges.push(obj)}if (i !== number.length - 1) {d = number[i + 1];if (i == 0) {ac += a + 1;let obj = { s: { c: 0, r: ac }, e: { c: 0, r: ac + d - 1 } };merges.push(obj)} else {ac += a;let obj = { s: { c: 0, r: ac }, e: { c: 0, r: ac + d - 1 } };merges.push(obj)}}}console.log(merges)var sheet = XLSX.utils.aoa_to_sheet(aoa);sheet['!merges'] = merges;openDownloadDialog(sheet2blob(sheet), filename);}// 下载重点function openDownloadDialog(url, saveName) {if (typeof url == 'object' && url instanceof Blob) {url = URL.createObjectURL(url); // 创建blob地址}var aLink = document.createElement('a');aLink.href = url;aLink.download = saveName || ''; // HTML5新增的属性,指定保存文件名,可以不要后缀,注意,file:///模式下不会生效var event;if (window.MouseEvent) event = new MouseEvent('click');else {event = document.createEvent('MouseEvents');event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0,null);}aLink.dispatchEvent(event);}// 将一个sheet转成最终的excel文件的blob对象,然后利用URL.createObjectURL下载function sheet2blob(sheet, sheetName) {sheetName = sheetName || 'sheet1';var workbook = {SheetNames: [sheetName],Sheets: {}};workbook.Sheets[sheetName] = sheet;// 生成excel的配置项var wopts = {bookType: 'xlsx', // 要生成的文件类型bookSST: false, // 是否生成Shared String Table,官方解释是,如果开启生成速度会下降,但在低版本IOS设备上有更好的兼容性type: 'binary'};var wbout = XLSX.write(workbook, wopts);var blob = new Blob([s2ab(wbout)], {type: "application/octet-stream"});// 字符串转ArrayBufferfunction s2ab(s) {var buf = new ArrayBuffer(s.length);var view = new Uint8Array(buf);for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;return buf;}return blob;}// 时间默认值function getDateInfo(number) {let date = new Date();let year = date.getFullYear();let month = byZero(date.getMonth(), 1);let day = byZero(date.getDate());let hour = byZero(date.getHours());let minute = byZero(date.getMinutes());let second = byZero(date.getSeconds());if (number === 1) {return year + '-' + month + '-' + day + ' ' + hour + ':' + minute + ':' + second;}}// 时间默认值加零function byZero(number, type) {if (number >= 10) {return number;} else {if (type === 1) {number = number + 1;return '0' + number;} else {return '0' + number;}}}// 转换function constrAbx(num, number) {if (number === 4) {if (num === 0) {return '正常';} else if (num === 1) {return '异常';} else if (num === 2) {return '不一致';}}}// 小数点function toFixed(number, n) {let numberStr = number + "";let reg = /^(-|\+)?(\d+(\.\d*)?|\.\d+)$/i;if (!reg.test(numberStr)) {alert('输⼊的数字格式不对');return;}let sign = numberStr.charAt(0) === '-' ? (numberStr = numberStr.slice(1), -1) : 1; // 判断是否是负数let pointIndex = numberStr.indexOf("."); // 记录⼩数点的位置if (pointIndex > -1) {numberStr = numberStr.replace(".", "");} else { // 没有⼩数点直接添加补0;numberStr += ".";numberStr += new Array(n).join('0');return numberStr;}let numberArray = numberStr.split(""); //转成数组let len = numberArray.length;let oldPointNum = len - pointIndex; // 获取原数据有多少位⼩数if (oldPointNum < n) { // 要保留的⼩数点⽐原来的要⼤,直接补0while (n - oldPointNum > 0) {numberArray.push(0);n--;}} else if (oldPointNum > n) { // 模拟四舍五⼊let i = oldPointNum - n; // 从倒数第i个数字开始⽐较let more = numberArray[len - i] >= 5 ? true : false;while (more) {i++;more = +numberArray[len - i] + 1 === 10 ? true : false; // 进位后判断是否等于10,是则继续进位numberArray[len - i] = more && i !== (len + 1) ? 0 : +numberArray[len - i] + 1; // 其他位置的数字进位直接变成0,第⼀位的例外}numberArray.length = len - (oldPointNum - n); // 截取多余的⼩数}numberArray.splice(pointIndex, 0, ".");return sign === -1 ? '-' + numberArray.join("") : numberArray.join("");};// KB转换成GBfunction getGB(number) {return number / 1024 / 1024 / 1024;}</script>
</body></html>

走到这一步遇到的一些帮助:

纯前端利用 js-xlsx 实现 Excel 文件导入导出功能示例:https://www.jianshu.com/p/74d405940305

如果不知道该怎么去自定义合并列或合并行,可以参考下面代码:

js-xlsx导出自定义合并列头实现思路:https://www.jianshu.com/p/9a465d7d1448

<!DOCTYPE html>
<html><head><meta charset="UTF-8"><title></title><script src="xlsx/xlsx.core.min.js"></script>
</head><body><input type="file" onchange="importf(this)" /><div id="demo"></div><script>var WB;var rABS = true; //是否将文件读取为二进制字符串function importf(obj) {//导入if (!obj.files) { return; }var f = obj.files[0];{var reader = new FileReader();var name = f.name;reader.onload = function (e) {var data = e.target.result;WB = XLSX.read(data, { type: 'binary' });document.getElementById("demo").innerHTML = JSON.stringify(WB.Sheets[WB.SheetNames[0]]);};if (rABS) reader.readAsBinaryString(f);else reader.readAsArrayBuffer(f);}}</script>
</body></html>

摘自文章:js利用sheetjs生成excel并导出_QingHan_wow的博客-CSDN博客_sheetjs 导出

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><title>Document</title><script src="js/jquery-2.1.0.min.js"></script><script type="text/javascript" src="https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js"></script>
</head><body><script>var aoa = [['姓名', '性别', '年龄', '注册时间'],['张三', '男', 18, new Date()],['张三', '男', 18, new Date()],['张三', '男', 18, new Date()],['李四', '女', 22, new Date()],['李四', '女', 22, new Date()],['李四', '女', 22, new Date()],['李四', '女', 22, new Date()],['王五', '男', 22, new Date()],['王五', '男', 22, new Date()],['老六', '女', 22, new Date()],['老六', '女', 22, new Date()],['老六', '女', 22, new Date()]];var countedNames = aoa.reduce((obj, name) => {if (name[0] != '姓名') {if (name[0] in obj) {obj[name[0]]++} else {obj[name[0]] = 1}}return obj}, {})console.log(countedNames)let number = [];Object.keys(countedNames).forEach((key) => {number.push(countedNames[key])})console.log(number);let merges = [];let ac = 0;for (let i = 0; i < number.length; i++) {let a = number[i], b = 0, c = 1, d = 0;if (i == 0) {let obj = { s: { c: 0, r: c }, e: { c: 0, r: a + b } };merges.push(obj)}if (i !== number.length - 1) {d = number[i + 1];if (i == 0) {ac += a + 1;let obj = { s: { c: 0, r: ac }, e: { c: 0, r: ac + d - 1 } };merges.push(obj)} else {ac += a;let obj = { s: { c: 0, r: ac }, e: { c: 0, r: ac + d - 1 } };merges.push(obj)}}}var sheet = XLSX.utils.aoa_to_sheet(aoa);sheet['!merges'] = merges;openDownloadDialog(sheet2blob(sheet), '导出.xlsx');function openDownloadDialog(url, saveName) {if (typeof url == 'object' && url instanceof Blob) {url = URL.createObjectURL(url); // 创建blob地址}var aLink = document.createElement('a');aLink.href = url;aLink.download = saveName || ''; // HTML5新增的属性,指定保存文件名,可以不要后缀,注意,file:///模式下不会生效var event;if (window.MouseEvent) event = new MouseEvent('click');else {event = document.createEvent('MouseEvents');event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0,null);}aLink.dispatchEvent(event);}// 将一个sheet转成最终的excel文件的blob对象,然后利用URL.createObjectURL下载function sheet2blob(sheet, sheetName) {sheetName = sheetName || 'sheet1';var workbook = {SheetNames: [sheetName],Sheets: {}};workbook.Sheets[sheetName] = sheet;// 生成excel的配置项var wopts = {bookType: 'xlsx', // 要生成的文件类型bookSST: false, // 是否生成Shared String Table,官方解释是,如果开启生成速度会下降,但在低版本IOS设备上有更好的兼容性type: 'binary'};var wbout = XLSX.write(workbook, wopts);var blob = new Blob([s2ab(wbout)], {type: "application/octet-stream"});// 字符串转ArrayBufferfunction s2ab(s) {var buf = new ArrayBuffer(s.length);var view = new Uint8Array(buf);for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;return buf;}return blob;}</script>
</body></html>

再此也保留一下查到的一些资料:

这种应该只能导出不能变的和数据,像合并单元格这种应该不支持,如果有的话,可以一起交流下。感谢!

<html>
<head><p style="font-size: 20px;color: red;">使用a标签方式将json导出csv文件</p><button onclick='tableToExcel()'>导出</button>
</head>
<body><script>const tableToExcel = () => {// 要导出的json数据const jsonData = [{name:'路人甲',phone:'123456789',email:'000@123456.com'},{name:'炮灰乙',phone:'123456789',email:'000@123456.com'},{name:'土匪丙',phone:'123456789',email:'000@123456.com'},{name:'流氓丁',phone:'123456789',email:'000@123456.com'},];// 列标题,逗号隔开,每一个逗号就是隔开一个单元格let str = `姓名\t电话\t邮箱\n`;// 增加\t为了不让表格显示科学计数法或者其他格式for(let i = 0 ; i < jsonData.length ; i++ ){for(const key in jsonData[i]){str+=`${jsonData[i][key] + '\t'}`;     }str+='\n';}console.log(str)// encodeURIComponent解决中文乱码const uri = 'data:text/csv;charset=utf-8,\ufeff' + encodeURIComponent(str);// 通过创建a标签实现const link = document.createElement("a");link.href = uri;// 对下载的文件命名link.download =  "json数据表.xlsx";link.click();}</script>
</body>
</html>

如果单纯导出数据,和layui合作,也可,只是我暂时不知道如何合并单元格

以下是代码,中间有个我对时间循环的解决办法,就一起放着保存吧

导出JS文件在这里可直接下载:

JS导出的一些资源,可共同学习-Javascript文档类资源-CSDN下载

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><!-- layui --><link rel="stylesheet" href="layui/css/layui_base.css"><script type="text/javascript" src="layui/layui.js"></script><script src="js/jquery-2.1.0.min.js"></script><script src="xlsx/xlsx.js"></script><script src="xlsx/dom.js"></script><script src="xlsx/xlsx.core.min.js"></script><title>Document</title>
</head><body><button type="button" class="layui-btn" id="daochu" onclick="exportData()">导出</button><table class="layui-table" lay-filter="videoTable" id="videoTable"></table><script>let table, layer;let videoData = [];let colsListFalse = [{ field: 'deviceId', title: '车牌号', align: 'center' },{ field: 'partitionIndex', title: '分区下标', align: 'center' },{ field: 'ypRL', title: '硬盘容量', align: 'center' },{ field: 'ypLoading', title: '硬盘加载状态', align: 'center' },{ field: 'ypDBRState', title: '硬盘DBR状态', align: 'center' },{ field: 'ypFATState', title: '硬盘FAT状态', align: 'center' },{ field: 'ypINDEXFileState', title: '硬盘录像状态', align: 'center' },{ field: 's1RL', title: '磁盘1容量', align: 'center' },{ field: 's1Loading', title: '磁盘1加载状态', align: 'center' },{ field: 's1DBRState', title: '磁盘1DBR状态', align: 'center' },{ field: 's1FATState', title: '磁盘1FAT状态', align: 'center' },{ field: 's1INDEXFileState', title: '磁盘1录像状态', align: 'center' },{ field: 's2RL', title: '磁盘2容量', align: 'center' },{ field: 's2Loading', title: '磁盘2加载状态', align: 'center' },{ field: 's2DBRState', title: '磁盘2DBR状态', align: 'center' },{ field: 's2FATState', title: '磁盘2FAT状态', align: 'center' },{ field: 's2INDEXFileState', title: '磁盘2录像状态', align: 'center' }];let deviceDiskStateArray = [{deviceId: '18721363239',diskStateInfoArray: [{DiskCapacity: 500107862016,partitions: 4,DiskType: 0,MountType: 0,diskPartitionArray: [{FATState: 1,partitionIndex: 0,DBRState: 0,INDEXFileState: 0},{FATState: 0,partitionIndex: 1,DBRState: 0,INDEXFileState: 0},{FATState: 0,partitionIndex: 2,DBRState: 0,INDEXFileState: 0},{FATState: 0,partitionIndex: 3,DBRState: 0,INDEXFileState: 0}]},{DiskCapacity: 277668662016,partitions: 2,DiskType: 1,MountType: 0,diskPartitionArray: [{FATState: 1,partitionIndex: 0,DBRState: 0,INDEXFileState: 0},{FATState: 0,partitionIndex: 1,DBRState: 0,INDEXFileState: 0},{FATState: 0,partitionIndex: 2,DBRState: 0,INDEXFileState: 0},{FATState: 0,partitionIndex: 3,DBRState: 0,INDEXFileState: 0}]},{DiskCapacity: 788662016,partitions: 2,DiskType: 2,MountType: 0,diskPartitionArray: [{FATState: 1,partitionIndex: 0,DBRState: 0,INDEXFileState: 0},{FATState: 0,partitionIndex: 1,DBRState: 0,INDEXFileState: 0}]}]},{deviceId: '122334455669',diskStateInfoArray: [{DiskCapacity: 500107862016,partitions: 4,DiskType: 0,MountType: 0,diskPartitionArray: [{FATState: 1,partitionIndex: 0,DBRState: 0,INDEXFileState: 0},{FATState: 0,partitionIndex: 1,DBRState: 0,INDEXFileState: 0}]},{DiskCapacity: 277668662016,partitions: 2,DiskType: 1,MountType: 0,diskPartitionArray: [{FATState: 1,partitionIndex: 0,DBRState: 0,INDEXFileState: 0}]}]},{deviceId: '18721363239',diskStateInfoArray: [{DiskCapacity: 500107862016,partitions: 4,DiskType: 0,MountType: 0,diskPartitionArray: [{FATState: 1,partitionIndex: 0,DBRState: 0,INDEXFileState: 0},{FATState: 0,partitionIndex: 1,DBRState: 0,INDEXFileState: 0},{FATState: 0,partitionIndex: 2,DBRState: 0,INDEXFileState: 0}]},{DiskCapacity: 277668662016,partitions: 2,DiskType: 1,MountType: 0,diskPartitionArray: [{FATState: 1,partitionIndex: 0,DBRState: 0,INDEXFileState: 0},{FATState: 0,partitionIndex: 1,DBRState: 0,INDEXFileState: 0},{FATState: 0,partitionIndex: 2,DBRState: 0,INDEXFileState: 0}]},{DiskCapacity: 788662016,partitions: 2,DiskType: 2,MountType: 0,diskPartitionArray: [{FATState: 1,partitionIndex: 0,DBRState: 0,INDEXFileState: 0},{FATState: 0,partitionIndex: 1,DBRState: 0,INDEXFileState: 0}]}]},{deviceId: '122334455669',diskStateInfoArray: [{DiskCapacity: 500107862016,partitions: 4,DiskType: 0,MountType: 0,diskPartitionArray: [{FATState: 1,partitionIndex: 0,DBRState: 0,INDEXFileState: 0},{FATState: 0,partitionIndex: 1,DBRState: 0,INDEXFileState: 0}]},{DiskCapacity: 277668662016,partitions: 2,DiskType: 1,MountType: 0,diskPartitionArray: [{FATState: 1,partitionIndex: 0,DBRState: 0,INDEXFileState: 0}]}]}];layui.use('layer', function () {layer = layui.layer;render();});exportArr();// 表格function render() {layui.use('table', function () {table = layui.table;table.render({elem: '#videoTable',data: videoData,height: '410',width: '100%',defaultToolbar: [],cellMinWidth: 100,cols: [colsListFalse],page: true, //是否显示分页limits: [10, 100, 1000, 2000],page: {count: videoData.length,prev: '上一页',next: '下一页',layout: ['prev', 'page', 'next', 'count']},done: function (res, curr, count) {mergeRows(res)}});});}// 展示数据在表格function exportArr() {let array = [];deviceDiskStateArray.map(item => {let arr = [], arr2 = [], arr3 = [], obj = {};obj.deviceId = item.deviceId;item.diskStateInfoArray.map(value => {if (value.DiskType === 0) {obj.ypRL = toFixed(getGB(value.DiskCapacity), 2) + 'G';obj.ypLoading = constrAbx(value.MountType, 4);value.diskPartitionArray.map(node => {if (node.partitionIndex === 0) {node.partitionIndex = '0';}let ypObj = {partitionIndex: node.partitionIndex,ypDBRState: constrAbx(node.DBRState, 4),ypFATState: constrAbx(node.FATState, 4),ypINDEXFileState: constrAbx(node.INDEXFileState, 4)}arr.push(ypObj);});} else if (value.DiskType === 1) {obj.s1RL = toFixed(getGB(value.DiskCapacity), 2) + 'G';obj.s1Loading = constrAbx(value.MountType, 4);value.diskPartitionArray.map(node => {if (node.partitionIndex === 0) {node.partitionIndex = '0';}let s1Obj = {partitionIndex: node.partitionIndex,s1DBRState: constrAbx(node.DBRState, 4),s1FATState: constrAbx(node.FATState, 4),s1INDEXFileState: constrAbx(node.INDEXFileState, 4)}arr2.push(s1Obj);});} else if (value.DiskType === 2) {obj.s2RL = toFixed(getGB(value.DiskCapacity), 2) + 'G';obj.s2Loading = constrAbx(value.MountType, 4);value.diskPartitionArray.map(node => {if (node.partitionIndex === 0) {node.partitionIndex = '0';}let s2Obj = {partitionIndex: node.partitionIndex,s2DBRState: constrAbx(node.DBRState, 4),s2FATState: constrAbx(node.FATState, 4),s2INDEXFileState: constrAbx(node.INDEXFileState, 4)}arr3.push(s2Obj);});}});let stubborn = [{}, {}, {}, {}];if (arr.length !== 0) {arr.map((value, index) => {let obj2 = {};obj2.ypRL = obj.ypRL;obj2.deviceId = obj.deviceId;obj2.ypLoading = obj.ypLoading;obj2.partitionIndex = value.partitionIndex;obj2.ypDBRState = value.ypDBRState;obj2.ypFATState = value.ypFATState;obj2.ypINDEXFileState = value.ypINDEXFileState;stubborn[index] = obj2;});}if (arr2.length !== 0) {arr2.map((value, index) => {let obj2 = {};obj2.s1RL = obj.s1RL;obj2.deviceId = obj.deviceId;obj2.s1Loading = obj.s1Loading;obj2.partitionIndex = value.partitionIndex;obj2.s1DBRState = value.s1DBRState;obj2.s1FATState = value.s1FATState;obj2.s1INDEXFileState = value.s1INDEXFileState;Object.assign(stubborn[index], obj2)});}if (arr3.length !== 0) {arr3.map((value, index) => {let obj2 = {};obj2.s2RL = obj.s2RL;obj2.deviceId = obj.deviceId;obj2.s2Loading = obj.s2Loading;obj2.partitionIndex = value.partitionIndex;obj2.s2DBRState = value.s2DBRState;obj2.s2FATState = value.s2FATState;obj2.s2INDEXFileState = value.s2INDEXFileState;Object.assign(stubborn[index], obj2)});}stubborn.map(item => {if (item.deviceId != undefined) {array.push(item)}})});videoData = array;render();}// 导出function exportData() {let arr5 = [], arrField = [];colsListFalse.map((item, index) => {arr5.push(item.title);arrField.push(item.field);});if (videoData.length > 0) {let dataLists = PlExportExcel.formatJson(arrField, videoData);PlExportExcel.exportJsonToExcel({header: arr5,data: dataLists,filename: 'diskInfo_' + getDateInfo(1),autoWidth: true,bookType: 'xlsx'});} else {layer.open({title: '提示',content: '无数据'});}}// 这里是从别人那里拷贝来的代码function mergeRows(res) {var data = res.data;var mergeIndex = 0;//定位需要添加合并属性的行数var mark = 1; //这里涉及到简单的运算,mark是计算每次需要合并的格子数// var columsName = ['deviceId', 'ypRL', 'ypLoading', 's1RL', 's1Loading', 's2RL', 's2Loading'];//需要合并的列名称var columsName = ['deviceId'];//需要合并的列名称// var columsIndex = [0, 2, 3, 7, 8, 12, 13];//需要合并的列索引值var columsIndex = [0];//需要合并的列索引值for (var k = 0; k < columsName.length; k++) { //这里循环所有要合并的列var trArr = $('div[lay-id="videoTable"] .layui-table-body>.layui-table').find("tr");//所有行,如果页面多个表格,这里一定要定位到你所要合并的表格for (var i = 1; i < res.data.length; i++) { //这里循环表格当前的数据var tdCurArr = trArr.eq(i).find("td").eq(columsIndex[k]);//获取当前行的当前列var tdPreArr = trArr.eq(mergeIndex).find("td").eq(columsIndex[k]);//获取相同列的第一列if (data[i][columsName[k]] === data[i - 1][columsName[k]]) { //后一行的值与前一行的值做比较,相同就需要合并mark += 1;tdPreArr.each(function () {//相同列的第一列增加rowspan属性$(this).attr("rowspan", mark);});tdCurArr.each(function () {//当前行隐藏$(this).css("display", "none");});} else {mergeIndex = i;mark = 1;//一旦前后两行的值不一样了,那么需要合并的格子数mark就需要重新计算}}mergeIndex = 0;mark = 1;}}// 时间默认值function getDateInfo(number) {let date = new Date();let year = date.getFullYear();let month = byZero(date.getMonth(), 1);let day = byZero(date.getDate());let hour = byZero(date.getHours());let minute = byZero(date.getMinutes());let second = byZero(date.getSeconds());// date = formatTimebytype(date, 'yyyy-MM-dd');//将日期转换成yyyy-mm-dd格式var date2 = new Date(date.getFullYear(), 0, 1);var day1 = date.getDay();if (day1 == 0) day1 = 7;var day2 = date2.getDay();if (day2 == 0) day2 = 7;let d = Math.round((date.getTime() - date2.getTime() + (day2 - day1) * (24 * 60 * 60 * 1000)) / 86400000);//当周数大于52则为下一年的第一周if ((Math.ceil(d / 7) + 1) > 52) {return (date.getFullYear() + 1) + "第1周"}if (number === 1) {return year + '-' + month + '-' + day + ' ' + hour + ':' + minute + ':' + second;} else if (number === 2) {return year + '-' + Number(month - 1) + ' - ' + year + '-' + month;} else if (number === 3) {return Math.ceil(d / 7) + 1;} else if (number === 4) {return year;} else if (number === 5) {return year + '-' + month + '-' + day + ' ' + '00:00:00';} else if (number === 6) {return year + '-' + month + '-' + day + ' ' + (hour - 1) + ':' + minute + ':' + second;}}// 时间默认值加零function byZero(number, type) {if (number >= 10) {return number;} else {if (type === 1) {number = number + 1;return '0' + number;} else {return '0' + number;}}}// 转换function constrAbx(num, number) {if (number === 4) {if (num === 0) {return '正常';} else if (num === 1) {return '异常';} else if (num === 2) {return '不一致';}}}// 小数点function toFixed(number, n) {let numberStr = number + "";let reg = /^(-|\+)?(\d+(\.\d*)?|\.\d+)$/i;if (!reg.test(numberStr)) {alert('输⼊的数字格式不对');return;}let sign = numberStr.charAt(0) === '-' ? (numberStr = numberStr.slice(1), -1) : 1; // 判断是否是负数let pointIndex = numberStr.indexOf("."); // 记录⼩数点的位置if (pointIndex > -1) {numberStr = numberStr.replace(".", "");} else { // 没有⼩数点直接添加补0;numberStr += ".";numberStr += new Array(n).join('0');return numberStr;}let numberArray = numberStr.split(""); //转成数组let len = numberArray.length;let oldPointNum = len - pointIndex; // 获取原数据有多少位⼩数if (oldPointNum < n) { // 要保留的⼩数点⽐原来的要⼤,直接补0while (n - oldPointNum > 0) {numberArray.push(0);n--;}} else if (oldPointNum > n) { // 模拟四舍五⼊let i = oldPointNum - n; // 从倒数第i个数字开始⽐较let more = numberArray[len - i] >= 5 ? true : false;while (more) {i++;more = +numberArray[len - i] + 1 === 10 ? true : false; // 进位后判断是否等于10,是则继续进位numberArray[len - i] = more && i !== (len + 1) ? 0 : +numberArray[len - i] + 1; // 其他位置的数字进位直接变成0,第⼀位的例外}numberArray.length = len - (oldPointNum - n); // 截取多余的⼩数}numberArray.splice(pointIndex, 0, ".");return sign === -1 ? '-' + numberArray.join("") : numberArray.join("");};function getGB(number) {return number / 1024 / 1024 / 1024;}</script><script>layui.use('layer', function () {let layer = layui.layer;let mediaFileLists = [{DeviceVideoFrame: 1977.5,SysConfigFrame: 3709,alarmType: [],avType: 9,endTime: "2022-08-04 11:04:42",logicalChannel: 1,startTime: "2022-08-04 08:07:26",storeType: 1,streamType: 1},{DeviceVideoFrame: 281.5,SysConfigFrame: 4077,alarmType: [],avType: 9,endTime: "2022-08-04 08:07:26",logicalChannel: 1,startTime: "2022-08-04 04:52:47",storeType: 1,streamType: 1},{DeviceVideoFrame: 3847.5,SysConfigFrame: 3600,alarmType: [],avType: 9,endTime: "2022-08-04 04:52:47",logicalChannel: 1,startTime: "2022-08-04 02:00:56",storeType: 1,streamType: 1},{DeviceVideoFrame: 2694.3,SysConfigFrame: 476,alarmType: [],avType: 9,endTime: "2022-08-04 02:00:02",logicalChannel: 1,startTime: "2022-08-04 01:37:23",storeType: 1,streamType: 1},{DeviceVideoFrame: 3361.7,SysConfigFrame: 2039,alarmType: [],avType: 9,endTime: "2022-08-04 01:37:23",logicalChannel: 1,startTime: "2022-08-04 00:00:00",storeType: 1,streamType: 1}];console.log(mediaFileLists);let arr = [];for (let i = 0; i < mediaFileLists.length; i++) {let a = mediaFileLists[i];if (a !== mediaFileLists[mediaFileLists.length - 1]) {let b = mediaFileLists[i + 1];console.log(a.startTime + '   ' + a.endTime)console.log(a.startTime, ' hhh ', b.endTime)if (a.startTime !== b.endTime) {arr.push('通道' + b.logicalChannel + '的 结束时间为: ' + b.endTime + ' 时间段丢帧');}}}console.log(arr)layer.msg(arr.toString(), {icon: 2,time: false,closeBtn: 1,offset: [$(window).height() - 100, $(window).width() / 2.5]});});</script>
</body></html>

JS导出合并行数据excel(js-xlsx)相关推荐

  1. 前端利用JS导出数据到Excel表 数字是文本类型 无法计算

    问题描述:前端利用JS导出数据到Excel表 数字是文本类型 无法进行公式计算:前端利用JS导出数据到Excel表 数字是文本类型 无法计算 解决办法:参考https://bbs.csdn.net/t ...

  2. js导出数据到excel,兼容ie浏览器

    建立Excle导出的js文件,在需要前台导出的页面中引用此js,调用methodExcel(tableid)方法,tableid为需要导出到excel的table表id. 将页面上的table显示内容 ...

  3. 前端通过js导出报表到excel(如果数据量很大的话,建议不要前端自己导出数据)

    function tableToExcel(title,datalist){//title 列名 datalist 需要导出的json文件var jsonData=datalist;//列标题,逗号隔 ...

  4. php导出复杂表头excel,js导出复杂表头(多级表头)的excel

    Document 姓名 一月 二月 收入支出收入支出张三10元20元15元25元李四100元200元150元250元 导出excel functiontableToExcel(){//要导出的数据 v ...

  5. js导出数据到excel纯数字过长如何将默认的科学计数法显示正常

    原因: 1.在Excel中,输入12-15位数字时,虽然会以科学记数的形式出现,但其数值大小是不变的.当今的身份证号码有15位和18位之分.如果15位身份证号以科学记数的形式出现,可以通过设置显示出身 ...

  6. JS技巧:兼容性导出表格为Excel文件

    项目中经常需要导出Excel文件,不在服务器端处理而是富客户端采用Javascript脚本处理数据并导出文件. Js导出表格为Excel文件 的常见一种办法是调用:ActiveXObject(&quo ...

  7. 精读《Excel JS API》

    Excel 现在可利用 js 根据单元格数据生成图表.表格,或通过 js 拓展自定义函数拓展内置 Excel 表达式. 我们来学习一下 Excel js API 开放是如何设计的,从中学习到一些开放 ...

  8. chrome将html转成excel,怎样在Chrome浏览器中,直接让表格中的数据以Excel文件形式导出|网页转excel表格...

    怎么把jsp页面表单上的数据导出成Excel-CSDN论坛 留个QQ,发给你个控件 在js导出表格到excel的时候,如何用js设置时间的的格式 将页面中指定的数据导入到Excel中 border=& ...

  9. 使用xlsx.full.min.js导出有复杂表头的excel(亲测有效)

    开篇 今天项目用到了导出table表格,但表头有点特殊,多个合并的单元格. 搜索了半天,发现有博主使用 xlsx.full.min.js 做过此类功能,使用的是vue+elementUI,特在该基础上 ...

最新文章

  1. LINUX分区空间扩容操作
  2. 用到的oracle sql语句-001
  3. spring boot 报错:Your ApplicationContext is unlikely to start due to a @ComponentScan of the default p
  4. 登录界面拦截java_java拦截通过url访问页面,必须通过登录页面访问目标页面
  5. ICCV 2019 | RankSRGAN:排序学习 + GAN 用于超分辨率
  6. Python的内置函数的学习笔记
  7. 快速集成二维码扫描,使用最新版本的zxing(2017.11.10抽取zxing代码)
  8. 问题二十:C++全局debug “ray tracing图形”实例
  9. php 数据访问框架,PHP Ice框架数据库访问层- Ice Framework(PHP Web开发框架)
  10. 【图像融合】基于matlab IHS变换与自适应区域特征遥感图像融合【含Matlab源码 1636期】
  11. 内存条上面参数详解_【硬件篇】第4期:内存条知识(台式机)
  12. [读书笔记]编程之美(一)
  13. 黑群晖二合一已损毁_黑群晖DSM6.2硬盘引导二合一镜像以及安装方法
  14. 3.9 JS制作登录验证码
  15. swfupload ajax,swfupload ajax无刷新上传图片实例代码
  16. matlab海龟交易策略,海龟交易策略
  17. linux磁盘满了删除docker文件夹,Docker磁盘空间使用分析与清理的方法
  18. 银行招考计算机专业考什么,银行笔试一般都考什么?
  19. 跳高女神oracle,她是跳高新星,颜值与实力并存,现被称为“最美跳高女神”!...
  20. 使用 Unity 和 C# 开发您的首个游戏

热门文章

  1. STM32常用协议之IIC协议详解
  2. 海美迪h7四代刷Linux,海美迪H7四代官方固件ROM升级包下载_刷机教程
  3. JS给数字添加千位分隔符
  4. GoogLeNet网络详解与模型搭建
  5. Ubuntu16.04更新源
  6. 三星手机S8曝光或再掀购机热潮
  7. 【神秘海域】[动图] 掌握 单链表 只需要这篇文章~ 「超详细」
  8. 阿里大文娱正式加入短视频竞争,一石二鸟
  9. js常见正则表达式验证
  10. linux dd删目录,dd命令详解(清除硬盘数据)