Configuration 配置
,由于我们将从 Excel 文件导入数据,我们还需要一个 Excel 文件,该文件应包含基于导入类型的数据,在这种情况下,我们的 Excel 文件包含学生的数据,包括姓名、电子邮件、地址、电话号码和班级/部分数据。
实现导入功能
让我们从定义 import 类开始,我们将在其中定义我们想要如何执行导入,Laravel Excel 提供了不同的方法来实现这一点,通过 Collection 或 from Model,在这种情况下,我们将使用 model 方法。文档可在此处找到
让我们从定义 Import 类开始,将这个类命名为 StudentsImport
php artisan make:import StudentsImport
这将在 app/Imports
中创建一个新文件,让我们继续填充我们的模型方法,我们还将实现 WithHeadingRow
,它允许我们在从 Excel 访问数据时使用标题名称,以及 SkipsEmptyRows
特征,它基本上会跳过任何空行。
最终的模型方法如下所示:
public function model(array $row)
{
return new Student([
'section_id' => self::getSectionId($row['class'], $row['section']),
'class_id' => self::getClassId($row['class']),
'name' => $row['name'],
'email' => $row['email'],
'address' => $row['address'],
'phone_number' => $row['phone_number'],
]);
}
如果我们仔细研究该方法,定义了两个静态方法,称为 getSectionId
和 getClassId,
这些方法是必需的,因为用户将传递 Class name 和 Section name,我们需要找到它们各自的 ID,对于 Section,我们也传递了 Class 数据,因为每个 Section 都属于一个 Class,我们需要找到相对于该 Class 的 Section。
最终的 StudentsImport
类如下所示:
<?php
namespace App\Imports;
use App\Models\Classes;
use App\Models\Section;
use App\Models\Student;
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\SkipsEmptyRows;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
class StudentsImport implements ToModel, WithHeadingRow, SkipsEmptyRows
{
public function model(array $row)
{
return new Student([
'section_id' => self::getSectionId($row['class'], $row['section']),
'class_id' => self::getClassId($row['class']),
'name' => $row['name'],
'email' => $row['email'],
'address' => $row['address'],
'phone_number' => $row['phone_number'],
]);
}
public static function getClassId($class)
{
$class = Classes::where('name', $class)->first();
return $class->id;
}
public static function getSectionId($class, $section)
{
$class_id = self::getClassId($class);
$section_model = Section::where([
'class_id' => $class_id,
'name' => $section
])->first();
return $section_model->id;
}
}
定义 filament 操作
让我们继续定义我们的 Custom Action,在哪里定义这个动作取决于用例。在本例中,我们将在 Students Index (学生索引) 页面上定义此操作。
让我们给它起个名字 importStudents
,将标签定义为 Import Students
以及一个危险
的颜色,在 form 方法中,我们将传递 FileUpload
组件并将表单字段命名为 attachment
目前,操作如下所示:
Action::make('importStudents')
->label('Import Students')
->color('danger')
->form([
FileUpload::make('attachment'),
])
对于操作方法,我们将从存储文件夹中获取文件,并确保将存储文件夹链接到公共文件夹,这样我们就可以公开访问文件。
可以使用以下命令链接存储:
php artisan storage:link
获取文件后,我们会将其传递给我们之前定义的 StudentsImport
类,这将负责从数据库中获取 Class/Section ID,并使用单个插入查询将所有数据插入数据库。
我们还将使用 Filament 的 Notification 包通知用户有关导入的信息。
最终操作如下所示:
Action::make('importStudents')
->label('Import Students')
->color('danger')
->form([
FileUpload::make('attachment'),
])
->action(function (array $data) {
// $data is an array which consists of all the form data
$file = public_path("storage/" . $data['attachment']);
Excel::import(new StudentsImport, $file);
Notification::make()
->success()
->title('Students Imported')
->body('Students data imported successfully.')
->send();
}),