Laravel 5.4
laravelcollective 5.4
Laravel Excel v2.1
を使用します。
Laravel Excelのインストール
Composerでインストールします。
composer require "maatwebsite/excel:~2.1.0"
Laravel Excel Documentation – Maatwebsite
初期設定
Laravel 5.5は必要ないですが、5.4まではコンフィグファイルにサービスプロバイダーとエイリアス登録します。
config/app.php
'providers' => [ // ... Maatwebsite\Excel\ExcelServiceProvider::class, ], 'aliases' => [ // ... 'Excel' => Maatwebsite\Excel\Facades\Excel::class, ],
CSVファイルについて
今回は価格表を想定したテーブル構造にしてみます。
アップロードCSVファイルの最初の行はカラム名を入れます。
price.csv
id,code,name,price 1,G001,商品1,100 2,G002,商品2,200 3,G003,商品3,300 4,G004,商品4,400 5,G005,商品5,500 6,G006,商品6,600 7,G007,商品7,700 8,G008,商品8,800 9,G009,商品9,900 10,G010,商品10,1000
データベース作成
データベースは「商品コード」「商品名」「金額」の項目を作成してみます。
config/app.php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreatePricesTable extends Migration
{
public function up()
{
Schema::create('prices', function (Blueprint $table) {
$table->increments('id');
$table->integer('code');
$table->string('name');
$table->integer('price');
});
}
public function down()
{
Schema::dropIfExists('prices');
}
}
migrateコマンドでデータベースにテーブルを作成します。
$ php artisan migrate
モデルの作成
モデルです。特別なことはありませんが、タイムスタンプを無効にしてます。
config/app.php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Price extends Model
{
public $timestamps = false;
protected $fillable = [
'code',
'name',
'price'
];
}
ルーティングの作成
管理画面から編集するという感じにしたいので「admin」でプレフィクスやらネームスペースを付与しています。
croutes/web.php
Route::group(['prefix' => 'admin', 'namespace' => 'Admin', 'as' => 'admin::'], function()
{
Route::get('prices', 'PricesController@index')->name('prices');
Route::patch('prices/upload', 'PricesController@upload')->name('prices.upload');
Route::get('prices/download', 'PricesController@download')->name('prices.download');
});
ビューの作成
ビューにはファイルをアップロードするフォームとダウンロードするボタンを設置します。
resources/views/admin/prices/index.blade.php
{!! Form::model($prices, [
'url' => route('admin::prices.upload'),
'method' => 'PATCH',
'files' => true
]) !!}
<div class="row">
<div class="col-md-4">
{!! Form::file('csv_file', null, ['class' => 'form-control']) !!}
</div>
<div class="col-md-8">
{!! Form::submit('アップロード', ['class' => 'btn btn-primary']) !!}
</div>
</div>
{!! Form::close() !!}
{{ link_to_route('admin::prices.download', 'ダウンロード', null, ['class' => 'btn btn-primary']) }}
コントローラーの作成
メインとなる部分です。
アップロードは差し替えにしたかったので、データを挿入する前にtruncateで全削除しています。
CSVのパース自体は\Excel::loadだけでしてくれます。
ある程度不特定のユーザーが使用擦る場合はもう少しデータのバリデーションも追記した方がよさそうですね。
app/Http/Controllers/Admin/PricesController.php
namespace App\Http\Controllers\Admin;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Price;
class PricesController extends Controller
{
public function index()
{
$prices = Price::all();
return view('admin.prices.index', compact('prices'));
}
public function upload(Request $request)
{
$this->validate($request, [
'csv_file' => 'required|mimes:txt|max:1000'
]);
$file = $request->file('csv_file');
// ファイルの読み込み
$reader = \Excel::load($file->getRealPath())->get();
$rows = $reader->toArray();
// 一度削除してから保存
Price::truncate();
if(count($rows)){
foreach ($rows as $row) {
Price::firstOrCreate($row);
}
}
\Session::flash('flash_message', '価格表を更新しました。');
return redirect()->route('admin::prices');
}
public function download(){
$price = Price::get()->toArray();
return \Excel::create('price', function($excel) use ($price) {
$excel->sheet('sheet', function($sheet) use ($price)
{
$sheet->fromArray($price);
});
})->download('csv');
}
}
今回はCSVでしたが、Laravel Excel は名前の通りエクセルファイルも扱えます。
参考サイト
【Laravel-Excel】表ファイルを読み込んでそのままDBに保存する方法【CSVインポート】

