问题背景
笔者在处理公司项目时,收到测试同学的反馈,批量导出excel功能只能导出10个excel文件。笔者写了一个测试demo,还原项目中的实际情况

点击导出全部用户按钮,结果却是这样的

可以看到,从第19条数据直接跳到50条数据,数据导出不完整。
笔者在网上查了一下,发现同时触发多个 Excel 文件下载,会遇到浏览器下载限制问题:
- Chrome/Edge: 通常限制 6-10 个并发下载
- 超过限制: 下载会被阻塞或失败
exportExcelSequentially
为了解决浏览器并发限制,可以防止一次性并发下载,转并发为串行,如下所示
核心实现
typescript
// 顺序导出 Excel 文件,避免浏览器下载限制
const exportExcelSequentially = async (files: any[], delayMs = 500) => {
for (let i = 0; i < files.length; i++) {
exportExcel([files[i]]);
if (i < files.length - 1) {
await delay(delayMs);
}
}
};
使用 async 函数,允许在函数内部使用 await 关键字,强迫按照顺序导出 Excel 文件
对比
有问题的代码逻辑
ts
const exportToExcel = async () => {
setExporting(true);
setProgress(0);
for (let i = 0; i < mockUsers.length; i++) {
const user = mockUsers[i];
await exportSingleUser(user);
setProgress(i + 1);
}
setExporting(false);
alert(`导出完成!共导出 ${mockUsers.length} 个 Excel 文件`);
};
在这里由于是快速并发导出,很容易导致受到浏览器下载限制
优化后的代码
ts
// 串行导出全部用户,避免浏览器下载限制
const exportToExcelSequentially = async (delayMs = 500) => {
setExportingSequential(true);
setProgress(0);
for (let i = 0; i < mockUsers.length; i++) {
const user = mockUsers[i];
await exportSingleUser(user);
setProgress(i + 1);
if (i < mockUsers.length - 1) {
await delay(delayMs);
}
}
setExportingSequential(false);
alert(`导出完成!共导出 ${mockUsers.length} 个 Excel 文件`);
};
利用 delay 方法把并发变成串行同步