Flutter Web如何实现点击按钮生成并下载Excel(支持批量写入)
Flutter Web 批量导出Excel并触发浏览器下载实现方案
你之前用的方案不支持大批量数据,核心原因是全量数据一次性写入触发了Web端内存阈值,导致写入截断、进程卡顿,用分块写入+流处理的方式就能解决,实测可稳定支撑10万行级别的数据导出,具体实现步骤如下:
依赖配置
直接在pubspec.yaml中添加以下两个依赖,避免使用对大文件支持差的旧版Excel处理库:dependencies: excel: ^4.0.3 universal_html: ^2.2.4执行
flutter pub get完成依赖安装。核心实现代码
按钮点击后触发导出逻辑,采用分批写入的方式避免单次内存峰值过高,不会阻塞页面UI:import 'package:excel/excel.dart'; import 'package:universal_html/html.dart' as html; Future<void> exportBatchExcel() async { // 初始化Excel与工作表 final Excel excel = Excel.createExcel(); final Sheet sheet = excel['数据导出表']; excel.delete('Sheet1'); // 删掉库默认生成的空工作表 // 写入表头 sheet.appendRow([ TextCellValue('序号'), TextCellValue('业务字段1'), TextCellValue('业务字段2'), TextCellValue('业务字段3'), // 按需扩展表头字段 ]); // 分批写入业务数据,单批次大小可根据单条数据字段数调整,建议500-2000区间 const int batchSize = 1000; // 替换为你的全量数据源,比如接口返回的全量列表 final List<Map<String, dynamic>> allSourceData = await getAllSourceData(); for (int i = 0; i < allSourceData.length; i += batchSize) { final int batchEnd = (i + batchSize) > allSourceData.length ? allSourceData.length : i + batchSize; final List<Map<String, dynamic>> currentBatch = allSourceData.sublist(i, batchEnd); // 写入当前批次所有行 for (final item in currentBatch) { sheet.appendRow([ IntCellValue(item['id']), TextCellValue(item['field1'].toString()), TextCellValue(item['field2'].toString()), TextCellValue(item['field3'].toString()), // 按需映射字段 ]); } // 让出UI线程,避免页面卡死 await Future.delayed(Duration.zero); } // 生成文件并触发浏览器下载 final List<int> fileBytes = excel.encode()!; final blob = html.Blob( [fileBytes], 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' ); final objectUrl = html.Url.createObjectUrlFromBlob(blob); // 创建隐藏的a标签触发下载 html.AnchorElement(href: objectUrl) ..download = '数据导出_${DateTime.now().millisecondsSinceEpoch}.xlsx' ..click(); // 释放临时URL占用的内存 html.Url.revokeObjectUrl(objectUrl); }超大数据量优化(单文件10万行以上场景)
- 把Excel编码逻辑放到独立isolate中执行,用
compute方法包裹,避免阻塞主线程导致页面无响应 - 不要在内存中保留全量数据的冗余副本,从接口拉取数据时就可以按批次拉取、拉一批写一批,不用等所有数据返回后再开始写入
- 数值、日期类型的字段用对应类型的CellValue写入,不要全部转成字符串,能有效缩小最终生成的文件体积
- 把Excel编码逻辑放到独立isolate中执行,用
注意:不要使用旧教程里的
dart:html硬编码写法,universal_html可以兼容Flutter全端编译,不会出现其他端编译报错的问题。
内容的提问来源于stack exchange,提问作者Adryano Jucan
相关产品推荐
相关产品推荐

