如何用ExcelJS写入流数据到Excel?代码生成空文件排查
问题分析与修复方案
你的代码生成空Excel文件主要有3个核心问题:
- 异步流程未正确封装:
processUpload是async函数,但内部依赖事件监听处理流,没有将整个流处理+文件提交的过程包装成Promise,导致外部调用时可能在文件写入完成前就结束流程,文件被截断为空。 addRow的异步特性未处理:worksheet.addRow()返回Promise,直接调用不等待的话,行数据还没写入缓冲区就执行了workbook.commit(),最终文件无内容。- 错误处理不完整:
workbook.commit()的错误未捕获,流的错误也没有向外抛出,导致问题无法被及时发现。
修正后的代码
const excel = require("exceljs"); async function processUpload(stream, filename) { return new Promise((resolve, reject) => { let counter = 0; const options = { filename, useStyles: true, useSharedStrings: true, }; const workbook = new excel.stream.xlsx.WorkbookWriter(options); const worksheet = workbook.addWorksheet("Sheet1"); // 处理流数据,等待每行写入完成 stream.on("data", async (row) => { counter++; try { await worksheet.addRow(row); } catch (err) { console.error("写入行失败:", err); reject(err); stream.destroy(); // 出错后终止流 } }); stream.on("end", async () => { try { await workbook.commit(); console.log("Workbook committed and uploaded to GCS.", counter); resolve(filename); } catch (err) { console.error("提交工作簿失败:", err); reject(err); } }); stream.on("error", (err) => { console.error("流处理错误:", err); reject(err); workbook.abort(); // 出错后终止工作簿写入 }); }); }
关键修复点说明
- 用Promise封装整个流程:让
processUpload返回Promise,外部调用时可以通过await确保文件写入完成后再执行后续操作。 - 等待
addRow完成:在data事件中使用await等待每行写入完成,避免数据丢失。 - 完善错误处理:捕获
addRow和commit的错误,流出错时终止工作簿写入并向外抛出错误,确保问题能被感知。 - 异常时清理资源:出错时调用
stream.destroy()和workbook.abort(),避免资源泄漏。
内容的提问来源于stack exchange,提问作者Ankit Kadam
相关产品推荐
相关产品推荐

