小数据导出用 response()->stream() 最轻量稳定;中大型必须用 maatwebsite/excel^3.1 并实现 ShouldQueue;导出类只接收 Collection,不处理请求或查询。

小数据导出直接用 response()->stream(),别碰内存炸弹
几千行以内、只要 CSV、不care样式,就别装包——response()->stream() 是最轻量也最稳的选择。常见错误是拼好整个 CSV 字符串再 return response($csvString),一两千行就 OOM,Excel 打开中文还是乱码。
- 必须用
fputcsv($fp, $row)逐行写,不能手动implode(',', $row) - 第一行前加 BOM:
fputs($fp, "\xEF\xBB\xBF"),否则 Excel 默认 ANSI 解码 - 查库别用
get(),改用cursor()或chunk(500);每 chunk 后调gc_collect_cycles(),PHP 8.1+ 尤其敏感
中大型导出必须用 maatwebsite/excel^3.1,装错版本直接报错
Laravel 5.5+ 自动发现包,但版本卡死:必须用 ^3.1,装 ^2.1 或 ^4.0 都会找不到 ExcelServiceProvider 或报 Call to undefined method Excel::create()。
- 安装命令只认这个:
composer require maatwebsite/excel:^3.1 - 导出类里
collection()方法返回值必须是Illuminate\Support\Collection,Eloquent Collection 或数组都不行,少一个->collect()就挂 - 别在导出类里调
request()——collection()可能在队列或 CLI 环境执行,request()根本不存在
WithStyles 和字体设置必须用 Excel 原生坐标,不是 PHP 数组索引
导出后字体是宋体、标题没加粗、列宽挤成一条线?不是包没生效,是你写的坐标格式错了。所有样式坐标必须是 Excel 原生格式(如 'A1'、'A1:Z1'),传 0、1 或 [0][0] 全无效。
- 设微软雅黑:
$event->sheet->getStyle('A1:Z1000')->getFont()->setName('Microsoft YaHei'),写在registerEvents()的AfterSheet::class回调里 - 标题加粗:配合
WithHeadings,再在styles()返回['A1:Z1' => ['font' => ['bold' => true]]] - 列宽别用
setAutoSize(true),大数据量卡死;改用getColumnDimension('A')->setWidth(20)手动设
大文件导出不加 ShouldQueue 就等着超时
导出上万行 Excel,HTTP 请求默认超时(Nginx 60s、PHP max_execution_time 30s),不进队列基本必挂。这不是可选项,是硬性前提。
- 导出类实现
ShouldQueue接口,Laravel 自动扔进队列,响应立刻返回 - 确保队列驱动已配置(
redis或database),并运行php artisan queue:work - 别忘了在控制器里传入已过滤好的数据,比如
new UsersExport($filteredUsers),导出类只管吐数据,不碰查询逻辑


















