最稳妥路径是使用maatwebsite/excel 2.1.x(推荐2.1.30)配合Excel::import()及自定义导入类,需手动注册服务提供者与门面,禁用已弃用的Excel::load(),ZIP文件须先解压再逐个导入,百万级数据应转CSV后用LOAD DATA INFILE。

直接用 maatwebsite/excel 的 Excel::import() 方法 + 自定义导入类是最稳妥的路径,但必须避开 Laravel 5.5 下的版本陷阱和内存雷区。
必须锁定 2.1.x 版本,否则会报错
Laravel 5.5 与 maatwebsite/excel 3.0+ 不兼容,安装时漏掉版本约束会导致 Class 'Maatwebsite\Excel\ExcelServiceProvider' not found 或 Facade 调用失败。
- 执行
composer require "maatwebsite/excel:~2.1.0"(推荐2.1.30,已验证稳定) - 手动在
config/app.php的providers数组中添加:Maatwebsite\Excel\ExcelServiceProvider::class - 同样在
aliases中添加:'Excel' => Maatwebsite\Excel\Facades\Excel::class - 不要运行
vendor:publish后盲目改配置——默认配置在小批量场景下足够,先跑通再调优
别用 Excel::load(),改用 Excel::import() 新式写法
Excel::load() 是 v2.1 的旧 API,已弃用且不支持 ZIP 解压、大文件流式读取;Excel::import() 才是官方推荐入口,能对接自定义导入类并天然支持事务包裹。
- 创建导入类:
php artisan make:import UsersImport --model=User - 在
UsersImport中实现ToModel和WithHeadingRow(如果 Excel 有表头) - 控制器中调用:
Excel::import(new UsersImport(), $request->file('file'))—— 注意传入的是UploadedFile实例,不是路径 - 错误示例:
Excel::load($filePath, function($reader){...})在 PHP 7.4+ 环境下容易触发Undefined index: 0或内存爆满
处理 ZIP 多文件时,得自己解压再逐个导入
maatwebsite/excel v2.1 不原生支持 ZIP 解包。上传 ZIP 后不能直接丢给 import(),否则会报 Could not open ... for reading! (Could not determine file type)。
- 先用 PHP 原生
ZipArchive解压到临时目录:$zip = new \ZipArchive(); $zip->open($file->getRealPath()); $zip->extractTo(storage_path('app/temp/imports')); - 遍历解压后的
.xlsx或.xls文件,对每个调用一次Excel::import() - 记得清理临时文件:
array_map('unlink', glob(storage_path('app/temp/imports/*.{xlsx,xls}'), GLOB_BRACE)); - ZIP 内含上百个文件?别一次性全导入——加队列或分页处理,否则超时或 OOM
百万级数据导入别硬扛,换 LOAD DATA INFILE
哪怕开了 memory_limit = 2G,v2.1 读取 10 万行以上 Excel 仍大概率触发 Allowed memory size exhausted。Excel 格式本身解析开销大,不是框架问题,是格式限制。
- 前端上传后,用
PhpOffice\PhpSpreadsheet\Reader\Csv把 Excel 转成 CSV(更轻量),再丢给 MySQL 的LOAD DATA INFILE - SQL 示例:
LOAD DATA LOCAL INFILE '/path/to/data.csv' INTO TABLE users FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY '\n' IGNORE 1 ROWS; - PHP 中执行需开启
mysqli.allow_local_infile = On,且数据库用户要有FILE权限 - 关键点:CSV 字段顺序必须和 DB 字段严格对应,否则数据错位——导出模板时就固定列顺序,比现场映射更可靠
真正卡住人的从来不是“怎么写导入逻辑”,而是 ZIP 解压路径权限、CSV 字段顺序错位、日期单元格被读成数字(如 44562)、以及没意识到 Excel 解析根本不是为百万行设计的。这些细节不提前踩一遍,上线后只能半夜改代码。


















