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

Flutter 如何实现后台生成下载PDF 带进度通知点击打开功能

问题核心优化方案

一、先解决PDF生成慢的核心瓶颈

你现有代码最大的耗时点在循环内串行拉取商品图片,300个商品串行发起300次网络请求,耗时会指数级上升,优先优化这部分:

  • 提前在购物车页面加载商品列表时,就把所有商品图片缓存到本地目录,生成PDF时直接读取本地缓存文件,完全避免生成阶段的网络请求
  • 若无法提前缓存,改用并发请求批量拉取所有图片,不要在for循环里逐个await网络请求,300个并发请求的耗时远低于300次串行请求
  • 所有插入PDF的图片提前压缩到显示所需的尺寸(比如宽度适配PDF列宽、分辨率控制在72DPI),不要直接插入原图,既减小PDF体积也加快生成速度
  • 删除循环内所有print语句,debug模式下高频打印会拖慢执行速度;删掉多余的sr数组,直接用循环变量计算序号即可,减少不必要的内存操作

二、PDF生成逻辑移至后台Isolate

syncfusion的PDF生成属于CPU密集型任务,跑在主Isolate会阻塞UI,用Flutter的后台Isolate执行生成逻辑:

  • 提前把所有需要用到的商品数据(本地缓存的图片字节、SKU、重量、数量等)整理成可跨Isolate传输的纯数据对象
  • 用Isolate.run()或者compute()函数把整个PDF生成逻辑放到后台Isolate执行,主Isolate只负责接收进度和最终生成的PDF文件路径

三、进度通知实现

用flutter_local_notifications实现类Google Drive的进度通知:

  1. 点击下载按钮时先请求通知权限,初始化通知通道,弹出初始进度为0的通知
  2. 后台生成PDF的过程中,每处理N个商品(比如每处理5个、或者每完成1%进度)就向主Isolate发送当前进度,主Isolate收到后更新通知的进度条和文案,用同一个通知ID更新就会覆盖之前的通知,不会重复弹出
  3. 生成完成后,更新通知内容为「PDF生成完成,点击打开」,给通知设置点击回调,调用OpenFile.open()打开生成好的PDF文件即可

四、其他细节优化

  • 你当前只添加了一个PDF页面,300个商品肯定会超出单页高度,syncfusion的PdfGrid支持自动分页,调用grid.draw()时不要指定固定page,让插件自动生成多页,避免内容截断
  • PDF保存路径可以改用公共下载目录,方便用户在文件管理器里直接找到导出的文件

核心优化代码示例

// 1. 提前批量缓存图片示例
Future<List<Uint8List>> preloadAllImages(List<String> photoUrls) async {
  final futures = photoUrls.map((url) async {
    final response = await get(Uri.parse(url));
    // 可以在这里加图片压缩逻辑
    return response.bodyBytes;
  });
  // 并发请求所有图片
  return Future.wait(futures);
}

// 2. 后台Isolate生成PDF的入口
static Future<String> generatePdfInBackground(Map<String, dynamic> params) async {
  // 这里放你原来的PDF生成逻辑,所有需要的数据都从params取
  // 生成过程中可以发送进度事件,用ReceivePort/SendPort通信
  final List<Uint8List> images = params['images'];
  final List<String> skuArray = params['skuArray'];
  // ... 其余生成逻辑和你原来的一致
  // 最终返回生成的PDF文件路径
  return filePath;
}

// 3. 更新通知进度示例
void updateNotificationProgress(int current, int total) {
  final progress = (current / total * 100).round();
  flutterLocalNotificationsPlugin.show(
    1001, // 固定通知ID,用来覆盖更新
    '正在生成PDF',
    '已完成$progress%',
    NotificationDetails(
      android: AndroidNotificationDetails(
        'pdf_download_channel',
        'PDF下载',
        channelDescription: 'PDF生成进度通知',
        importance: Importance.low,
        priority: Priority.low,
        showProgress: true,
        maxProgress: 100,
        progress: progress,
        ongoing: true,
      ),
    ),
  );
}

内容的提问来源于stack exchange,提问作者Samkit Shah

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 23:12:02