UNPKG

@emmafgy/jsontoexcel

Version:

json export excel

289 lines (257 loc) 7.53 kB
/** * 原生js导出excel */ let excelObj = { list: [], headerConfig: [], fileds: [], tableId: "@emmafgyTable", fileName: "@emmafgy", fileSuffix: ".xls", tableBorderWidth: 1, filedsOtherConfig: { style: { // filed1:'mso-number-format:"\@";' } }, nodata: "", // 配置无数据显示内容 tdDataObjTemplate: { styleFiled: "style", valueFiled: "value" }, // json row data set style enableOrder: false, // 是否开启序号 customRowFunctionMap: {}, // 自定义行value 函数 /** * */ exportByJson: function(fileName = "", list = [], headerConfig = [], fileds = [], filedsOtherConfig = {}) { this.list = list; this.headerConfig = headerConfig; this.fileds = fileds; this.filedsOtherConfig = filedsOtherConfig; fileName && (this.fileName = fileName); this.start(); }, start: function() { this.check(); var tableHtml = this.createTableHtml(); // console.log(tableHtml); this.exportByDomString(tableHtml); }, defaultStart: function({ list, fileName, // filterFileds = null, // 废弃 // filterFiledsLabelObj = null, // 废弃 filedsMap = null, customRowFunctionMap = null, }) { if (!Array.isArray(list) || list.length < 1) { throw new Error("list必须是数组,list 参数的长度必须大于1"); } let keys = (filedsMap && Object.keys(filedsMap)) || Object.keys(list[0]); let headerConfig = []; let fileds = keys; let tmpArr = keys.map(key => { let label = key; if (filedsMap.hasOwnProperty(key) && filedsMap[key]) { label = filedsMap[key]; } return { label }; }); headerConfig[0] = tmpArr; this.list = list; this.headerConfig = headerConfig; this.fileds = fileds; this.fileName = fileName || this.fileName; customRowFunctionMap && (this.customRowFunctionMap = customRowFunctionMap); this.start(); }, /** * 通过dom Sting 导出 * @param {Object} tableHtml * @param {Object} fileName */ exportByDomString: function(tableHtml) { //判断是否IE浏览器 const isIE = () => { if (!!window.ActiveXObject || "ActiveXObject" in window) { return true; } else { return false; } } var htm = ` <html xmlns:x="urn:schemas-microsoft-com:office:excel"> <head><meta charset="UTF-8"> <x:ExcelWorkbook> <x:ExcelWorksheets> <x:ExcelWorksheet> <x:WorksheetOptions> <x:Print> <x:ValidPrinterInfo /> </x:Print> </x:WorksheetOptions> </x:ExcelWorksheet> </x:ExcelWorksheets> </x:ExcelWorkbook> </xml> </head> <style>table{vnd.ms-excel.numberformat:@;}</style> <body> `; htm += tableHtml; htm += '</body></html>'; var excelBlob = new Blob([htm], { type: 'application/vnd.ms-excel' }); if (isIE()) { window.navigator.msSaveOrOpenBlob(excelBlob, this.fileName + this.fileSuffix); } else { var oa = document.createElement('a'); var href = window.URL.createObjectURL(excelBlob); oa.href = href; oa.download = this.fileName + this.fileSuffix; document.body.appendChild(oa); oa.click(); document.body.removeChild(oa); // 下载完成移除元素 window.URL.revokeObjectURL(href); // 释放掉blob对象 } }, // ================== check: function() { // throw new Error("test"); if (!Array.isArray(this.list) || this.list.length < 1) { throw new Error("list必须是数组,list 参数的长度必须大于1"); } if (!Array.isArray(this.fileds) || this.fileds.length < 1) { throw new Error("fileds必须是数组,fileds 参数的长度必须大于1"); } if (!Array.isArray(this.headerConfig) || this.headerConfig.length < 1) { throw new Error("headerConfig必须是数组,headerConfig 参数的长度必须大于1"); } else { if (!Array.isArray(this.headerConfig[0])) { throw new Error("headerConfig 必须是二维数组"); } } }, createTableHtml: function() { var tableHtml = `<table border="${this.tableBorderWidth}" id="${this.tableId}">`; tableHtml += this.createTableHeader(); tableHtml += this.createTableBody(); tableHtml += "</table>"; // console.log(tableHtml); return tableHtml; }, createTableHeader: function() { // 设置序号 if (this.enableOrder === true) { this.headerConfig[0].unshift({ label: '序号', colspan: 1, rowspan: this.headerConfig.length }); } var res = ""; this.headerConfig.forEach(tr => { var trDom = "<tr>"; tr.forEach(td => { var { colspan = 1, rowspan = 1, label = "" } = td; var tdDom = `<th rowspan="${rowspan}" colspan="${colspan}">${label}</th>`; trDom += tdDom; }); trDom += "</tr>"; res += trDom; }); return res; }, createTableBody: function() { var res = ""; this.list.forEach((trData, index) => { var trDom = "<tr>"; var row = index + 1; // 设置序号 if (this.enableOrder === true) { trDom += `<td style=''>${row}</td>`; } this.fileds.forEach(filed => { var tdData = ""; var styleString = ""; // set sourceValue var sourceValue = ""; if (Object.prototype.toString.call(filed) == "[object String]") { // 设置field 样式 if (this.filedsOtherConfig.style.hasOwnProperty(filed)) { styleString += this.filedsOtherConfig.style[filed]; } // 设置td值 // if (trData.hasOwnProperty(filed)) { if (this.customRowFunctionMap.hasOwnProperty(filed)) { // 传入了该字段自定义函数 let customRowFunc = this.customRowFunctionMap[filed]; if (Object.prototype.toString.call(customRowFunc) == "[object Function]") { sourceValue = customRowFunc(trData[filed], trData); } else { throw new Error(filed + "_customRowFunctionMap type error,only function"); } } else { sourceValue = trData[filed]; } // } } else { throw new Error("filed type error,only string/function"); } // else if (Object.prototype.toString.call(filed) == "[object Function]") { // 自定义值 // sourceValue = filed(trData); // } // set tdData if ((sourceValue || sourceValue == 0)) { // 判断数据类型 if (Object.prototype.toString.call(sourceValue) == "[object Array]") { tdData = sourceValue.toString(); } else if (Object.prototype.toString.call(sourceValue) == "[object Object]") { // 如果类型是Object 则设置改td值的样式 let data = sourceValue[this.tdDataObjTemplate.valueFiled]; let style = sourceValue[this.tdDataObjTemplate.styleFiled]; tdData = data; styleString += style; } else { tdData = sourceValue || this.nodata; } } else { tdData = this.nodata; } var tdDom = `<td style='${styleString}'>${tdData}</td>`; trDom += tdDom; }); trDom += "</tr>"; res += trDom; }) return res; }, }; /** * 深拷贝 * @param {Object} obj */ const clone = (obj) => { let res; if (typeof obj == 'object' && obj != null) { res = obj instanceof Array ? [] : {}; for (let i in obj) { res[i] = clone(obj[i]); } } else { res = obj; } return res; } const getExcelObj = _ => clone(excelObj); export default getExcelObj;