Laravel 批量导入导出实战:用 maatwebsite/excel 处理十万行数据
test12026-10-181 次阅读
为什么不直接读文件
PHP 一次性把十万行 CSV 读进数组,内存立刻爆炸。maatwebsite/excel 基于 Laravel 的队列与分块读取,导出时按集合流式写、导入时按 chunk 分块处理,内存占用基本恒定。下面覆盖最常见的导出和导入两种诉求。
安装
composer require maatwebsite/excel
php artisan make:export ArticlesExport
php artisan make:import ArticlesImport
导出:从集合生成带表头的表格
// app/Exports/ArticlesExport.php
namespace App\Exports;
use App\Models\Article;
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\WithHeadings;
class ArticlesExport implements FromCollection, WithHeadings
{
public function collection()
{
// 用 select 只取需要的列,避免把整模型的重量都拖进来
return Article::select('id', 'title', 'views', 'created_at')
->latest()
->get();
}
public function headings(): array
{
return ['ID', '标题', '阅读量', '创建时间'];
}
}
控制器里一行触发下载,底层用 StreamedResponse 边写边传:
use App\Exports\ArticlesExport;
use Maatwebsite\Excel\Facades\Excel;
public function export()
{
return Excel::download(new ArticlesExport, 'articles.xlsx');
}
导入:分块落库并做行级校验
// app/Imports/ArticlesImport.php
namespace App\Imports;
use App\Models\Article;
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithChunkReading;
use Maatwebsite\Excel\Concerns\WithValidation;
class ArticlesImport implements ToModel, WithChunkReading, WithValidation
{
public function model(array $row)
{
return new Article([
'title' => $row[1],
'views' => (int) ($row[2] ?? 0),
]);
}
// 每 1000 行读一次,内存不累积
public function chunkSize(): int
{
return 1000;
}
public function rules(): array
{
return [
1 => 'required|string|max:200',
2 => 'nullable|integer|min:0',
];
}
}
落地经验
- 超大文件导入建议配合 WithBatchInserts 和 ShouldQueue,让写入走批量并异步进行。
- 校验失败默认抛异常中断,可用 SkipsOnFailure 收集坏行而不是整文件失败。
- 导出海量数据时优先 FromQuery 而不是 FromCollection,后者会先把数据全查出来。
T
test1
文章作者
为什么不直接读文件 PHP 一次性把十万行 CSV 读进数组,内存立刻爆炸。maatwebsite/excel 基于...
- 分类
- 技术
- 发布时间
- 2026-10-18
- 字数
- 约 1924 字
- 阅读
- 1 次
