You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 08:57:15