laravel 5.5 必须使用 maatwebsite/excel:~2.1.0,因其是唯一兼容该版本的稳定版;超5k行导出需用 fromquery + 游标分页 + 手动 chunk 控制内存,禁用 excel::load() 和 fromcollection。

直接说结论:Laravel 5.5 用 maatwebsite/excel:~2.1.0 是唯一可行路径,但必须绕开内存陷阱——不能用 Excel::load() 或 FromCollection 处理 >5k 行,得靠 FromQuery + 游标分页 + 手动 chunk 控制内存峰值。
为什么 Laravel 5.5 只能选 maatwebsite/excel v2.1
Laravel 5.5 发布于 2017 年,PHP 版本普遍为 7.0–7.2。FastExcel 依赖 OpenSpout ≥v4,而 OpenSpout v4 要求 PHP ≥7.4;maatwebsite/excel:^4.0 则要求 Laravel 9+。v2.1 是最后一个兼容 Laravel 5.5 的稳定版,且底层基于 PHPExcel(非 PhpSpreadsheet),对老环境更友好。
- 装错版本会报错:
Class "Maatwebsite\Excel\ExcelServiceProvider" not found或Call to undefined method Illuminate\Foundation\Application::bindShared() - 别试图升级到 v3.x:它已移除对 Laravel 5.5 的支持,且依赖的 PhpSpreadsheet 要求 PHP ≥7.2.5,部分 5.5 项目仍跑在 PHP 7.1 上
- v2.1 的配置项名也不同:
excel.php里是'cache' => 'default',不是 v4 的'cache' => ['driver' => 'file']
导出超 10 万行数据:FromQuery + cursor() 是底线
FromCollection 会把全部数据加载进内存再转 Excel,10 万行用户数据轻松突破 512MB 内存限制。必须改用 FromQuery,并配合数据库游标分页避免 OFFSET 性能坍塌。
- 导出类里实现
query()方法,返回 Builder 实例:User::where('status', 'active')->select('id', 'name', 'email') - 不要在
query()里调用->get()或->all(),否则等于白写 - 若需关联字段(如部门名),用
join而非with()——with()在FromQuery中不生效 - 日期字段导出为字符串:
DB::raw("DATE_FORMAT(created_at, '%Y-%m-%d') as created_date"),避免 PhpOffice/PHPExcel 自动转成 Excel 序列号
导入大文件时内存爆掉?用 chunk + 临时表中转
Excel::load($file)->get() 会一次性读入全部 sheet 数据,5 万行 CSV 就可能吃光 1GB 内存。Laravel 5.5 没有原生流式导入支持,得手动拆解。
- 先用
Excel::load($file)->get()->chunk(500)分批处理,但注意:chunk 是在内存里切数组,不是流式读取,治标不治本 - 真正有效的做法是:上传后用
php artisan excel:import命令(需自定义命令)调用DB::transaction()+DB::table('temp_imports')->insert()先入库,再从临时表逐批读取处理 - 更激进但稳定的方案:让前端把 Excel 转成 CSV 后上传,后端用
fgetcsv()流式解析,每 1000 行 commit 一次事务 - 别信
ini_set('memory_limit', '-1')—— 它只是延迟崩溃,不解决根本问题
容易被忽略的坑:时区、空值、字符编码
导出中文字段乱码、数字变成科学计数法、空单元格变 0 —— 这些不是 bug,是 v2.1 默认行为没关对。
- 导出前强制设置时区:
date_default_timezone_set('Asia/Shanghai'),否则Carbon时间字段会按 UTC 导出 - 空值要显式转空字符串:
return array_merge($row, ['phone' => $user->phone ?: '']),否则 Excel 里显示为0 - CSV 导出必须指定 BOM 头,否则 Excel 打开中文乱码:
header('Content-Type: text/csv; charset=UTF-8');+echo "\xEF\xBB\xBF"; - v2.1 不支持 XLSX 样式定制,想加背景色或冻结窗格?只能导出 CSV 或用
PHPExcel原生 API 手写,代价是失去 Laravel 封装便利性
最后提醒一句:Laravel 5.5 已结束官方维护,所有 Excel 相关扩展都停留在安全补丁阶段。如果业务数据量持续增长,最省事的升级路径不是调优,而是把核心导出逻辑抽成独立服务,用 Laravel 10+ + FastExcel 重写,再通过 HTTP API 对接旧系统。











