maatwebsite/Excel 3.1 使用教程 (匯入篇)

GitPush發表於2019-08-10

maatwebsite/excel 使用教程 (匯入篇)

官方文件

https://docs.laravel-excel.com/3.1/getting...

GIT 地址

https://github.com/maatwebsite/Laravel-Exc...

作為一個和 laravel 契合度很高的 excel 工具包,大家應該都是用過這個工具。特別是 2.x 版本幾乎是用laravel框架都接觸過,3.x 基本上全部重構,全網幾乎找不到比較完善的教程,我就先拋磚引玉,大概把我用到的功能使用方式列一下,歡迎大家補充。

環境要求
  • PHP: ^7.0

  • Laravel: ^5.5

安裝方式
composer require maatwebsite/excel

因為目前 3.1 只支援 Laravel 5.5 以上,所以會自動註冊。

excel 匯入

新建匯入檔案,匯入匯出業務程式碼儘量不要和原來業務耦合。我們拿官網 user 模組舉例

php artisan make:import UsersImport --model=User

會在 app 目錄下建立 Exports 目錄

.
├── app
│   ├── Imports
│   │   ├── UsersImport.php
│ 
└── composer.json

UsersImport.php 程式碼內容

<?php

namespace App\Imports;

use App\User;
use Illuminate\Support\Facades\Hash;
use Maatwebsite\Excel\Concerns\ToModel;

class UsersImport implements ToModel
{
    /**
     * @param array $row
     *
     * @return User|null
     */
    public function model(array $row)
    {
        return new User([
           'name'     => $row[0],
           'email'    => $row[1], 
           'password' => Hash::make($row[2]),
        ]);
    }
}

業務控制器中呼叫

use App\Imports\UsersImport;
use Maatwebsite\Excel\Facades\Excel;
use App\Http\Controllers\Controller;

class UsersController extends Controller 
{
    public function import() 
    {
        Excel::import(new UsersImport, 'users.xlsx');
    }
}

需要說明的是,上面所用的模式是 toModel,不需要手動去呼叫 save 方法,如果需要手動控制儲存過程,請使用下列方法。

<?php

namespace App\Imports;

use App\User;
use Illuminate\Support\Facades\Hash;
//替換 toModel
use Maatwebsite\Excel\Concerns\ToCollection;

class UsersImport implements ToCollection
{
    /**
     * 使用 ToCollection
     * @param array $row
     *
     * @return User|null
     */
    public function ToCollection(Collection $rows)
    {
        //如果需要去除表頭
        unset($rows[0]);
        //$rows 是陣列格式
        $this->createData($rows);
    }

    public function createData($rows)
    {
        //todo
    }
}

Excel 匯入基本功能到這基本完成,應該可以滿足80%業務需求。如果有更多需求請繼續閱讀,下面將介紹分塊匯入、多表匯入。

分塊匯入

如果 excel 資料量比較大,不適合一次性匯入資料庫,可以透過按量分塊匯入的方式節約記憶體。

按 1000 條為基準取出匯入

namespace App\Imports;

use App\User;
use Maatwebsite\Excel\Concerns\ToModel;
//新增
use Maatwebsite\Excel\Concerns\WithBatchInserts;
use Maatwebsite\Excel\Concerns\WithChunkReading;

class UsersImport implements ToModel, WithBatchInserts, WithChunkReading
{
    public function model(array $row)
    {
        return new User([
            'name' => $row[0],
        ]);
    }

    //批次匯入1000條
    public function batchSize(): int
    {
        return 1000;
    }
    //以1000條資料基準切割資料
    public function chunkSize(): int
    {
        return 1000;
    }
}

需要注意的是 批次匯入 只支援 ToModel 模式,如果你需要對資料進行更改,建議先批次匯入臨時表,再修改資料匯入業務相關表。

多 sheet 匯入

和匯出比較類似,需要兩步操作,第一步讀取整體 excel 結構,第二步完成對應表資料匯入。

第一個檔案 UsersImport.php

namespace App\Imports;

use Maatwebsite\Excel\Concerns\WithMultipleSheets;

class UsersImport implements WithMultipleSheets 
{

    public function sheets(): array
    {
        //這裡需要注意的是鍵,這個鍵可以是sheet表的名稱,比如 'sheet1'=> new FirstSheetImport()
        return [
            0 => new FirstSheetImport(),
            1 => new SecondSheetImport(),
        ];
    }
}

這裡我沒有找到獲取所有 sheet 的方法,所以只能一個個指定,如果你呼叫的方法是一致的,可以參考以下我的寫法。如果你有更好的方式,歡迎交流。

public function sheets(): array
{
    $sheet = [];
    for ($i=1; $i<=26; $i++) {
        $sheet[$i] = new CustomSheetImport();
    }
    return $sheet;
}

第二個檔案處理資料

namespace App\Imports;

use Illuminate\Support\Collection;
use Maatwebsite\Excel\Concerns\ToCollection;

class FirstSheetImport implements ToCollection
{
    public function collection(Collection $rows)
    {
        //todo
    }
}

其他比如資料驗證之類的方法我覺得還是不要使用它提供的方式,大部分業務環境不需要這些額外繁瑣的東西。
LNCODE
如果你有其他需要分享的功能模組歡迎在評論提出,我會更新文件。

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

相關文章