Laravel 9导入Excel至PostgreSQL异常问题求助
Laravel 9 Excel导入PostgreSQL问题排查与解决
问题现象
- 使用Postman提交文件上传请求时,页面重定向至Laravel默认页面,无任何导入结果或错误提示
- 使用Blade视图提交时,页面返回
Users imported successfully!,但PostgreSQL的users表要么为空,要么仅存在一条空数据
相关代码
UsersController.php
public function importUsers(Request $request) { $request->validate([ 'file' => 'required|mimes:xlsx,csv' ]); Excel::import(new UsersImport, $request->file('file')); return back()->with('success', 'Users imported successfully!'); }
UsersImport.php
<?php namespace App\Imports; use App\Models\User; use Maatwebsite\Excel\Concerns\ToCollection; use Maatwebsite\Excel\Concerns\WithHeadingRow; use Illuminate\Support\Collection; class UsersImport implements ToCollection, WithHeadingRow { public function collection(Collection $rows) { foreach ($rows as $row) { if (empty($row['Matricule'])) { continue; } User::updateOrCreate( [ 'matricule' => $row['Matricule'], ], [ 'id_badge' => $row['Badge'] ?? null, 'nom' => $row['Nom'] ?? null, 'prenom' => $row['Prenom'] ?? null, 'post' => $row['Departement'] ?? null, 'role' => $row['Role'] ?? '1', 'id_projet' => $row['Project Id'] ?? null, ] ); } } }
用户表迁移文件
Schema::create('users', function (Blueprint $table) { $table->id(); $table->unsignedBigInteger('id_projet'); $table->integer('id_badge')->unique()->nullable(); $table->string('matricule'); $table->string('nom')->nullable(); $table->string('prenom')->nullable(); $table->string('post')->nullable(); $table->enum('role',['0','1'])->default('1')->nullable(); $table->foreign('id_projet')->references('id')->on('projects'); $table->rememberToken(); $table->timestamps(); });
路由定义
Route::post('/import-users', [UsersController::class, 'importUsers'])->name('import.users');
Excel表格结构
表头包含:Matricule、Badge、Nom、Prenom、Departement、Role、Project Id
问题排查与解决方案
1. Postman请求重定向问题
Postman提交POST请求出现重定向,核心原因是CSRF令牌验证失败:
- Laravel默认对POST请求强制CSRF验证,需在Postman请求头中添加
X-CSRF-TOKEN字段,值可从应用的csrf-token元标签获取,或先访问/csrf-cookie接口获取令牌后再提交请求 - 临时测试可在
app/Http/Middleware/VerifyCsrfToken.php中将/import-users加入$except数组,但生产环境禁止此操作
2. 数据库无数据/空数据问题
核心原因
- 表头匹配失效:
WithHeadingRow依赖Excel第一行作为表头,若表头存在空格、大小写差异或编码识别错误,会导致$row['Matricule']等字段无法取值,进而跳过数据或插入空值 id_projet必填约束冲突:迁移文件中id_projet为非空unsignedBigInteger,但导入时$row['Project Id'] ?? null可能传入null,导致数据库插入失败,而代码未捕获异常仍返回成功提示- 模型批量赋值拦截:
User模型未配置$fillable属性包含所有导入字段,Laravel会拦截未授权的字段赋值
修复步骤
步骤1:修正表头匹配与数据校验
在UsersImport.php中添加调试与校验逻辑:
public function collection(Collection $rows) { // 打印表头确认键名,调试完成后可删除 // dd($rows->first()->keys()); foreach ($rows as $row) { // 增加必填字段校验,跳过无效数据 if (empty($row['Matricule']) || empty($row['Project Id'])) { continue; } User::updateOrCreate( [ 'matricule' => $row['Matricule'], ], [ 'id_badge' => $row['Badge'] ?? null, 'nom' => $row['Nom'] ?? null, 'prenom' => $row['Prenom'] ?? null, 'post' => $row['Departement'] ?? null, 'role' => $row['Role'] ?? '1', 'id_projet' => $row['Project Id'], // 移除null兜底,确保必填字段有值 ] ); } }
步骤2:调整数据库字段约束
若id_projet允许为空,创建新迁移修改字段:
Schema::table('users', function (Blueprint $table) { $table->unsignedBigInteger('id_projet')->nullable()->change(); });
若id_projet必须必填,确保Excel中Project Id列数据有效且对应projects表存在该ID
步骤3:配置模型可填充字段
在App\Models\User.php中添加$fillable:
protected $fillable = [ 'matricule', 'id_badge', 'nom', 'prenom', 'post', 'role', 'id_projet', ];
步骤4:添加异常捕获反馈
修改UsersController.php导入方法,捕获异常并返回错误信息:
public function importUsers(Request $request) { $request->validate([ 'file' => 'required|mimes:xlsx,csv' ]); try { Excel::import(new UsersImport, $request->file('file')); return back()->with('success', 'Users imported successfully!'); } catch (\Exception $e) { return back()->with('error', '导入失败:' . $e->getMessage()); } }
内容的提问来源于stack exchange,提问作者Adam El Matni
相关产品推荐
相关产品推荐

