Laravel-excel で帳票を出力する

> Laravel Excelとは、PhpSpreadsheet（Excelなどのさまざまなスプレッドシートファイル形式の読み書きを可能にする一連のクラスを提供するPHP製のライブラリ）を基にしたLaravel特化のエクセル操作ライブラリです。
[https://laravel-excel.maatwebsite.nl/](https://laravel-excel.maatwebsite.nl/)

このライブラリの機能のひとつにインポート、エクスポート機能がある。

# 実行環境

- laravel 5.7
- laravel-excel 3.1.10

# 準備

ライブラリのインストール

```sh
composer require maatwebsite/excel
```
 次に、設定ファイルにサービスプロパイダとファサードを登録します。

```php:laravel/config/app.php
'providers' => [
    Maatwebsite\Excel\ExcelServiceProvider::class,
],
```


```php:laravel/config/app.php
'aliases' => [
    'Excel' => Maatwebsite\Excel\Facades\Excel::class,
],
```


設定ファイルのパブリッシュ

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

設定ファイル `laravel/config/excel.php` が作られます。
PDFでのエクスポート機能を利用する場合は、`pdf` の項目を編集し、PDF生成ライブラリ名を設定する。

```php
return [

        /*
        |--------------------------------------------------------------------------
        | PDF Extension
        |--------------------------------------------------------------------------
        |
        | Configure here which Pdf driver should be used by default.
        | Available options: Excel::MPDF | Excel::TCPDF | Excel::DOMPDF
        |
        */
        'pdf'      => Excel::DOMPDF,
    ],
];
```

参考
[https://www.ritolab.com/entry/160#aj_7_2](https://www.ritolab.com/entry/160#aj_7_2)

# 使用方法

## エクスポート

```bash
php artisan make:export Export
```

で生成される、以下のファイルを編集する。
初期設定では `Collection` から表を作成する設定であるが、Viewから生成されるようにすると、blade が使えるため、見た目にいい帳票が作りやすい。

```php
// app/Export/Export.php

<?php

namespace App\Exports;

use Maatwebsite\Excel\Concerns\FromCollection;

class Export implements FromCollection
{
    /**
    * @return \Illuminate\Support\Collection
    */
    public function collection()
    {
        //
    }
}
```

↓

```php
<?php

namespace App\Exports;

use Illuminate\Contracts\View\View;
use Maatwebsite\Excel\Concerns\FromView;

class Export implements FromView
{

    private $view;

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

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

次にコントローラーに export() メソッドを追加する
例に`UserController`に設定する。

`routes/web.php`にはルーティングの設定をもちろん行うこと。

```php
Route::get('users/export', 'UserController@export')->name('users.export');
```

基本的な使い方は以下のようになり、HTMLフォームで絞り込んだり、検索結果を帳票に出力することも可能になる。

### XLSXでエクスポートする

```php
<?php

namespace App\Http\Controllers;

use App\Exports\Export;
use App\Http\Requests\UserFormRequest;
use App\Models\User;

class UserController extends Controller
{

    public function index()
    {
        $users = User::with('company.companyType', 'role')->get();
        return view('users.index', compact($users));
    }

    /**
     * 帳票のエクスポート
     */
    public function export()
    {
        $users = User::with('company.companyType', 'role')->get();
        $view = \view('users.export', compact($users));
        return \Excel::download(new Export($view), 'users.xlsx');
    }

}
```
### CSVでエクスポートする

```php
public function export()
{
    $users = User::with('company.companyType', 'role')->get();
    $view = \view('users.export', compact($users));
    return \Excel::download(new Export($view), 'users.csv'); // 拡張子を変更するだけ
}
```

blade テンプレートには、`table` でレイアウトするだけで十分。
必ずしもHTML要素から書く必要はありません。

```php
<table>
  <thead>
  <tr>
    <th>{{ __('users.id') }}</th>
    <th>{{ __('company_types.name') }}</th>
    <th>{{ __('companies.name') }}</th>
    <th>{{ __('roles.name') }}</th>
    <th>{{ __('users.name') }}</th>
    <th>{{ __('users.email') }}</th>
    <th>{{ __('users.created_at') }}</th>
    <th>{{ __('users.updated_at') }}</th>
    <th>{{ __('users.created_by') }}</th>
    <th>{{ __('users.updated_by') }}</th>
  </tr>
  </thead>
  <tbody>
  @foreach ($models as $model)
    <tr>
      <td>{{ $model->id }}</td>
      <td>{{ $model->company->companyType->name }}</td>
      <td>{{ $model->company->name }}</td>
      <td>{{ $model->role->name }}</td>
      <td>{{ $model->name }}</td>
      <td>{{ $model->email }}</td>
      <td>{{ $model->created_at }}</td>
      <td>{{ $model->updated_at }}</td>
      <td>{{ $model->createdBy->name }}</td>
      <td>{{ $model->updatedBy->name }}</td>
    </tr>
  @endforeach
  </tbody>
</table>
```