laravel-admin 实现导入功能笔记
版本
- php 7.2
- ubuntu 18
- laravel 6.18
- laravel-admin 1.8
- maatwebsite/excel 3.1
步骤
- 添加导入数据按钮
- 引入
maatwebsite/excel
包处理数据
添加导入数据按钮
运行下面的命令创建一个普通操作类:
php artisan admin:action Tenant\\ImportTenant --name="导入数据"
生成的类文件 app/Admin/Actions/Tenant/ImportTenant.php
:
<?php
namespace App\Admin\Actions\Tenant;
use Encore\Admin\Actions\Action;
use Illuminate\Http\Request;
class ImportTenant extends Action
{
protected $selector = '.import-tenant';
public function handle(Request $request)
{
// $request ...
return $this->response()->success('Success message...')->refresh();
}
public function html()
{
return <<<HTML
<a class="btn btn-sm btn-default import-tenant">导入数据</a>
HTML;
}
}
修改这个类,提供上传文件的功能,并加上处理数据的逻辑:
<?php
namespace App\Admin\Actions\Tenant;
use Encore\Admin\Actions\Action;
use Illuminate\Http\Request;
class ImportTenant extends Action
{
protected $selector = '.import-tenant';
public function handle(Request $request)
{
// 下面的代码获取到上传的文件,然后使用`maatwebsite/excel`等包来处理上传你的文件,保存到数据库
$request->file('file');
return $this->response()->success('导入完成!')->refresh();
}
public function form()
{
$this->file('file', '请选择文件');
}
public function html()
{
return <<<HTML
<a class="btn btn-sm btn-default import-tenant"><i class="fa fa-upload"></i>导入数据</a>
HTML;
}
}
修改app/Admin/Controller/TenantController.php
, 将导入操作加入到表格的工具条中
class TenantController extends AdminController
{
protected $title = '租客';
protected function grid()
{
$grid = new Grid(new Tenant());
.
.
.
// 将导入操作加入到表格的工具条中
$grid->tools(function (Grid\Tools $tools) {
$tools->append(new ImportTenant());
});
}
到这里完成添加导入按钮。
引入 maatwebsite/excel
包处理数据
安装包
composer require maatwebsite/excel
创建一个导入类
php artisan make:import TenantsImport --model=Models\\Tenant
生成的类文件app\Imports\TenantImport.php
:
<?php
namespace App\Imports;
use App\Models\Tenant;
use Maatwebsite\Excel\Concerns\ToModel;
class TenantsImport implements ToModel
{
public function model(array $row)
{
return new Tenant([
//
]);
}
}
修改类文件,设置字段对应的列
use App\Models\Tenant;
use Maatwebsite\Excel\Concerns\ToModel;
class TenantsImport implements ToModel
{
public function model(array $row)
{
return new Tenant([
'name' => $row[0],
'phone' => $row[1],
'id_card' => $row[2]
]);
}
}
为了不读取表头,通过实现WithStartRow
接口来设置从第二行开始读取数据
namespace App\Imports;
·
·
use Maatwebsite\Excel\Concerns\WithStartRow;
class TenantsImport implements ToModel, WithStartRow
{
·
·
·
// 从2行开始读取数据
public function startRow(): int
{
return 2;
}
}
设置数据验证规则
<?php
namespace App\Imports;
.
.
.
use Maatwebsite\Excel\Concerns\Importable;
use Maatwebsite\Excel\Concerns\WithValidation;
class TenantsImport implements ToModel, WithStartRow, WithValidation
{
use Importable;
.
.
.
// 验证
public function rules(): array
{
return [
'0' => 'required',
];
}
}
自定义验证信息
namespace App\Imports;
.
.
.
class TenantsImport implements ToModel, WithStartRow, WithValidation
{
.
.
.
// 自定义验证信息
public function customValidationMessages()
{
'0.required' => '姓名未填',
}
}
在app\Admin\Actions\Tenant\ImportTenant.php
调用导入
namespace App\Admin\Actions\Tenant;
.
.
use App\Imports\TenantsImport;
class ImportTenant extends Action
{
protected $selector = '.import-tenant';
public function handle(Request $request)
{
// 下面的代码获取到上传的文件,然后使用`maatwebsite/excel`等包来处理上传你的文件,保存到数据库
$request->file('file');
$import = new TenantsImport();
$import->import($request->file('file'));
return $this->response()->success('导入完成!')->refresh();
}
.
.
.
}
跳过验证失败的行
app\Imports\TenantImport.php
:
namespace App\Imports;
.
.
.
use Maatwebsite\Excel\Concerns\SkipsOnFailure;
use Maatwebsite\Excel\Concerns\SkipsFailures;
class TenantsImport implements ToModel, WithStartRow, WithValidation, SkipsOnFailure
{
use Importable, SkipsFailures;
.
.
.
}
收集验证失败的行信息并显示
app\Admin\Actions\Tenant\ImportTenant.php
:
namespace App\Admin\Actions\Tenant;
.
.
use App\Imports\TenantsImport;
class ImportTenant extends Action
{
protected $selector = '.import-tenant';
public function handle(Request $request)
{
// 下面的代码获取到上传的文件,然后使用`maatwebsite/excel`等包来处理上传你的文件,保存到数据库
$import = new TenantsImport();
$import->import($request->file('file'));
$str = "";
foreach ($import->failures() as $failure) {
$str .= ' 第'. $failure->row() . '行 失败原因:' . implode(' ', $failure->errors()) . '<br> 行数据:' . implode(' ', $failure->values()). '<br>';
}
if ($str !== '') {
return $this->response()->error($str)->topFullWidth()->timeout(7000000);
}
return $this->response()->success('导入完成!')->refresh();
}
.
.
.
}
参考
本作品采用《CC 协议》,转载必须注明作者和本文链接
怎么验证导入的数据是否唯一
那批量导入怎样实现