• 作者:老汪软件技巧
  • 发表时间:2024-10-15 21:04
  • 浏览量:

前段时间写过一篇类似的文章,介绍了sheetjs。最近发现了一个更好用的库ExcelJS,它支持高级的样式自定义,并且使用起来也不复杂。实际上sheetjs也支持高级自定义样式,不过需要使用付费版。

下面对比了Exceljs和Sheetjs:

特性ExcelJSSheetJS (xlsx)

写入样式

支持单元格的样式设置(字体、颜色、边框等)

不支持样式设置

图表支持

不支持

不支持

内存效率

适合处理较大文件,支持流式写入与读取

处理大文件时内存占用较高,需要手动优化

流式操作

支持(如流式写入、读取大文件)

不支持流式操作,适用于小到中型数据集的处理

社区与文档

文档详尽,社区活跃

社区活跃,文档相对较简单

适用场景

适合需要丰富样式、较大数据集处理的场景

适合快速操作小型文件,支持更多文件格式

ExcelJS主要用于Node.js环境,它是一个Node.js库。因此,它的核心功能是为Node.js应用程序提供操作Excel文件的接口。虽然ExcelJS本身是为Node.js设计的,但它也提供了在浏览器端使用的版本。

这里我们主要来介绍浏览器端的使用方式,还是通过下载和上传来演示这个库的常规用法,更多功能可以参考文档:/exceljs/exc…

前端实现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>上传ExcelButton>
Upload>

获取到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.xlsx.load(arrayBuffer)将文件对象解码workbook.getWorksheet(1)获取到xls文件的第一个sheet使用worksheet?.eachRow方法获取到每行与单元格在线调试

仓库和在线访问:/~/github.co…

运行演示命令:

cd exceljs-demo/
npm i
npm run dev


上一条查看详情 +Redis--缓存雪崩及解决方案
下一条 查看详情 +没有了