LoginSignup
1
1

Laravelでcsvファイルを簡単インポート

Posted at

はじめに

選択したCSVファイルがインポートされるまでの流れを簡単に作ってみたいと思い、必要最低限で実装。

テーブル定義

カラム CSVファイル読み込み対象
id bigint(20)
name varchar(255)
age varchar(255)
address varchar(255)
created_at timestamp
rpdated_at timestamp

今回使うcsvファイル

image

実際の動き

インポート画面

image

「CSVファイル選択」を押下し、test.csvを開く。

image

「インポート」ボタンを押下する。

※選択したファイル名を表示させたい場合はjqueryなどで実装。今回は省略

image

csvファイルの内容がインポートされる。

image

実際の処理

<!DOCTYPE html>
<html>
    <head>
        <title>Laravel CSVインポート</title>
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
    </head>
    <body>
        <div class="container mt-5">
            <form action="{{ route('csvImport') }}" method="POST" enctype="multipart/form-data">
                @csrf
                <div class="form-group mb-4" style="max-width: 500px; margin: 0 auto;">
                    <div class="custom-file text-left">
                        <input type="file" name="csvFile" class="" id="csvFile">
                        <label class="custom-file-label" for="customFile">CSVファイル選択</label>
                    </div>
                </div>
                <button class="btn btn-primary btn-lg">インポート</button>
            </form>
        </div>
    </body>
</html>

ファイルを送る際は、enctype="multipart/form-data"と、<input type="file" が必要

idにcsvFileを指定する。コントローラーで使用するhasFile()では、指定したidを参照するので、ファイル有無のバリデーションに活用できる。

コントローラーの処理

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\User;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;


class UserController extends Controller
{
    public function import(){
        return view('csvImport');
    }
    
    public function csvImport(Request $request)
    {
        if ($request->hasFile('csvFile')) {
            // リクエストからファイルを取得
            $file = $request->file('csvFile');
            $path = $file->getRealPath();
            // ファイルを開く
            $fp = fopen($path, 'r');
            // ヘッダー行をスキップ
            fgetcsv($fp);
            // 1行ずつ読み込む
            while (($csvData = fgetcsv($fp)) !== FALSE) {
                $this->InsertCsvData($csvData);
            }
            // ファイルを閉じる
            fclose($fp);
        } else {
            throw new Exception('CSVファイルの取得に失敗しました。');
        }
    }

    public function InsertCsvData($csvData)
    {
        // csvファイル情報をインサートする
        $user = new User;
        $user->name = $csvData[0];
        $user->age = $csvData[1];
        $user->address = $csvData[2];
        $user->save();
    }
    
}

まずはrequestにファイルが送られてきているか判定。
requestのファイルを参照する。
fopenのmode'r'、読み込みモードでCSVをオープンにする。
fopenのmodeについては下記を参照。(よく使いそうなもの。細かく知りたい場合はPHPマニュアルを確認)

mode 説明 ファイルポインタ
'r' 読み込みのみでオープ。 先頭に置く
'r+' 読み込み/書き出し用でオープン 先頭に置く
'w' 書き出しのみでオープン 先頭に置く
'a' 書き出しのみでオープン 終端に置く

fgetcsv関数で、csvファイルを一行ずつ配列として取得。

csvファイルを配列として取得できたので、あとはInsertCsvDataメソッドにてインサート。

業務ではバリデーションなどで複雑だと思いますが、インポートだけに着目するとシンプルだと思いました。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1