如何在Laravel中导入具有各种模型(和子数据/模型)的单个excel文件/工作表?

时间:2019-01-10 13:42:41

标签: laravel import import-from-excel maatwebsite-excel

按照标题,我在每行中都有一个包含所有数据(父/子)的excel文件。 Laravel Excel网站显示了如何导入,假设每行只有一个模型-但是如何导入子数据? https://laravel-excel.maatwebsite.nl/3.1/imports/

例如“伪”模式:

Vector

例如,文件:students.xlsx

    Schema::create('students', function (Blueprint $table) {
        $table->increments('id')->unsigned()->index();
        $table->string('student_code',16);
        $table->string('student_name',64);
        $table->string('student_surname',64);
    });
    Schema::create('student_courses', function (Blueprint $table) {
        $table->increments('id')->unsigned()->index();
        $table->integer('student_id')->unsigned()->index();
        $table->string('course', 32);
        $table->date('start_date');
        $table->date('end_date');
        $table->timestamps();
    });
    Schema::create('student_contacts', function (Blueprint $table) {
        $table->increments('id')->unsigned()->index();
        $table->integer('student_id')->unsigned()->index();
        $table->string('contact_name', 32);
        $table->string('contact_number', 32);
        $table->timestamps();
    });

假设我的导入代码:

Student Code | Student Name | Student Surname | Course  | Course Start Date | Course End Date | Contact Person | Contact Numbers
ABC1         | Arnold       | Clarp           | C++     | 2019-01-01        | 2019-12-01      | Boogle         | 555-111-222
DEF2         | Delta        | Flork           | English | 2019-01-02        | 2019-12-02      | Google         | 555-111-333
GHI3         | Goblin       | Clark           | Science | 2019-01-03        | 2019-12-03      | Foogle         | 555-111-444

我实际上将在哪里插入“子”课程/联系方式数据的导入? 我猜想不是“返回新学生”,而是要先将其分配给变量,然后再将其导入?这是正确的方法吗? 例如:

class StudentsImport implements ToModel, WithStartRow
{
/**
* @param array $row
*
* @return \Illuminate\Database\Eloquent\Model|null
*/
public function model(array $row)
{
    return new Student([
        'student_code'                  => $row[1],
        'student_name'              => $row[2],
        'student_surname'               => $row[3],
    ]);
}

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

//按实际情况显示的代码,不再是'pseudo':

public function model(array $row)
{
    $student = new Student([
        'student_code'=> $row[1],
        'student_name'=> $row[2],
        'student_surname'=> $row[3],
    ])
    $student->courses()->create([
        'course'=>$row[4],
        'start_date'=>$row[5],
        'end_date'=>$row[6]
    ]);
    $student->contacts()->create([
        'contact_name'=>$row[7],
        'contact_number'=>$row[8]
    ]);
    return $student;
}

错误(错误未通过父ID传递)

SQLSTATE [23000]:违反完整性约束:1048列'student_id'不能为空(SQL:插入 $student = new Student([ 'bursary_provider_id' => 1, 'bursary_provider_reference' => 'xxx', 'student_name' => $row[1], 'student_initials' => $row[3], 'student_surname' => $row[2], 'passport_number' => $row[7], 'passport_expiration' => \PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($row[9]), 'country_id' => 7, 'id_number' => $row[6], 'status' => $status, 'notes' => $row[5] ]); if (isset($row[10])) { $student->visas()->create([ 'country_id' => 201, 'visa_reference_number' => $row[10], 'visa_expiration_date' => \PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($row[11]) ]); student_visascountry_idvisa_reference_number,{ {1}},visa_expiration_datestudent_id)值(201,ABCHFV4,2019-12-31 00:00:00,,2019-01-11 08:03:06,2019-01- 11 08:03:06))

2 个答案:

答案 0 :(得分:0)

答案(不要问我为什么,因为在这个阶段文档太少了)就是使用集合。

use Illuminate\Support\Collection;
use Maatwebsite\Excel\Concerns\ToCollection;

,而不是ToModel:

public function collection(Collection $rows)

,它不会“返回”任何东西。除了这些更改之外,在OP中使用完全相同的代码可以按预期工作。

答案 1 :(得分:0)

您收到此错误,因为该学生尚未写入数据库,因此没有为新的学生实例分配ID。如果使用集合,则数据将立即写入数据库。在模型功能中,您可以使用

$student=Student::Create(['bursary_provider_id' => 1,
    'bursary_provider_reference' => 'xxx',
    'student_name' => $row[1],
    'student_initials' => $row[3],
    'student_surname' => $row[2],
    'passport_number' => $row[7],
    'passport_expiration' => \PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($row[9]),
    'country_id' => 7,
    'id_number' => $row[6],
    'status' => $status,
    'notes' => $row[5]]);

这会将学生写入数据库并生成必要的ID。我不确定这如何影响性能。