如何使用nodejs快速拆分excel文件
业务场景
最近在进行数据迁移时,领导给我安排了几十个几万条数据的excel文件进行迁移,但是所迁移的系统不支持过于大的excel文件解析,需要将excel拆分为多个较小的excel文件,才能上传。
所用技术
exceljs, nodejs, readline, fs
使用方法及实现效果
- 首先下载代码并配置好nodejs环境 (搜索nodejs环境配置)
- 使用编辑器或使用自带终端,进入代码文件夹,执行npm i命令
- 将需要分割的文件放置在input文件夹内,一次只能分割一个
- 执行npm run start,输入分割大小,等待代码执行
- 分割好的excel文件存在output文件夹中
文件目录
使用方法,执行npm run start
执行完毕
Exceljs
当涉及到处理 Excel 文件时,ExcelJS 是一个非常有用的 JavaScript 库。它可以在 Node.js 和浏览器环境中实现代码层面的 Excel 编辑功能。包括创建、导出、读取、修改内容等 功能。
Exceljs可以通过调用方法编辑excel文件的内容,操作单元包括了工作表、单元行、单元列以及单元格,不仅可以设置单元格的值还可以设置格式样式。这意味着可以通过编程方式生成复杂的报表和数据表格。
除了数据,ExcelJS 还允许你创建和修改 Excel 文件中的图表和图形。你可以设置图表的类型、数据范围、标题和样式。这使得你可以在报表中添加可视化的图表,以更好地呈现数据。
ExcelJS 提供了丰富的样式和格式选项。你可以设置单元格、行、列和工作表的样式,包括字体、颜色、边框、对齐方式等。这使得你可以自定义 Excel 文件的外观,使其符合你的品牌和设计要求。
如果你需要在单元格中进行计算,ExcelJS 也支持设置和计算公式。你可以使用内置的 Excel 函数和运算符来创建复杂的公式,并在计算时获取结果。
ExcelJS 还允许你在 Excel 文件中插入图片和图表,并设置其位置、大小和样式。这使得你可以在报表中添加图片和图表,以更好地展示数据和信息。
exceljs/exceljs: Excel Workbook Manager (github.com)
具体代码实现
我们需要实现读取一个大体积的excel文件,同时对文件内容进行分割,之后导出为较小的excel文件。
读取excel文件
//文件路径
let excelfile = "test.xlsx";
//获取待分割excel文件路径
const filenames = fs.readdirSync('./input')
if (filenames)
excelfile = filenames[0]
//文件入口
let url = './input/' + excelfilees[0]
// 初始化
const workbook = new ExcelJS.Workbook();
workbook.xlsx.readFile(url).then(function () {
var worksheet = workbook.getWorksheet(1); //获取第一个worksheet
});
- 首先使用fs读取input文件夹下的大体积excel文件,设置好文件url
- 初始化exceljs, 创建workbook,同时使用readFile方法读取目标文件
- 使用getWorksheet获取excel文件的内容,默认读取第一个工作表
- 此时worksheet即为我们需要分割的excel文件
获取数据并设置表头
workbook.xlsx.readFile(url).then(function () {
var worksheet = workbook.getWorksheet(1); //获取第一个worksheet
let tableHead
let data = []
worksheet.eachRow(function (row, rowNumber) {
//获取表头
if (rowNumber == 1)
tableHead = row.values.slice(1)
else
data.push(row.values.slice(1))
});
const arr = sliceArray(data, fileSize)
output(arr, tableHead)
});
- 获取完excel之后,使用eachRow方法读取数据
- 判断是否为表头,并保存表头数据,slice(1) --> 去除null数据
- 存储所有的数据
分割数据
遍历整个数据并按照文件大小进行分割
//分割
function sliceArray(array, size) {
var result = [];
for (var i = 0; i < Math.ceil(array.length / size); i++) {
var start = i * size;
var end = start + size;
result.push(array.slice(start, end));
}
return result;
}
导出
使用exceljs创建一个新的workbook,并使用addRow方法添加表头和数据
最后使用writeFile方法导出数据
// 导出
function output(data, head) {
data.forEach(async (i, index) => {
// 创建工作簿
const _workbook = new ExcelJS.Workbook();
// 添加工作表
const _sheet1 = _workbook.addWorksheet("sheet1");
_sheet1.addRow(head)
_sheet1.addRows(i)
// 导出表格
let url = excelfile.split('.')
url[0] = url[0] + index
await _workbook.xlsx.writeFile(`./output/${url.join('.')}`)
})
}
优化
为了动态的接受用户输入的文件大小,使用readline读取用户输入的分割大小进行分割。
将整个分割逻辑封装到start函数中,判断输入参数后执行分割。
//获取分割大小
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
// ask user for the fileSize
let fileSize = 1000
rl.question(`What is the file size you need?\n`, (size) => {
if (isNaN(size))
console.log('输入数据有误,请输入数字')
else {
fileSize = +size
if(fileSize <= 0 || !Number.isInteger(fileSize)){
console.log('请输入一个正整数')
rl.close();
return
}
console.log('正在处理数据...')
start()
}
rl.close();
});