前段时间写过一篇类似的文章,介绍了sheetjs。最近发现了一个更好用的库ExcelJS,它支持高级的样式自定义,并且使用起来也不复杂。实际上sheetjs也支持高级自定义样式,不过需要使用付费版。
下面对比了Exceljs和Sheetjs:
ExcelJS主要用于Node.js环境,它是一个Node.js库。因此,它的核心功能是为Node.js应用程序提供操作Excel文件的接口。虽然ExcelJS本身是为Node.js设计的,但它也提供了在浏览器端使用的版本。
前端实现Excel导出下载
先来看下功能演示,如下图把表格中的数据下载到excel文件中
export const exportExcel = (data: DataType[] ) => {
const headerStyle = {
font: {
name: 'Arial',
family: 4,
size: 12,
bold: true,
// color: { argb: 'FF0000' }
},
fill: {
type: 'pattern',
pattern: 'solid',
// fgColor: { argb: 'FFFF00' },
// bgColor: { argb: 'FFFF00' }
},
alignment: {
vertical: 'middle',
horizontal: 'center'
},
border: {
top: {style: 'thin', color: {argb: '000000'}},
left: {style: 'thin', color: {argb: '000000'}},
bottom: {style: 'thin', color: {argb: '000000'}},
right: {style: 'thin', color: {argb: '000000'}}
}
};
const headerTitle = ['APP', '名称', '作品数']
const workbook = new ExcelJS.Workbook();
const ws = workbook.addWorksheet("Sheet1")
ws.addRow(headerTitle)
.eachCell((cell) => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
cell.style = headerStyle
})
data.forEach(it=> {
ws.addRow(Object.values({
app: it.app,
name: it.name,
works: it.works
}))
})
ws.columns = headerTitle.map((header) => ({
header, key: header, width: 20
}))
workbook.xlsx.writeBuffer()
.then(buffer => {
// 创建 Blob 对象
const blob = new Blob([buffer], {type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'});
// 创建下载链接
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `exceljs.xlsx`;
a.click();
// 清理 URL
setTimeout(() => {
window.URL.revokeObjectURL(url);
a.remove();
}, 100);
})
.catch(err => console.error('Error creating file:', err));
}
这段代码实现的功能是:
使用ExcelJS.Workbook()创建一个Workbook对象
使用addWorksheet("Sheet1")向Workbook中添加一个sheet
使用addRow方法先加入表头,再使用eachCell为表头单元格设置样式,后面添加数据也是使用这个方法
最后通过模拟点击a标签下载xlsx
前端实现Excel上传解析
将上面下载的excel文件再次上传解析
这里使用antd的Upload组件获取到file文件对象,你可以可以使用原生的标签来上传。beforeUpload是上传前调用这个方法, 我们的目的是获取到file对象,没有必要把文件真的上传到服务器,所以返回值为false,表示不再执行后续上传动作了。
<Upload
multiple
showUploadList={false}
action="/"
beforeUpload={async (file) => {
const excelData = await uploadExcel(file);
setTableData([...tableData, ...excelData])
return false;
}}
>
<Button>上传Excel</Button>
获取到file对象就传递给exceljs来解析文件,代码如下:
export const uploadExcel = async (file: File) => {
const arrayBuffer = await file.arrayBuffer()
const tableData: DataType[] = [];
const workbook = new ExcelJS.Workbook();
try {
await workbook.xlsx.load(arrayBuffer);
// 获取第一个工作表
const worksheet = workbook.getWorksheet(1);
// 读取工作表中的数据
worksheet?.eachRow({includeEmpty: true}, (row, rowNumber) => {
console.log(`Row ${rowNumber}:`, row.values);
// 去掉表头
if (rowNumber > 1) {
tableData.push({
key: rowNumber.toString(),
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
app: row.values[1].trim(),
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
name: row.values[2].trim(),
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
works: row.values[3].trim()
})
}
});
} catch (error) {
console.error('Error loading workbook:', error);
}
console.log(tableData);
return tableData;
}
下面解释一下这段代码
使用ExcelJS.Workbook()创建一个workbook对象
workbook.getWorksheet(1)获取到xls文件的第一个sheet
使用worksheet?.eachRow方法获取到每行与单元格
在线调试
运行演示命令:
cd exceljs-demo/
npm i
npm run dev
领取专属 10元无门槛券
私享最新 技术干货