代码拉取完成,页面将自动刷新
layui.define(["jquery", "layer"], function (exports) {
"use strict";
var MOD_NAME = "layuiExcel",
$ = layui.jquery,
layer = layui.layer;
//表头样式
var HEAD_STYLES = {
font: { name: "Times New Roman", sz: "13", bold: true },
alignment: {
horizontal: "center",
vertical: "middle",
},
border: {
top: { style: "thin" },
bottom: { style: "thin" },
left: { style: "thin" },
right: { style: "thin" },
},
};
//导出文件默认参数
var EXCEL_FILETYPE = {
xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8",
csv: "application/octet-stream;charset=UTF-8",
};
//工具函数类
var Tools = function Tools() { };
//获取全局水印文字
Tools.prototype.getMcsWatermarkText = function (waterMark) {
return waterMark = waterMark ? waterMark : "添加水印";
};
Tools.prototype.getWatemarkBASE64 = function (waterMark) {
var id = "1.23452384164.123412416";
if (document.getElementById(id) !== null) {
document.body.removeChild(document.getElementById(id));
}
// 创建一个画布
var can = document.createElement("canvas");
// 设置画布的长宽
can.width = 500;
can.height = 200;
var cans = can.getContext("2d");
// 旋转角度
cans.rotate((-15 * Math.PI) / 180);
// 设置字体大小
cans.font = "18px Microsoft YaHei";
// 设置填充绘画的颜色、渐变或者模式
cans.fillStyle = "rgba(0, 0, 0, 0.1)";
// 设置文本内容的当前对齐方式
cans.textAlign = "center";
// 设置在绘制文本时使用的当前文本基线
cans.textBaseline = "Middle";
cans.fillText(waterMark, 80, 180);
var base64 = can.toDataURL("image/png");
return base64;
};
//绘制文字图片水印
Tools.prototype.setWatermark = function (workbook, worksheet, waterMark) {
waterMark = this.getMcsWatermarkText(waterMark);
var base64 = this.getWatemarkBASE64(waterMark);
var imageId1 = workbook.addImage({ base64, extension: "png" });
worksheet.addBackgroundImage(imageId1);
};
//buffer转ArrayBuffer,因为layExcel已经内置FileSaver旧版本,用的是ArrayBuffer,需要转换一下,后期不用layExcel之后可以删除
Tools.prototype.toArrayBuffer = function (buf) {
var ab = new ArrayBuffer(buf.length);
var view = new Uint8Array(ab);
for (var i = 0; i < buf.length; ++i) {
view[i] = buf[i];
}
return ab;
};
//文件名处理
Tools.prototype.filenameDeal = function (filename, type) {
if (typeof filename === "string") {
if (filename.indexOf(".") < 0) {
filename += "." + type;
}
} else {
filename = "导出数据." + type;
}
return filename;
};
//获取表头的列名字母
Tools.prototype.numToTitle = function (num) {
var ans = "";
if (num > 26) {
//要注意小心26的倍数导致的无限递归问题
var dec = num % 26;
ans = this.numToTitle((num - dec) / 26) + this.numToTitle(dec ? dec : 26);
return ans;
} else {
//A的ASCII为65,顺位相加
ans = String.fromCharCode(64 + num);
return ans;
}
};
//获取表头的列名字母
Tools.prototype.getColName = function (colNum) {
var excelNameArray = [
"A",
"B",
"C",
"D",
"E",
"F",
"G",
"H",
"I",
"J",
"K",
"L",
"M",
"N",
"O",
"P",
"Q",
"R",
"S",
"T",
"U",
"V",
"W",
"X",
"Y",
"Z",
];
var integer = Math.floor(colNum / excelNameArray.length); //整数
var remainder = colNum % excelNameArray.length; //余数
var excelColName = "";
if (integer > 0) {
excelColName = excelNameArray[integer - 1];
}
excelColName += excelNameArray[remainder];
return excelColName;
};
//复杂表头递归重新得到表头数组
Tools.prototype.getNewHeader = function (header, newHeader, col, row) {
if (row == 0) {
return;
}
var item = header[col][0];
if (item == undefined) {
return;
}
//去除有type、templet、toolbar
if (item.type && item.type != "normal") {
header[col].shift();
this.getNewHeader(header, newHeader, col, --row);
return;
}
if (item.templet && !item.field) {
header[col].shift();
this.getNewHeader(header, newHeader, col, --row);
return;
}
if (item.toolbar && !item.field) {
header[col].shift();
this.getNewHeader(header, newHeader, col, --row);
return;
}
if (item.colGroup != undefined && item.colGroup) {
newHeader[col].push(item);
header[col].shift();
this.getNewHeader(header, newHeader, col + 1, item.colspan);
} else {
var field = item.field.toLowerCase();
newHeader[col].push(item);
header[col].shift();
}
this.getNewHeader(header, newHeader, col, --row);
};
//递归获取实际展示数据列
Tools.prototype.getHeaderColumns = function (header, col, row, columns) {
if (row == 0) {
return;
}
var item = header[col][0];
if (item == undefined) {
header[col].shift();
this.getHeaderColumns(header, col, --row, columns);
return;
}
if (item.colGroup != undefined && item.colGroup) {
header[col].shift();
this.getHeaderColumns(header, col + 1, item.colspan, columns);
} else {
columns.push({ header: item.title, key: item.field.toLowerCase() });
header[col].shift();
}
this.getHeaderColumns(header, col, --row, columns);
};
//多层表头设置表头单元格
Tools.prototype.headerMergeRowSet = function (worksheet, header) {
//单元格计数数组
var cellNumber = new Array(header.length).fill(-1);
var newHeader = new Array();
//转换成单个数组,向右合并要递归
this.headerMergeDeal(cellNumber, header, newHeader, 0, 0, header[0].length);
//单元格设置
for (var i = 0; i < newHeader.length; i++) {
var cellItem = newHeader[i];
var cell = worksheet.getCell(cellItem.cellName);
cell.value = cellItem.title;
if (cellItem.cellName != cellItem.cellMerge) {
worksheet.mergeCells(cellItem.cellName + ":" + cellItem.cellMerge);
}
}
};
/**
* 递归处理layui的多层表头,只向下和向右合并
* @param {any} cellNumber 计数定位单元格
* @param {any} header 原表头数组
* @param {any} newHeader 新表头数组
* @param {any} arrLength 数组层级
* @param {any} num 从0开始
* @param {any} colLength 数组长度
* @returns
*/
Tools.prototype.headerMergeDeal = function (
cellNumber,
header,
newHeader,
arrLength,
num, colLength
) {
if (num == colLength) {
return;
}
cellNumber[arrLength]++;
var item = header[arrLength][0];
item.colspan = item.colspan == 0 ? 1 : item.colspan;
item.rowspan = item.rowspan == 0 ? 1 : item.rowspan;
var colName = this.getColName(cellNumber[arrLength]);
item.cellName = colName + "" + (arrLength + 1);
header[arrLength].shift();
if (item.colspan == 1 && item.rowspan > 1) {
//向下合并
for (var cc = 1; cc < item.rowspan; cc++) {
cellNumber[cc + arrLength]++;
}
item.cellMerge = colName + "" + (item.rowspan + arrLength);
newHeader.push(item);
} else if (item.colspan > 1 && item.rowspan == 1) {
//向右合并
for (var cc = 1; cc < item.colspan; cc++) {
cellNumber[arrLength]++;
}
item.cellMerge =
this.getColName(cellNumber[arrLength]) + "" + (arrLength + 1);
newHeader.push(item);
this.headerMergeDeal(
cellNumber,
header,
newHeader,
arrLength + 1,
0,
item.colspan,
0
);
num = arrLength > 0 ? num + item.colspan - 1 : num;
} else {
item.cellMerge = item.cellName;
newHeader.push(item);
}
this.headerMergeDeal(
cellNumber,
header,
newHeader,
arrLength,
++num,
colLength
);
};
//数据行处理
Tools.prototype.rowDeal = function (worksheet, data) {
// 将数组中每个对象的属性名转换为小写
data.map((obj) => {
// 使用 Object.keys 获取当前对象的所有键
var newObj = Object.keys(obj).reduce((acc, key) => {
// 将键转为小写并设置到新的对象中
var newKey = key.toLowerCase();
acc[newKey] = obj[key];
return acc;
}, {});
worksheet.addRow(newObj);
});
};
//表头样式设置
Tools.prototype.setHeaderStyle = function (worksheet, headerNum) {
for (var i = 1; i <= headerNum; i++) {
var row = worksheet.getRow(i);
row.eachCell(function (cell, colNumber) {
cell.style = HEAD_STYLES;
});
}
var lastRow = worksheet.getRow(headerNum);
var rowSize = lastRow.cellCount - 1;
// 设置自动过滤器
worksheet.autoFilter = {
from: "A" + headerNum,
to: this.getColName(rowSize) + "" + headerNum,
};
};
Tools.prototype.formatDate = function (date, format) {
var pad = (num) => (num < 10 ? "0" + num : num);
return format
.replace(/yyyy/g, date.getFullYear())
.replace(/MM/g, pad(date.getMonth() + 1))
.replace(/dd/g, pad(date.getDate()))
.replace(/HH/g, pad(date.getHours()))
.replace(/mm/g, pad(date.getMinutes()))
.replace(/ss/g, pad(date.getSeconds()));
};
//es6:递归多层深拷贝
Tools.prototype.deepCopy = function (source) {
if (typeof source != "object") {
return source;
}
if (source == null) {
return source;
}
var newObj = source.constructor === Array ? [] : {}; //开辟一块新的内存空间
for (var i in source) {
newObj[i] = this.deepCopy(source[i]);
}
return newObj;
};
/**
* 针对layui的数据表格封装,自动处理多层表头,表头列名重复会有一列缺少数据
* 需要下列js
* ExcelJS版本v4.4.0
* FileSaver版本v2.0.4
* layui版本v2.9.18
* @returns
*/
var LAYUI_EXCEL = function () {
this.v = "1.0";
if (typeof ExcelJS == "undefined") {
layer.msg("请先加载ExcelJS");
console.error("请先加载ExcelJS");
return;
}
if (typeof saveAs !== "function") {
layer.msg("请先加载FileSaver");
console.error("请先加载FileSaver");
return;
}
};
var tools = new Tools();
/**
* 自动解析layui表格的表头参数并导出单个工作表,默认格式xlsx
* @param {any} header 表头
* @param {any} data 数据
* @param {any} filename 文件名
*/
LAYUI_EXCEL.prototype.exportExcelXlsx = function (header, data, filename) {
var _this = this;
var type = "xlsx";
filename = tools.filenameDeal(filename, type);
var workbook = new ExcelJS.Workbook();
var nowDate = new Date();
workbook.creator = "layui";
workbook.lastModifiedBy = "layui";
workbook.created = nowDate;
workbook.modified = nowDate;
workbook.lastPrinted = nowDate;
var worksheet = workbook.addWorksheet("sheet1");
//设置背景水印
// tools.setWatermark(workbook, worksheet);
var columns = new Array();
var copyHeader = tools.deepCopy(header);
var newHeader = new Array(header.length).fill(null).map(() => {
return new Array();
});
//处理特殊字段,返回新的表头
tools.getNewHeader(copyHeader, newHeader, 0, header[0].length);
var copyNewHeader = tools.deepCopy(newHeader);
//得到明细数据列
tools.getHeaderColumns(copyNewHeader, 0, copyNewHeader[0].length, columns);
worksheet.columns = columns;
//设置表头单元格,合并单元格
tools.headerMergeRowSet(worksheet, newHeader);
//设置表头样式
tools.setHeaderStyle(worksheet, header.length);
//添加数据行
tools.rowDeal(worksheet, data);
//导出文件
workbook.xlsx.writeBuffer().then((buffer) => {
var blob = new Blob([buffer], { type: EXCEL_FILETYPE[type] });
saveAs(blob, filename);
});
};
//自动完成渲染
var layuiExcel = new LAYUI_EXCEL();
exports(MOD_NAME, layuiExcel);
});
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。