版本
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());
    });


}    

到这里完成添加导入按钮。

3IGgd.png

引入 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();
}

.
.
.

}