👏
Laravel-ExcelでCSVインポートを行う
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