LaravelのExcelパッケージでCSVデータをDBへ一括登録する方法

laravel-excel-csv
  • URLをコピーしました!

LaravelExcelを操作するための「Laravel Excel」というパッケージがありあます。
今回はそれを利用してCSVファイルをデータベースへ簡単にインポートする方法をご紹介します。
CSVを使ったデータ一括登録にとても便利です!

目次

Laravel ExcelでCSVをインポート

[Laravel Excel]の基本的な使い方は、パッケージを配布している公式サイトに書いてありますので参考にしてください。

あわせて読みたい
Laravel Excel Supercharged Excel exports and imports in Laravel

パッケージのインストール

いつもの如、Composerを使って[Laravel Excel]パッケージインストールします。

composer require maatwebsite/excel

Laravelバージョンによっては、[config/app.php]内のプロバイダーエイリアスの登録は不要になります。
最後にartisanで[vendor:publish]を実行すれば完了です。

php artisan vendor:publish

これでconfigディレクトリの中に[excel.php]という設定ファイルが入ります。
後程使います。

CSVデータを1行ずつ登録

今回の場合は、CSVデータをデータベース一括登録しますので、コントローラー側でストレージディレクトリに保存しているCSVデータを1行ずつ読み込んでインサートします。
その際、同じものがあれば更新、なければ新規登録を行います。
登録先のテーブル名はposts(モデル名はPost)とします。
CSVの内容はブログによくある記事のタイトルや内容を想像してください。

設定ファイルの変更

今回の例ではCSVファイルのサイズが巨大なため、以下を変更しています。
お好みで変更してください。

・・・
'settings' => [
    'memoryCacheSize' => '32MB',
    'cacheTime'       => 600
],
・・・

また、この記事を読まれているということは、日本語を使っていると思いますので、文字化けしないように入出力の文字コードを変更する必要があるかもしれません。
デフォルトはUTF-8なので、日本語ならShift-JISかな?
著者はUTF-8に変換済みのCSVファイルを使いますのでこのままです。

・・・
'encoding' => [
    'input'  => 'UTF-8',
    'output' => 'UTF-8'
],
・・・

最後に、ここが1番重要です!
CSVを1行ずつ読み込む際に、CSVのヘッダ(1行目)をキーとして使わないようにしましょう。
CSVファイルの1行目登録するテーブルのフィールド名が一致していれば変更の必要はなく、もっと簡単になりますが、日本に住んでいる限りそんなに都合の良いデータがあるはずもなく…。
ってことで、[heading]を[false]にして1行目を無視します。

'heading' => 'false',

Modelにfillableをセットする

上記の通り、CSVの1行目を使いませんので、Postモデルの[$fillable]にCSVと一致するフィールド名を登録しておきます。

// 例)
protected $fillable = ['post_id', 'title', 'body', 'category', 'tags', 'status' … ];

Controllerで差分登録

<?php
namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Post;

use Excel;class CsvController extends Controller
{
    public function __construct(Post $post)
    {
        $this->post = $post;
    }

    public function import()
    {
        $fields = $this->post->getFillable();
        $reader = Excel::load(storage_path('csv/data.csv'));
        $rows = $reader->toArray();
        foreach ($rows as $row){
            $id = $row[0];
            $record = $this->post->firstOrNew(['post_id' => $id]);
            foreach ($row as $key => $value) {
                $colmun = $fields[$key];
                $record->$colmun = $value;
            }
            $record->save();
        }
    }
}

解説

まずは、[use]でLaravel Excelを宣言して、CSV一括登録用の関数を作成します。

Excel::load(storage_path('csv/data.csv'));

で[/storage/csv/data.csv]のCSVを読み込み、

$reader->toArray();

配列に変換し、行数分ループを回します。
[firstOrNew()]でデータの存在を確認し、なければオブジェクトを生成します。
Postモデルの[$fillable]の値をキーにセットして、[save()]で登録します。
今回は差分登録するために[save()]を使ってデータを登録します。
[save()]関数は、データが存在して変更があるならupdate、存在しなければinsertを自動的に行なってくれます。

【番外編】

もしCSV1行目とテーブルのフィールド名が一致していたら、2つ目のループが不要になり、以下のように書くことができます。

    ・・・
    foreach ($rows as $row){
        $id = $row['post_id'];
        $record = $this->post->firstOrNew(['post_id' => $id]);
        $record->fill($row);
        $record->save();
    }
    ・・・・

CSVファイルをアップロードするやり方はこちらを参考に。

次はCSV出力も試してみたいです。
以上、すごく便利ですね。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメント一覧 (2件)

コメントする

CAPTCHA


目次