👏

Laravel-ExcelでCSVインポートを行う

2021/10/22に公開

CSVインポートを行う際は、僕は結構Laravel-Excelというライブラリを使用します。

今回はLaravel-ExcelでCSVインポートを行う手順をまとめてみました。

1. Laravel-Excelインストール

Laravel-Excelをインストールします。

composer require maatwebsite/excel

そして、設定ファイルも生成しておきます

php artisan vendor:publish --provider="Maatwebsite\Excel\ExcelServiceProvider"

2. importクラスを作成する

例えばユーザー情報をcsvインポートしたいとすると、適当にUserImportと名付けてimportクラスを生成します。

php artisan make:import UserImport

3. CSVインポートを実装する

実装の仕方は様々あるのですが、僕がよく行う方法を紹介します。

僕は ToCollection を使ってcsvの内容をコレクションに変換するのと、 WithStartRow を使っ、csvのデータの何行目から取り込むか?を指定します。

<?php

namespace App\Imports;

use App\Models\User;
use Maatwebsite\Excel\Concerns\WithStartRow;
use Illuminate\Support\Collection;
use Maatwebsite\Excel\Concerns\ToCollection;

/**
 * 価格テーブルのCSVインポート
 */
class PriceTableImport implements ToCollection, WithStartRow
{
    public static $startRow = 2; // csvの1行目にヘッダがあるので2行目から取り込む

    public function collection(Collection $rows)
    {
        foreach ($rows as $row) {
            User::create([
                'name' => $row[0], // 行の1列目
                'email' => $row[1], // 行の2列目
                'password' => bcrypt($row[2]), // 行の3列目
            ]);
        }
    }

    /**
     * @return int
     */
    public function startRow(): int
    {
        return self::$startRow;
    }
}

これは1つのサンプルですが、 これを基盤として、結構どんなcsvデータでもこの型で処理を行うことができます。

(補足)バリデーションをしたいときは

インポートを始める前に一回全部のデータをバリデーションしたい時があります。
つまりcsvのデータの中に一つでもバリデーションの引っかかっているものがあれば、1つもデータをインポートしないという方法です。

バリデーションをしたいときはサンプルをこのように改変します。

<?php

namespace App\Imports;

use App\Models\User;
use Maatwebsite\Excel\Concerns\WithStartRow;
use Illuminate\Support\Collection;
use Maatwebsite\Excel\Concerns\ToCollection;

/**
 * 価格テーブルのCSVインポート
 */
class PriceTableImport implements ToCollection, WithStartRow
{
    public static $startRow = 2; // csvの1行目にヘッダがあるので2行目から取り込む

    public function collection(Collection $rows)
    {
        Validator::make($rows->toArray(), [
            '*.0' => "required|string", // 名前
            '*.1' => "required|unique:users", // メールアドレス
            '*.2' => "required|min:8", // カタログ掲載ページ(かんま区切り)
        ])->validate();
	
        foreach ($rows as $row) {
            User::create([
                'name' => $row[0], // 行の1列目
                'email' => $row[1], // 行の2列目
                'password' => bcrypt($row[2]), // 行の3列目
            ]);
        }
    }

    /**
     * @return int
     */
    public function startRow(): int
    {
        return self::$startRow;
    }
}

4. コントローラからimportクラスを呼び出す

このimportクラスを使用して、csvインポートを実装します。

コントローラの方でimportクラスを呼び出すだけでcsvインポートは完成します。

use Maatwebsite\Excel\Facades\Excel;
use Maatwebsite\Excel\Validators\ValidationException;

    /**
     * CSVインポート
     */
    protected function importCsv(Content $content)
    {
        // アップロードされたCSVファイル
        $file = request()->file('file');

        try {
            $import = new UserImport();
            Excel::import($import, $file);
        } catch (ValidationException $e) {
            Log::alert($e->errors());
        }
    }

これでcsvインポートを行い、csvインポート時のバリデーションエラーもキャッチできます。

終わりに

僕がcsvインポートをする際は大体このやり方で全部いけちゃいます。もちろんlaravel8でも使えています。
ぜひ参考にしてみてください。

Discussion