import * as XLSX from 'xlsx' /* * @description: * @param {Object} json 服务端发过来的数据 * @param {String} name 导出Excel文件名字 * @param {String} titleArr 导出Excel表头 * @param {String} sheetName 导出sheetName名字 * @return: */ export interface excelType { json: object name: string titleArr: string[] sheetName: string } export function exportExcel(params: excelType) { /* convert state to workbook */ const data = [] const keyArray = [] const getLength = function (obj: object) { let count = 0 for (const i in obj) { if (Object.prototype.hasOwnProperty.call(obj, i)) { // if (obj.hasOwnProperty(i)) { count++ } } return count } for (const key1 in params.json) { if (Object.prototype.hasOwnProperty.call(params.json, key1)) { const element = (params.json as { [key: string]: object })[key1] const rowDataArray = [] for (const key2 in element) { if (Object.prototype.hasOwnProperty.call(element, key2)) { const element2 = (element as { [key: string]: object })[key2] rowDataArray.push(element2) if (keyArray.length < getLength(element)) { keyArray.push(key2) } // console.log(keyArray, 'keyArray') } } data.push(rowDataArray) } } // keyArray为英文字段表头 data.splice(0, 0, keyArray as any, params.titleArr as any) // console.log('data', data) const ws = XLSX.utils.aoa_to_sheet(data) const wb = XLSX.utils.book_new() // 表头样式(灰色背景、加粗字体、居中对齐) const headerStyle = { fill: { fgColor: { rgb: 'D3D3D3' } }, font: { bold: true, sz: 12, // 字体大小 color: { rgb: '000000' } }, alignment: { horizontal: 'center', vertical: 'center' }, border: { top: { style: 'thin', color: { rgb: '000000' } }, bottom: { style: 'thin', color: { rgb: '000000' } }, left: { style: 'thin', color: { rgb: '000000' } }, right: { style: 'thin', color: { rgb: '000000' } } } } // 数据样式(居中对齐、边框) const dataStyle = { alignment: { horizontal: 'center', vertical: 'center' }, } // 此处隐藏英文字段表头 const wsrows = [{ hidden: true }] /* 设置worksheet每列的最大宽度 */ const colWidth = data.map(row => row.map((val) => { /* 先判断是否为null/undefined */ if (val == null) { return { wch: 10, } } /* 再判断是否为中文 */ else if (val.toString().charCodeAt(0) > 255) { return { wch: val.toString().length * 2, } } else { return { wch: val.toString().length, } } })) // 获取表格范围 const range = XLSX.utils.decode_range(ws['!ref']); console.log(range, 'range') // 应用表头样式(第二行,因为第一行被隐藏) for (let c = range.s.c; c <= range.e.c; c++) { const cellAddress = XLSX.utils.encode_cell({ r: 1, c }); if (ws[cellAddress]) ws[cellAddress].s = headerStyle; } // 应用数据样式(从第三行开始) for (let r = 2; r <= range.e.r; r++) { for (let c = range.s.c; c <= range.e.c; c++) { const cellAddress = XLSX.utils.encode_cell({ r, c }); if (ws[cellAddress]) ws[cellAddress].s = dataStyle; } } /* 以第一行为初始值 */ const result = colWidth[0] for (let i = 1; i < colWidth.length; i++) { for (let j = 0; j < colWidth[i].length; j++) { if (result[j].wch < colWidth[i][j].wch) { result[j].wch = colWidth[i][j].wch } } } ws['!cols'] = result ws['!rows'] = wsrows // ws - worksheet XLSX.utils.book_append_sheet(wb, ws, params.sheetName) /* generate file and send to client */ XLSX.writeFile(wb, `${params.name}.xlsx`, { bookType: 'xlsx', type: 'array' }) }