Laravel5.3でEXCELのデータをインポートする方法

こちらのサイトにでていたとおりにやろうとして、書かれていなかったことなどを補足。

http://reffect.co.jp/blog/post/laravel-csv-easy-way

いろいろでていたんだけど、自分なりにまとめます。

まずは、Laravel 5.3をインストール、excel01というプロジェクト名でやります。


composer create-project "laravel/laravel=5.3.*" excel01

.envファイルを修正して、MAMPのMySQLにつながるようにする。
DataBaseはLaravel_excel01をいうのをつくりました。


DB_DATABASE=Laravel_excel01
DB_USERNAME=root
DB_PASSWORD=root
DB_SOCKET = /Applications/MAMP/tmp/mysql/mysql.sock

composer.jsonににmaawebsite/excelを追加


    "require": {
        "php": ">=5.6.4",
        "laravel/framework": "5.3.*",
        "maatwebsite/excel": "~2.1.0"

Composer updateをして、パッケージをインストール


composer update

config/app.phpの’providers’と’aliases’に追記


'providers' => [

    /*
     * Laravel Framework Service Providers...
     */

Maatwebsite\Excel\ExcelServiceProvider::class,

'aliases' => [

'Excel' => Maatwebsite\Excel\Facades\Excel::class,

Productテーブルを準備する


php artisan migrate:install

Productsテーブルのためのmigrationファイルを作成


 php artisan make:migration create_products_table --create=products

migrationファイルを修正

Database/migrations/

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateProductTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('products', function (Blueprint $table) {
            $table->increments('id');
            $table->string('product_id');
            $table->string('product_name');
            $table->Integer('price');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('products');
    }
}

これで、productsテーブルがデータベースに作成されます


php artisan migrate

ルーティングの追加

routes/web.php に、下記を追加

Route::get('import','ImportController@index');
Route::post('import','ImportController@import');

Route::get('products','ProductController@index');

ImportControllerを php artisan makeコマンドで作成します。


php artisan make:controller ImportController

ImportControllerファイルは下記のように編集


namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\Product;

use Excel;
use Redirect;


class ImportController extends Controller
{
  public function index()
  {
      return view('import');
  }

  public function import(Request $request){

      $file = $request->file('file');

      $rows = Excel::load($file->getRealPath(),function($reader){

      })->get();

      $rows = $rows->toArray();

      // 最終的にエラーがでたので、ここでExcelから取得した$rowsファイルを出力しました。
      // ここまではできたのでOK
      echo '<pre>';
      var_dump($rows);
      echo '</pre>';
      
      die;


      foreach ($rows as $row){

          Product::create($row);

      }

      return redirect('products');

  }
}

Productのモデルもつくります


php artisan make:model Product

Product.phpはこんな風にしておきましょう。

namespace App;

use Illuminate\Database\Eloquent\Model;

class Product extends Model
{
  protected $fillable = [
      'product_id', 'product_name', 'price',
  ];
}

import.blade.phpをつくる

@extends('layouts.app')

@section('content')
<div class="row">
        <div class="col-md-6">

            <h2>商品情報のCSVインポート画面</h2>

            <form method="POST" action="/import" enctype="multipart/form-data">

            {{ csrf_field() }}

            <table class="table table-bordered">
            <thead>
                <tr>
                <th>項目</th>
                <th>値</th>
                </tr>
            </thead>
            <tbody>
            <div class="form-group">
                <tr>
                <th>
                <label for="pca_product_id" class="control-label">ファイル名</label>
                </th>
                <td>
                <input type="file" name="file" class="form-control">
                </td>
                </tr>
            </div>
            </tbody>
            </table>

            <div class="form-group">
                <button type="submit" class="btn btn-primary">インポートする</button>
            </div>

            </form>

        </div>
    </div>
@stop

これだけだと表示されないので、

Views/layouts/app.blade.php

というファイルをつくる

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <title>Excel</title>

    <!-- Fonts -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.5.0/css/font-awesome.min.css" integrity="sha384-XdYbMnZ/QjLh6iI4ogqCTaIjrFk87ip+ekIjefZch0Y+PvJ8CDYtEs1ipDmPorQ+" crossorigin="anonymous">
    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Lato:100,300,400,700">

    <!-- Styles -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
    {{-- <link href="{{ elixir('css/app.css') }}" rel="stylesheet"> --}}


</head>
<body>


    @yield('content')

    <!-- JavaScripts -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.3/jquery.min.js" integrity="sha384-I6F5OKECLVtK/BL+8iSLDEHowSAfUo76ZL9+kGAgTRdiByINKJaqTPH/QVNS1VDb" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" crossorigin="anonymous"></script>
    {{-- <script src="{{ elixir('js/app.js') }}"></script> --}}
</body>
</html>

ProductControllerも必要なのでつくっておきます。


php artisan make:controller ProductController

おそらくここにちゃんとかけば表示できるようになるのですが、それはまたこんど。

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class ProductController extends Controller
{
    public function index()
    {
      echo 'yes';
    }
}

ImportController.phpの中にvar_dumpをいれて$rowsの値を確認してみました。
これで、無事に表示されました。


namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\Product;

use Excel;
use Redirect;


class ImportController extends Controller
{
  public function index()
  {
      return view('import');
  }

  public function import(Request $request){

      $file = $request->file('file');

      $rows = Excel::load($file->getRealPath(),function($reader){

      })->get();

      $rows = $rows->toArray();

      // 最終的にエラーがでたので、ここでExcelから取得した$rowsファイルを出力しました。
      // ここまではできたのでOK
      echo '<pre>';
      var_dump($rows);
      echo '</pre>';
      
      die;


      foreach ($rows as $row){

          Product::create($row);

      }

      return redirect('products');

  }
}