前段时间写过一篇类似的文章,介绍了sheetjs。最近发现了一个更好用的库ExcelJS,它支持高级的样式自定义,并且使用起来也不复杂。实际上sheetjs也支持高级自定义样式,不过需要使用付费版。
下面对比了Exceljs和Sheetjs:
特性ExcelJSSheetJS (xlsx)*写入样式支持单元格的样式设置(字体、颜色、边框等)不支持样式设置*图表支持不支持不支持内存效率适合处理较大文件,支持流式写入与读取处理大文件时内存占用较高,需要手动优化流式操作支持(如流式写入、读取大文件)不支持流式操作,适用于小到中型数据集的处理社区与文档文档详尽,社区活跃社区活跃,文档相对较简单适用场景适合需要丰富样式、较大数据集处理的场景适合快速操作小型文件,支持更多文件格式
ExcelJS主要用于Node.js环境,它是一个Node.js库。因此,它的核心功能是为Node.js应用程序提供操作Excel文件的接口。虽然ExcelJS本身是为Node.js设计的,但它也提供了在浏览器端使用的版本。
这里我们主要来介绍浏览器端的使用方式,还是通过下载和上传来演示这个库的常规用法,更多功能可以参考文档:
https://github.com/exceljs/exceljs/blob/master/README_zh.md
前端实现Excel导出下载
先来看下功能演示,如下图把表格中的数据下载到excel文件中
exportconstexportExcel=(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 =newExcelJS.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 =newBlob([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();// 清理 URLsetTimeout(()=>{
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>
</Upload>
获取到file对象就传递给exceljs来解析文件,代码如下:
exportconstuploadExcel=async(file: File)=>{const arrayBuffer =await file.arrayBuffer()const tableData: DataType[]=[];const workbook =newExcelJS.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.xlsx.load(arrayBuffer)
将文件对象解码 workbook.getWorksheet(1)
获取到xls文件的第一个sheet- 使用
worksheet?.eachRow
方法获取到每行与单元格
在线调试
仓库和在线访问:https://stackblitz.com/~/github.com/fullee/exceljs-demo
运行演示命令:
cd exceljs-demo/
npm i
npm run dev
版权归原作者 程序饲养员 所有, 如有侵权,请联系我们删除。