欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Node.js读写巨大Excel

程序员文章站 2022-07-10 21:47:21
Node.js写巨大数据量Excel问题最初我采用的是node-xlsx框架,每一个工作表50000行4列,100个工作表,如此大的数据使用node-xlsx写入,会溢出内存。在网上百般查找,没有什么有用的方案。最后查了下目前常用的写excel的框架,发现了一个框架提供了流式的写入方法,该框架就是exceljsexceljs框架优势功能齐全官方提供中文文档,地址支持流式读写…优势很多,在此不再赘述exceljs框架使用安装npm install exceljs引用con...

Node.js写巨大数据量Excel

问题

最初我采用的是node-xlsx框架,每一个工作表50000行4列,100个工作表,如此大的数据使用node-xlsx写入,会溢出内存。在网上百般查找,没有什么有用的方案。最后查了下目前常用的写excel的框架,发现了一个框架提供了流式的写入方法,该框架就是exceljs

exceljs框架优势

  • 功能齐全
  • 官方提供中文文档,地址
  • 支持流式读写
  • …优势很多,在此不再赘述

exceljs框架使用

  • 安装
npm install exceljs
  • 引用
const ExcelJS = require('exceljs');

使用这种发法引用的话,Node.js版本高于10的话会报如下错误

throw new Error(‘For node versions older than 10, please use the ES5 Import: https://github.com/exceljs/exceljs#es5-imports’);
^

Error: For node versions older than 10, please use the ES5 Import: https://github.com/exceljs/exceljs#es5-imports

因此Node.js版本高于10的话应该用es5的方法引用,按照官方文档的说法,还需要添加core-jsregenerator-runtime这两个依赖。
安装这两个依赖

npm install core-js
npm install regenerator-runtime

高版本Node.js的引用方法

require('core-js/modules/es.promise');
require('core-js/modules/es.string.includes');
require('core-js/modules/es.object.assign');
require('core-js/modules/es.object.keys');
require('core-js/modules/es.symbol');
require('core-js/modules/es.symbol.async-iterator');
require('regenerator-runtime/runtime');
const ExcelJS = require('exceljs/dist/es5');

把这些依赖都引入就可以正常使用了

下面提供了IO方法和流式方法的两个测试速度的例子

IO方法写文件

let workbook1 = new ExcelJS.Workbook(); //创建工作簿
let sheet = workbook1.addWorksheet('My Sheet');//添加工作表

console.time('write to excel time')
for(let i=0;i<50000;i++){
  sheet.addRow([3, 'Sam', 1]); //添加行
}
workbook1.xlsx.writeFile('./speedTest.xlsx');//以IO方法写入文件
console.timeEnd('write to excel time')//程序执行时间

流式方法写入文件

官方文档对流式方法描述如下
上面记录的文件 I/O 需要在内存中建立整个工作簿,然后才能写入文件。虽然方便,但是由于所需的内存量,它可能会限制文档的大小。

流写入器(或读取器)在生成工作簿或工作表数据时对其进行处理,然后将其转换为文件形式。通常,这在内存上效率要高得多,因为最终的内存占用量,甚至中间的内存占用量都比文档版本要紧凑得多,尤其是当您考虑到行和单元格对象一旦提交就被销毁时,尤其如此。

let workbook1 = new ExcelJS.stream.xlsx.WorkbookWriter({filename:'./speedTest.xlsx'});//创建一个流式写入器
let sheet = workbook1.addWorksheet('My Sheet');//添加工作表

console.time('write to excel time')
for(let i=0;i<50000;i++){
  sheet.addRow([3, 'Sam', 1]).commit();//添加行,commit()是将添加的行提交
}
sheet.commit();//提交工作表
workbook1.commit()//提交工作簿,即写入文件
console.timeEnd('write to excel time')

值得注意的是

  • 将工作表添加到工作簿后,将无法将其删除。
  • 提交行后,将无法再访问该行,因为该行将从工作表中删除。
    这也正是为什么流式的方法写不会超出内存的原因:每提交一行,直接转换为文件形式,在内存中销毁该行。
  • 二者速度用上面两段程序粗略测试差不多,也没有深究具体谁快。
  • exceljs和node-xlsx写入相同的数据量,exceljs生成的文件要比node-xlsx生成的文件小10倍左右,这一是一个非常棒的优势。

小结

使用exceljs,不仅功能齐全,可以设置各种样式,而且提供了流式方法,可以写入大量数据。同时该框架生成的文件要比node-xlsx小很多。

本文地址:https://blog.csdn.net/weixin_43272648/article/details/107313189