Laravel 5.4
laravelcollective 5.4
Laravel Excel v2.1
を使用します。
Laravel Excelのインストール
Composerでインストールします。
composer require "maatwebsite/excel:~2.1.0"初期設定
Laravel 5.5は必要ないですが、5.4まではコンフィグファイルにサービスプロバイダーとエイリアス登録します。
'providers' => [ // ... Maatwebsite\Excel\ExcelServiceProvider::class,],'aliases' => [ // ... 'Excel' => Maatwebsite\Excel\Facades\Excel::class,],CSVファイルについて
今回は価格表を想定したテーブル構造にしてみます。
アップロードCSVファイルの最初の行はカラム名を入れます。
id,code,name,price1,G001,商品1,1002,G002,商品2,2003,G003,商品3,3004,G004,商品4,4005,G005,商品5,5006,G006,商品6,6007,G007,商品7,7008,G008,商品8,8009,G009,商品9,90010,G010,商品10,1000データベース作成
データベースは「商品コード」「商品名」「金額」の項目を作成してみます。
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モデルの作成
モデルです。特別なことはありませんが、タイムスタンプを無効にしてます。
namespace App;
use Illuminate\Database\Eloquent\Model;
class Price extends Model{ public $timestamps = false;
protected $fillable = [ 'code', 'name', 'price' ];}ルーティングの作成
管理画面から編集するという感じにしたいので「admin」でプレフィクスやらネームスペースを付与しています。
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');
});ビューの作成
ビューにはファイルをアップロードするフォームとダウンロードするボタンを設置します。
{!! 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だけでしてくれます。
ある程度不特定のユーザーが使用擦る場合はもう少しデータのバリデーションも追記した方がよさそうですね。
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 は名前の通りエクセルファイルも扱えます。

