人気のPHP WEBアプリケーションフレームワークLaravelのTipsを記録していきます

Laravel-Excel で一覧リストをエクセル形式やCSV形式のファイルでダウンロードさせる

● Laravel Excel で一覧リストをエクセルでダウンロードさせる

1. Laravel-Excelのインストール

composer require "maatwebsite/excel"

続けてコンフィグファイルを生成します

php artisan vendor:publish --provider="Maatwebsite\Excel\ExcelServiceProvider"

config/excel.phpが生成されます。

次を変更します

        'csv'                    => [
            'enclosure'              => '',
            'line_ending'            => "\r\n",    // 改行を Windows形式にする
            'use_bom'                => true,      // utf8 With BOM 形式にする
        ],

enclosure は CSVの各項目を囲む文字を設定します。 通常 “ ですが、いったん何もなしで設定しておいて blade 側で“を設定したいから無理だけセットするようにします。

2. Exportクラスの作成

ExportExcel クラスを生成します。

php artisan make:export ExportExcel

ファイル app/Exports/ExportExcel.php が自動生成されます。

3. app/Exports/ExportExcel.php の編集

次のように変更します。

<?php

namespace App\Exports;

use Illuminate\Contracts\View\View;
use Maatwebsite\Excel\Concerns\FromView;
use PhpOffice\PhpSpreadsheet\Cell\Cell;
use PhpOffice\PhpSpreadsheet\Cell\DataType;
use Maatwebsite\Excel\Concerns\WithCustomValueBinder;
use PhpOffice\PhpSpreadsheet\Cell\DefaultValueBinder;


class ExportExcel extends DefaultValueBinder implements FromView, WithCustomValueBinder
{
    private $view;

    public function __construct(View $view)
    {
        $this->view = $view;
    }

    /**
     * @return View
     */
    public function view(): View
    {
        return $this->view;
    }

    /**
     * 文字列型をセット
     */
    public function bindValue(Cell $cell, $value)
    {
        // 全てを文字列型で返す
        $cell->setValueExplicit($value, DataType::TYPE_STRING);
        return true;
    }
}

$cell->setValueExplicit($value, DataType::TYPE_STRING); メソッドですべてを文字列型に設定しています。
これを設定しないと「0001112222」は「1112222」として出力されてしまいます。

4. コントローラーにダウンロード命令を記述

ファイル名 download.xlsx でダウンロードさせます。

$view = \view('estimates.excel_index', compact('estimates_rows'));
return \Excel::download(new \App\Exports\ExportExcel($view), 'download.xlsx');

5. blade ファイルの作成

<table>
    <thead>
        <tr>
            <th>管理ID</th>
            <th>プログラム名</th>
        </tr>
    </thead>
    <tbody>
        @forelse ( $programs as $program )
            <tr>
                <td>{{ $program->id }}</td>
                <td>"{{ str_replace('"','""',$program->name) }}"</td>
            </tr>
        @empty
            データがありません
        @endforelse
    </tbody>
</table>

1カラム目は クォーテーション 無し
2カラム目は クォーテーション あり
としています。

5. CSVファイルにてダウンロードさせる

ファイル名を download.csv のように拡張子をCSVにするだけでokです

$view = \view('estimates.excel_index', compact('estimates_rows'));
return \Excel::download(new \App\Exports\ExportExcel($view), 'download.csv');

6. サーバー上で保存する

\Excel::download(new \App\Exports\ExportExcel($view), 'download.csv');

とすると、storage/ ディレクトリ直下にファイルが保存されます。

7. CSVファイルの文字コードをsjisにしてダウンロードさせる

一旦 utf-8 のCSVファイルを tmp/myfile.csv 保存し sjis に変換してダウンロードさせます (メモリ上で utf-8 sjis 変換を行なっているのでファイルサイズが大きい場合はメモリエラーになります。 ファイルを1行ずつ処理するように適宜コードを書き換えてください)

// いったんutf8で保存
$file_path = 'tmp/myfile.csv';
$filename = pathinfo($file_path, PATHINFO_BASENAME);
\Excel::store(new \App\Exports\ExportExcel($view), $file_path);

// sjisダウンロード
$disk = \Storage::disk('local');
$content = $disk->get($file_path);

// remove BOM
$bom = hex2bin('EFBBBF');
$content = preg_replace("/^{$bom}/", '', $content);

// utf-8 to sjis
$content = mb_convert_encoding($content, 'sjis', 'UTF-8');

$headers = [
'Content-Type'        => 'text/csv',
'Content-Disposition' => 'attachment; filename="' . $filename . '"'
];
return \Response::make($content, 200, $headers);
No.1938
07/09 13:12

edit