laravel-admin 實現匯入功能筆記

zerocoder發表於2020-08-23

版本

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

    .
    .
    .


}

參考

laravel-admin 文件 模型表格-自定義行&批量操作

Laravel Excel 文件

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章