一. 概览
前端导出excel是比较常见的需求,比如下载excel模板和批量导出excel。目前比较常用的库有xlsx和excel,接下来就着两种方式进行梳理。
二. 下载模板
xlsx库实现:
示例核心代码如下:
javascript
const excelColumn = {
details: {
materialName: '物料名称',
applyCount: '请购数量',
unit: '单位',
unitPrice: '单价',
use: '用途',
remark: '备注',
},
};
function downloadTemplate(key, name) {
const book = utils.book_new();
// 实例化一个Sheet
const sheet = utils.json_to_sheet(
[
Object.values(excelColumn[key]).reduce((p: any, c: string) => {
p[c] = '';
return p;
}, {}),
],
{
header: Object.values(excelColumn[key]),
},
);
// 将Sheet写入工作簿
utils.book_append_sheet(book, sheet, 'Sheet1');
// 写入文件,直接触发浏览器的下载
writeFile(book, `${name}.xlsx`);
}
代码分析:
javascript
// 实例化一个Sheet
const sheet = utils.json_to_sheet(
[
Object.values(excelColumn[key]).reduce((p: any, c: string) => {
p[c] = '';
return p;
}, {}),
],
{
header: Object.values(excelColumn[key]),
},
);
- utils.json_to_sheet第一个参数是为了得到一个诸如 {物料名称: '' ", 数量: " "}的数据,通过reduce方法实现对象属性的累加;
- header: Object.values(excelColumn[key]): 第二个参数是为了得到的表头的集合,诸如["物料名称","数量"]
javascript
utils.book_append_sheet(book, sheet, 'Sheet1');
- sheet1是定义工作簿的名称
exceljs库实现
示例核心代码如下:
javascript
const excelHeadColums = [
{
header: '物料名称',
key: 'materialName',
width: 12,
},
{
header: '请购数量',
key: 'applyCount',
width: 14,
},
{
header: '单位',
key: 'unit',
width: 14,
}
];
const downLoadTemp = () => {
// 创建工作簿
const workbook = new ExcelJS.Workbook();
// 添加工作表
const sheet1 = workbook.addWorksheet('sheet1');
sheet1.columns = excelHeadColums;
data.value.details.forEach((item) => {
sheet1.addRow(item);
});
// 导出表格
workbook.xlsx.writeBuffer().then((buffer) => {
let _file = new Blob([buffer], {
type: 'application/octet-stream',
});
FileSaver.saveAs(_file, '模板.xlsx');
});
};
代码分析:
原理基本同xlsx,只不过相比之下,exceljs库更为强大,可以自定义导出的excel的样式
三. 批量导出
xlsx库:
javascript
function exportExcel<T>(
name: string,
key: string,
colFn?: (d: T) => Record<string, any>,
{
format,
}: {
format?: (d: T, c: string) => string;
} = {},
) {
const book = utils.book_new();
const tableData = data.value![key].map((d) =>
colFn
? colFn(d)
: (Object.keys(excelColumn[key]).reduce((p, c) => {
p[excelColumn[key][c]] = format ? format(d, c) : d[c];
return p;
}, {}) as any),
);
const sheet = utils.json_to_sheet(tableData, {
header: Object.keys(tableData[0]),
});
utils.book_append_sheet(book, sheet, 'Sheet1');
writeFile(book, `${name}.xlsx`);
}
exceljs库:
javascript
const exportReturnData = (hkDetails) => {
// 创建工作簿
const workbook = new ExcelJS.Workbook();
// 添加工作表
const sheet1 = workbook.addWorksheet('sheet1');
sheet1.columns = receiptTableHeadColums;
const hkColumsData = hkDetails;
hkColumsData.forEach((item) => {
sheet1.addRow(item);
});
// 设置表头样式
const titleCell = sheet1.getRow(1);
// 设置第一行的高度
titleCell.height = 30;
// 设置第一行的字体样式
titleCell.font = {
bold: true,
};
// 设置第一行文字对齐方式
titleCell.alignment = {
vertical: 'middle',
horizontal: 'center',
};
// 设置第一行单元格的背景色
titleCell.fill = {
type: 'pattern',
pattern: 'solid',
fgColor: {
argb: 'FFDFEAFC',
},
};
// 导出表格
workbook.xlsx.writeBuffer().then((buffer) => {
let _file = new Blob([buffer], {
type: 'application/octet-stream',
});
FileSaver.saveAs(_file, '数据表.xlsx');
});
};
代码分析:
- 原理基本同下载模板,另附exceljs库样式调整的基本应用。
四. excel库的其它基本使用
excel库除了设置单元格样式外,另外常见的使用有设置单元格下拉框,限制某个单元格不可编辑等
1. 设置下拉框
核心代码
javascript
const sheet1 = workbook.addWorksheet('sheet1');
for (let i = 2; i < totalExcelLength + 1; i++) {
sheet1.getCell(`M${i}`).dataValidation = {
type: 'list',
allowBlank: true,
formulae: [`"中标,流标"`],
};
sheet1.getCell(`N${i}`).dataValidation = {
type: 'list',
allowBlank: true,
formulae: [`"最高价,最低价"`],
};
}
2. 限制某个单元格不可编辑
核心代码
javascript
sheet1.protect('yourpassword', {
selectLockedCells: true,
selectUnlockedCells: true,
});
//解锁可编辑列
const unlockColumns = isInitProcess ? [9, 10, 11] : [13, 14];
unlockColumns.forEach((columnIndex) => {
sheet1.getColumn(columnIndex).eachCell((cell, rowNumer) => {
if (rowNumer !== 1) {
// 跳过标题行
cell.protection = { locked: false };
}
});
});
另外还有exceljs还有其它很多强大的功能,在这就不一一举例。