はじめに
選択したCSVファイルがインポートされるまでの流れを簡単に作ってみたいと思い、必要最低限で実装。
テーブル定義
カラム | 型 | CSVファイル読み込み対象 |
---|---|---|
id | bigint(20) | |
name | varchar(255) | ○ |
age | varchar(255) | ○ |
address | varchar(255) | ○ |
created_at | timestamp | |
rpdated_at | timestamp |
今回使うcsvファイル
実際の動き
インポート画面
「CSVファイル選択」を押下し、test.csvを開く。
「インポート」ボタンを押下する。
※選択したファイル名を表示させたい場合はjqueryなどで実装。今回は省略
csvファイルの内容がインポートされる。
実際の処理
<!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メソッドにてインサート。
業務ではバリデーションなどで複雑だと思いますが、インポートだけに着目するとシンプルだと思いました。