SheetJs 导出数据
1.Excel数据导出
根据后端数据导出
数据源样式
list = [
{ code: '610230', name: '长尺', num: 2, price: 3.5, amount: 7, type: 1, status: 2 },
{ code: '610230', name: '圆规', num: 6, price: 5, amount: 30, type: 1, status: 1 },
{ code: '610230', name: '板材12*12', num: 100, price: 23.5, amount: 2350, type: 1, status: 2 }
];
导出
exportBasicInfo(list: any[]) { let datas = []; //根据数据源中数据列名来定义展示的顺序 const header = [ 'index', 'code', 'name', 'num',
'price', 'amount' ]; //#region 表头组合 根据header中选中显示的数据列来对应定义数据表中列显示的数据 const headerDisplay1 = { index: `XXXX${DateTime.fromJSDate(new Date()).toFormat('MM')}-月盘点` }; //#endregion //#region 表尾 const headerDisplay2 = { index: '序号', code: '编码', name: '名称', num: '数量',
price: '单价', amount: '金额' }; const endDisplay = { code: '制表人:', amount: '审核人:' }; //#endregion //增加序号列,若源数据中含有header中定义以外的数据列,且不展示,需要将其他数据列移除掉 for (let index = 0; index < list.length; index++) { datas.push({ index: index + 1, code: list[index].gode, name: list[index].name, num: list[index].num,
price: list[index].price, amount: list[index].amount }); } //表头要放数据数组的前面,表尾要放在数据数组的后面 const newData = [headerDisplay1, headerDisplay2, ...datas, endDisplay]; //header与datas中的属性对应,skipHeader为true表示忽略原来的表头(忽略源数据datas中除header以外的数据表头) var worksheet = utils.json_to_sheet(newData, { header: header, skipHeader: true }); //第一行标题 this.setCellStyle(worksheet, 0, 0, 0, 5, '16', true); //第二行标题 this.setCellStyle(worksheet, 1, 1, 0, 5, '12', true); //数据行 this.setCellStyle(worksheet, 4, 4 + datas.length - 1, 0, 5, '9', false); //末尾行 this.setCellStyle(worksheet, 4 + datas.length, 4 + datas.length, 0, 5, '9', true); //表格样式 this.initSheetStyle(worksheet); /* 生成Excel文件 */ var workbook = utils.book_new(); /* 将工作簿添加到工作簿集合中 */ utils.book_append_sheet(workbook, worksheet, `${DateTime.fromJSDate(new Date(form.stockTakingDate)).toFormat('yyyy-MM-dd')}盘点表`); /* 导出Excel文件 */ writeFile(workbook, `备品备件${DateTime.fromJSDate(new Date(form.stockTakingDate)).toFormat('MM')}-月盘点.xlsx`); }
单元格样式
/** * 设置单元格样式 * @param worksheet 工作单元 * @param firstRow 开始行 * @param lastRow 结束行 * @param firstCol 开始列 * @param lastCol 结束列 * @param font 字号 * @param blod 是否加粗 */ setCellStyle(worksheet: WorkSheet, firstRow, lastRow, firstCol, lastCol, font, blod) { //金额列 var cols1 = new Set([4, 5]); for (var i = firstRow; i <= lastRow; i++) { for (var j = firstCol; j <= lastCol; j++) { //根据单元格地址转换为A1样式 var cell = utils.encode_cell({ c: j, r: i }); if (worksheet[cell]) { worksheet[cell].s = { font: { sz: font, bold: blod }, alignment: { horizontal: 'center', vertical: 'center' //是否自动换行 默认值false // wrapText: true }, border: { top: { style: 'thin' }, right: { style: 'thin' }, bottom: { style: 'thin' }, left: { style: 'thin' } }, //'@' 文本格式 第三行开始4、5列以金额格式显示,第3列以数字格式展示 numFmt: i > 1 && cols1.has(j)? '0.00' : i > 1 && j==3 ? '0' : '@' }; } else { //为空的单元格设置空值并加上边框 worksheet[cell] = { s: { border: { top: { style: 'thin' }, right: { style: 'thin' }, bottom: { style: 'thin' }, left: { style: 'thin' } } }, v: '' }; } } } }
表格样式
initSheetStyle(worksheet: WorkSheet) { //列宽 worksheet['!cols'] = [ { wpx: 80 }, //设置第1列列宽为80像素 { wpx: 100 }, { wpx: 100 }, { wpx: 80 }, { wpx: 80 }, { wpx: 80 } ]; //行高 worksheet['!rows'] = [{ hpx: 21 }, { hpx: 20 }];
//合并单元格 //获取工作表的范围 const range = utils.decode_range(worksheet['!ref']); worksheet['!merges'] = [ { s: { c: 0, r: 0}, //A1 e: { c: 5, r: 0} //F1 }, //末尾行 { s: { c: 0, r: range.e.r - 1 }, e: { c: 1, r: range.e.r - 1 } } ]; }
合并单元格的另外一种方式,通过单元格名称指定单元格区域
//表示合并第一行的第1列到第6列 worksheet['!merges'].push(utils.decode_range('A1:F1'));
单元格地址转换
根据单元格行列序号转换为A1样式
//转换为A2 var a1_addr = XLSX.utils.encode_cell({r:1, c:0});
将A1样式转换单元格为行号列号
//{c: 0, r: 1} var address = XLSX.utils.decode_cell("A2");
单元格区域转换
根据单元格行列序号转换为A1样式区域
//A1:D3 var a1_range = XLSX.utils.encode_range({ s: { c: 0, r: 0 }, e: { c: 3, r: 2 } });
将A1样式转换单元格区域行号列号
//{ s: { c: 0, r: 0 }, e: { c: 3, r: 2 } } var range = XLSX.utils.decode_range("A1:D3");