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

Laravel 7使用laravel-excel导入Excel时如何正确设置关联表外键?

解决方案

核心思路

通过给导入类添加构造函数的方式,把控制器中刚保存完成的主表ID直接传递到导入类内部使用,不需要再查询数据库获取主表ID。

第一步:修改导入类 BookedVoucherDetailImport.php

<?php
namespace App\Imports;
use App\Model\BookedVoucherDetail;
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithStartRow;

class BookedVoucherDetailImport implements ToModel, WithStartRow
{
    // 新增私有属性存储主表ID
    protected $bookedVoucherId;

    // 新增构造方法接收主表ID
    public function __construct($bookedVoucherId)
    {
        $this->bookedVoucherId = $bookedVoucherId;
    }

    /**
     * @return int
     */
    public function startRow(): int
    {
        return 2;
    }

    /**
    * @param array $row
    *
    * @return \Illuminate\Database\Eloquent\Model|null
    */
    public function model(array $row)
    {
        return new BookedVoucherDetail([
            // 直接使用传入的主表ID
            'booked_voucher_id'     => $this->bookedVoucherId,
            'course_code'           => $row[0], 
            'voucher_code'          => $row[1],
            'user_name'             => $row[2],
            'status'                => 'OK'
        ]);
    }
}

第二步:修改控制器中导入调用代码

找到控制器中Excel::import那一行,实例化导入类时传入刚保存的主表ID:

if ($data->save()) {
    // 把主表ID作为参数传入导入类构造方法
    Excel::import(new BookedVoucherDetailImport($data->id), $request->file('file'));
}

可选优化:添加事务保证数据一致性

如果担心导入过程中出错导致主表已保存但明细缺失的问题,可以用数据库事务包裹整个操作:

use DB;

public function import(Request $request)
{
    $validator = Validator::make($request->all(), [
        'file' => 'required|mimes:csv,xlx,xls,xlsx'
    ]);

    if ($validator->fails()) {
        return back()->with('toast_error', $validator->messages()->all()[0])->withInput();
    }

    DB::beginTransaction();
    try {
        $data = new BookedVoucher();
        $data->name = $request->name;
        $fileName = time().'_'.$request->file->getClientOriginalName();
        $filePath = $request->file('file')->storeAs('reports', $fileName, 'public');

        $data->file = $filePath;
        $data->created_by = \Auth::user()->id;
        $data->save();
        
        Excel::import(new BookedVoucherDetailImport($data->id), $request->file('file'));
        
        DB::commit();
        return redirect()->back()->with('success','数据导入成功');
    } catch (\Exception $e) {
        DB::rollBack();
        return back()->with('toast_error', '导入失败:'.$e->getMessage())->withInput();
    }
}

内容的提问来源于stack exchange,提问作者Hilmi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 05:51:00