Laravel7 DBデータをEXCLEでダウンロードする

Laravel7 DBデータをEXCLEでダウンロードする

Laravel7でDBデータをEXCLEファイルでダウンロードするまでの手順を記述してます。ここではphpspreadsheetを使用してEXCEL操作を行います。

環境

  • OS windows10 pro 64bit
  • Composer 1.10.5
  • PHP 7.4.5
  • MariaDB 10.4.12
  • Laravel Framework 7.6.2

※windows10に Laravel のインストールはこちら
※windows10に Composer のインストールはこちら
※windows10に PHP のインストールはこちら
※windows10に MariaDB のインストールはこちら

Laravelアプリケーション作成

任意の場所で、プロジェクトを作成します 。
ここではsampleという名称で作成してます。

laravel new sample

初期設定

.envファイル設定

環境に合わせてMariaDBとの接続情報を設定しておきます。

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=root → ユーザー名を変更
DB_PASSWORD= → パスワードを記述

bootstrap導入

UIに利用しているだけです。
詳しい手順はこちらに記述してますが、下記のコマンドで利用可能になります。

composer require laravel/ui
php artisan ui bootstrap
npm install && npm run dev

日本語環境設定

configフォルダ配下の「app.php」のtimezoneとlocalを変更しておきます。

'timezone' => 'Asis/Tokyo',

'locale' => 'ja',

phpspreadsheet導入

下記のコマンドで導入可能です。

composer require phpoffice/phpspreadsheet

モデル作成

下記のコマンドを実行して、モデルとマイグレーションファイルを作成します。

php artisan make:model Task -m

「sample\app\Task.php」が作成されるので、下記の通りに編集します。

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Task extends Model
{
    
}

テーブル作成

モデル作成時に生成された「sample\database\migrations\xxxx_xx_xx_xxxxxx_create_tasks_table.php」を下記の通りに編集して、テーブルを作成します。

<?php

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

class CreateTasksTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('tasks', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('subject');
            $table->text('description')->nullable();
            $table->date('complete_date')->nullable();
            $table->boolean('completed');
            $table->timestamps();
        });
    }

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

マイグレーションを実行します。

php artisan migrate

テーブル「tasks」が作成されて、カラムも作成されます。

適当なデータを作成しておきます。

EXCEL操作コントローラー作成

EXCELとしてダウンロードするためのコントローラーを作成します。

php artisan make:controller ExcelController

app\Http\Controllers\ExcelController.phpが作成されるので、下記の通りに編集しておきます

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;

class ExcelController extends Controller
{

    public function show() {
        $task = new \App\Task;
        $table = $task->getTable();
        $columns = $task->getConnection()->getSchemaBuilder()->getColumnListing($table);
        return view('excel.show')->with('columns', $columns);

    }

    public function down(Request $request) {
        $task = new \App\Task;
        $table = $task->getTable();
        $columns = $task->getConnection()->getSchemaBuilder()->getColumnListing($table);
        $downloadColumns = [];

        foreach($columns as $column) {
            if(in_array($column, $request->columns)) {
                $downloadColumns[] = $column;
            }
        }
        // スプレッドシートを作成
        $spreadsheet = new Spreadsheet();

        $downloadData = [];
        $tasks = $task::all();

        foreach($tasks as $task) {
            $downloadData[] = $task->only($downloadColumns);
        }
        //カラム名
        $spreadsheet->getActiveSheet()->fromArray($downloadColumns, null, 'A1');
        //データ
        $spreadsheet->getActiveSheet()->fromArray($downloadData, null, 'A2');
        //ファイル名指定
        $filename = 'tasks.xlsx';
        // ダウンロード
        header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
        header('Content-Disposition: attachment; filename="'. $filename .'"');
        header('Cache-Control: max-age=0');
        header('Cache-Control: max-age=1');
        header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
        header('Cache-Control: cache, must-revalidate');
        header('Pragma: public');
        $writer = new Xlsx($spreadsheet);
        $writer->save('php://output');

    }
}

ルーティング追加

アクセスするURLを設定するため、ルーティングを記述します。

routes\web.phpに下記を追加します。

Route::get('excel/show', 'ExcelController@show');
Route::post('excel/down', 'ExcelController@down');

ビュー作成

次にレイアウト部であるviewを作成します。

resources\views内で「excel」というフォルダを作成して、フォルダ内に「show.blade.php」を下記の内容で、新たに作成します。

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <title>Laravel</title>

        <!-- Fonts -->
        <link href="https://fonts.googleapis.com/css?family=Nunito:200,600" rel="stylesheet">
        <!-- bootstrap -->
        <link href="{{ asset('css/app.css') }}" rel="stylesheet">

        <!-- Styles -->
        <style>
            html, body {
                background-color: #fff;
                color: #636b6f;
                font-family: 'Nunito', sans-serif;
                font-weight: 200;
                height: 100vh;
                margin: 0;
            }

            .full-height {
                height: 100vh;
            }

            .flex-center {
                align-items: center;
                display: flex;
                justify-content: center;
            }

            .position-ref {
                position: relative;
            }

            .top-right {
                position: absolute;
                right: 10px;
                top: 18px;
            }

            .content {
                text-align: center;
            }

            .title {
                font-size: 84px;
            }
           
            .m-b-md {
                margin-bottom: 30px;
            }
        </style>
    </head>
    <body>
        <div class="flex-center position-ref full-height">           

            <div class="content">
                <div>
                    <form id="form" method="post" action="/excel/down">
                        @csrf
                        <div class="row form-group">                            
                            <ul class="list-group list-group-flush">                            
                                    @foreach($columns as $column)
                                        <li class="list-group-item">
                                            <input class="form-check-input" name="columns[]" type="checkbox" value="{{ $column }}"> {{ $column }}
                                        </li>
                                    @endforeach                                
                            </ul>                            
                        </div>
                        <div class="row form-group">   
                            <button type="submit" class="btn btn-success">EXCLE download</button>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </body>
</html>

実行

実行します。

php artisan serve --host 0.0.0.0

ブラウザから http://プライベートIP:8000/excel/show にアクセスにアクセスします。

カラム一覧が表示されているので、ダウンロードしたいカラムをチェックして「 EXCLE download 」をクリックするとEXCLEファイルがダウンロードされることが確認できます。