You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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写入,不要全部转成字符串,能有效缩小最终生成的文件体积

注意:不要使用旧教程里的dart:html硬编码写法,universal_html可以兼容Flutter全端编译,不会出现其他端编译报错的问题。

内容的提问来源于stack exchange,提问作者Adryano Jucan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 23:03:23