Help us understand the problem. What is going on with this article?

Laravel-Excelでbladeのテンプレートを使って複数シートで作成する

概要

いろんな事務所に所属するバンドのデータを取得。bladeにテンプレートを作り、事務所ごとのデータをExcelファイルでダウンロードするというパターンを想定して実装する。テーブルはbladeにてテンプレートを作る。

Laravel-Excelのインストールの手順などは省く。
bladeでテンプレートを作って出力する方法は下記を参考。

Laravel-excel で帳票を出力する
https://qiita.com/ShibuyaKosuke/items/7e5e99c51546a578d97b

複数ファイルは出せないのか

最初はダウンロードする処理を foreach で回して事務所ごとにファイルをダウンロードする処理をすればいいだろうと安易に考えていたが、どうもそれはできないようで(ダウンロードする処理で return しなければならないため)、ファイルはひとつだが事務所ごとに複数シートで分けるということにした。
Laravel-Excel を使って複数シートでダウンロードする方法は公式サイトも含めて探せばいくつか見つかるが、bladeでテンプレートを作って出力するパターンのものは工夫して作らなければならなかった。

必要なファイル

以下4点のファイルを用意すれば作ることができる。
ディレクトリやファイル名は任意。
テンプレートとなるbladeは割愛する。

bandController.php
public function export()
{
// 中略

// 複数シートでのダウンロード
$view = \view('band_information.export')
    ->with('offices', $offices);
return (new MultiBookExport($view))->download("band_info.xlsx");
}
BandInfosExport.php
<?php

namespace App\Exports;

use Maatwebsite\Excel\Concerns\Exportable;
use Illuminate\Contracts\View\View;
use Maatwebsite\Excel\Concerns\WithMultipleSheets;

class BandInfosExport implements WithMultipleSheets
{
    use Exportable;

    private $view;

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

    public function sheets(): array
    {
        $sheets = [];
        $i = 1;

        // 事務所数
        $count = count($this->view->offices);

        // 事務所の数だけシートを作る
        foreach ($this->view->offices as $office) {

            $sheets[] = new BandInfosSheet($office);

            if ($i === $count) {
                return $sheets;
            }
            $i++;
        }
    }
}
<?php

namespace App\Exports;

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

class BandInfosSheet implements FromView, WithTitle
{
    private $office;

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

    public function view(): View
    {
        // 事務所に所属するバンドのデータをbladeのテンプレートに渡す
        return \view('band_information.export')
            ->with('informations', $this->office['band_informations']);        
    }

    public function title(): string
    {
        // シート名となる事務所名を取得
        return $this->office->name;
    }
}
arsagapartners
最高品質を最速で。 業務未経験でも最速最高の成長を!
https://www.arsaga.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away