jobsys / importexport-module
Installs: 54
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 2
Forks: 1
Open Issues: 0
Type:laravel-module
README
该模板主要功能是基于 Excel 进行数据的导入导出。
!> 该模板的数据导入
功能为异步执行,依赖于 Laravel 队列,请确保后台已经正确开起了队列命令。
# 该命令需长驻后台,可使用 supervisor 进行管理,在导入逻辑有变化后,需要重启该命令
php artisan queue:work
模块安装
composer require jobsys/importexport-module
依赖
-
PHP 依赖
{ "maatwebsite/excel": "^3.1", // Excel 操作库 }
-
JS 依赖 (无)
配置
模块配置 config/module.php
"Importexport" => [ "route_prefix" => "manager", // 路由前缀 ]
maatwebsite/excel
配置
php artisan vendor:publish --provider="Maatwebsite\Excel\ExcelServiceProvider" --tag=config
具体配置查看 Laravel Excel
模块功能
数据导入
数据导入由 NewbieImporter
组件负责前端的上传、字段对应、进度显示等功能,并结合 ImportexportService
提供的 API 进行数据的导入。
开发规范
-
在
Controller
中定义本次导入的字段,每个字段有 4 个属性分别为field
接收并存储的字段名,label
字段的名称,rule
字段的验证规则。| 属性 | 类型 | 说明 | | --- | --- |---------------------------------------------------------------------------------------------------------------| | field | string | 接收并存储的字段名 | | label | string | 字段的名称 | | rule | string | 字段的验证规则,规则与 Laravel Form Validation 一致 | | type | string | 字段的类型,如
date
,导入时会自动对该列数据进行处理 |// 定义导入字段 $fields = [ ['field' => 'name', 'label' => '学员姓名', 'rule' => 'required'], ['field' => 'student_num', 'label' => '学员编号'], ['field' => 'birthday', 'label' => '生日', 'type' => 'date'], ]; // 附属数据,将在后续的 Importer 中一并处理 $extra_data = ['creator_id' => $this->login_user_id]; // 调用 ImportexportService 的 import 方法进行数据导入 list($result, $error) = $service->import('学员信息导入', StudentImporter::class, $fields, $extra_data);
-
在页面引入
NewbieImporter
组件,其中url
属性为上一步中的 API,progress-url
由本模块提供的默认路由,extra-data
可以定义一些其它的附属属性,并可以将其与上传的数据一并发送到 Controller。组件属性
extra-data
与上一步中的extra_data
不是同一个属性,组件中的$extra-data
仅会在上传时一并发送到 Controller,而上一步中的$extra_data
会在 Importer 的store
方法中一并处理。import NewbieImporter from "@modules/Importexport/Resources/views/web/components/NewbieImporter.vue"
<a-button type="parimary" @click="() => studentImporter.openImporter()">导入数据</a-button> <NewbieImporter ref="studentImporter" :url="route('api.manager.course.student.import')" template-url="/templates/student-import-template.xlsx" :progress-url="route('api.manager.import-export.progress')" :tips="['模板中红色字段为必填项']" :extra-data="{ course_id: course.id }" />
-
处理并存储数据,在
app\Importer
中定义一个Importer
类,该类继承于Modules\Importexport\Importers\CollectionImporter
,重写该类的store
方法,该方法有两个参数$row
和$extra_data
| 参数 | 类型 | 说明| | --- | --- |------------------------| | $row | array | Excel 文件上传的一行数据| | $extra_data | array | 附属数据 |
public function store(array $row, array $extra): void { // 通过 $row 和 $extra_data 处理数据并存储,可以进行其它的验证或者是操作,如发送通知提醒等。 Student::updateOrCreate(['course_id' => $extra['course_id'], 'id_card' => $row['id_card']], array_merge($row, $extra)); }
数据导出
使用 Laravel Excel
提供的 Excel
类进行数据的导出,具体使用方法参考 Laravel Excel
开发规范
-
在
app\Exporters
中定义一个Exporter
类,参考如下:class CourseStudentExporter implements FromQuery, WithHeadings, WithMapping { use Exportable; public int $course_id; public function __construct($course_id) { $this->course_id = $course_id; } public function query() { return Student::where('course_id', $this->course_id); } public function headings(): array { return [ '学员编号', '备注', '标签', ]; } public function map($row): array { return [ land_csv_to_string($row->student_num), $row->remark, implode(', ', $row->tags ?: []), ]; } }
-
在 Controller 中调用
Excel
类的download
方法进行导出,参考如下:public function export(Request $request, Course $course) { return (new CourseStudentExporter($course_id))->download("{$course->name}学员导出.xlsx"); }
模块代码
Controller
Modules\Importexport\Http\Controllers\ImportexportController # 提供导入进度查询接口s
UI
PC 组件
web/components/NewbieImporter.vue # 导入组件
Service
-
ImportexportService
readHeaders
将上传的文件进行存储并读取 Excel 文件的表头
/** * 保存文件并读取文件头 * @param UploadedFile $file * @return array */ public function readHeaders(UploadedFile $file): array
import
导入数据
/** * 导入数据,如果上传数据中有文件,将文件保存到本地,并返回文件路径与表头,如果不含文件而只有文件路径,则进行数据导入 * @param string $title 标题 * @param string $importer 导入器 * @param array $fields 字段 * @param array $extra_data 额外数据 * @return array */ public function import(string $title, string $importer, array $fields, array $extra_data = []): array