PHPにはMicrosoft Officeのファイルを扱うためのPHPOfficeというライブラリがあって、フレームワークLaravelにMaatwebsite/Laravel-Excelというライブラリをインストールすると、LaravelからPHPOffice/Excelの機能を使うことができる。

Laravel -> Maatwebsite/Laravel-Excel -> PHPOffice/Excel

Maatwebsite/Laravel-Excelには、loadView()というメソッドがあり、LaravelのテンプレートエンジンであるBladeのテンプレートファイルを指定すると、そのテンプレートファイルのフォーマットに従ってExcelのファイルを出力することができる。これは便利だ!

ウェブ上で作成した テーブルをExcelのファイルに出力したかったので、Maatwebsite/Laravel-ExcelからPHPOffice/Excelを使うことになった。

Maatwebsite/Laravel-Excel 

テンプレートファイルを以下のように定義し、loadView()に指定してExcelのファイルを出力した。

{{– resources/views/exports/payroll_table.blade.php –}}

<html>
  <head>
    <title></title>
    {!! Html::style(‘excel.css’) !!}
  </head>

  <body>
    <table class=”テーブルの周囲は太線”>
      <thead>
        <tr class=”ヘッダの上下は中太線”>
          <th class=”ほげほげ”></th>
        </tr>
      </thead>
      <tbody>
        @foreach($reports as $report)
        <tr class=”ヘッダ以外の上下は細線”>
          <td class=”セルの周囲は細線”></td> 
        </tr>
        @endforeach
      </tbody>
    </table>
  </body>
</html>

{{– resources/views/exports/payroll_table.blade.php –}}
その結果、作成されたファイルが以下となる。


53 PM

黒で指定したはずの線が青になっている。また、太さも反映されていない。
ヘッダのセンタリングなどはできているので、cssのファイルが読み込めていないわけではないようだ。
実装がどうなっているのかを調べた。

結論から言うと、Maatwebsite/Laravel-Excelでは、罫線の設定をCSSで行う場合、以下のフォーマットに従う必要がある。

  border: 1px solid #000000;

現在の実装では、以下のようになっている。

  • 1pxなどのサイズ指定は無視される。
  • 2番目の要素には線の種類が来ると決められている。
  • 最後の要素には色が来ると決められている。

そのため、例えば以下の設定は無効となる。

  border: 3px solid #000000 !important; // !importantがcolorとして認識されてしまい無効

.top-thick-border {
  border-top-width: 3px;
  border-top-style: solid;
  border-top-color: #000000;
} // 1行で設定しないので無効
以下のようにCSSの設定を修正したところ、罫線が正しく設定できるようになった。
.top-thick-border {
  border-top: 3px thick #000000;
}

Excelファイルを出力するには、以下のようにメソッドを呼び出す必要がある。

Excel::create(‘New file’, function($excel) {
    $excel->sheet(‘New sheet’, function($sheet) {
        $sheet->loadView(‘folder.view’);
    });
})->store();

そこで、Excel.phpという名前でcreate()を呼び出しているファイルを探す。

% find . -name “Excel.php” -print | xargs grep create
./vendor/maatwebsite/excel/src/Maatwebsite/Excel/Excel.php:    public function create($filename, $callback = null)
./vendor/maatwebsite/excel/src/Maatwebsite/Excel/Excel.php:        return $this->create($view)->shareView($view, $data, $mergeData);

findは条件に合致するファイルを取得するコマンド、xargsは標準入力を受け取って次のコマンドに渡すコマンド、grepはファイルから指定された語を検索するコマンドだ。上記で実行したコマンドの内容は「現在のディレクトリ以下から”Excel.php”という名前のファイルを取得して標準出力に出力し、標準出力を受け取って次のコマンドに渡し、標準出力からcreateという語を検索する」となる。

./vendor/maatwebsite/excel/src/Maatwebsite/Excel/Excel.phpを開いてみると、すぐに以下が見つかった。

    /**
     * Create a new file
     * @param                $filename
     * @param  callable|null $callback
     * @return LaravelExcelWriter
     */
    public function create($filename, $callback = null)
    {
        // Writer instance
        $writer = clone $this->writer;

        // Disconnect worksheets to prevent unnecessary ones
        $this->excel->disconnectWorksheets();

        // Inject our excel object
        $writer->injectExcel($this->excel);

        // Set the filename and title
        $writer->setFileName($filename);
        $writer->setTitle($filename);

        // Do the callback
        if ($callback instanceof Closure)
            call_user_func($callback, $writer);

        // Return the writer object
        return $writer;
    }
$callbackがClosureの場合に$writerを登録しているので、$writerを探すと次の記述が見つかった。
    /**
     * Writer object
     * @var LaravelExcelWriter
     */
    protected $writer;
そこで、今度はclass LaravelExcelWriterを探す。
% find . -name “*.php” -print | xargs grep LaravelExcelWorksheet | grep class
./vendor/composer/autoload_classmap.php:    ‘Maatwebsite\\Excel\\Classes\\LaravelExcelWorksheet’ => $vendorDir . ‘/maatwebsite/excel/src/Maatwebsite/Excel/Classes/LaravelExcelWorksheet.php’,
./vendor/maatwebsite/excel/src/Maatwebsite/Excel/Classes/LaravelExcelWorksheet.php:class LaravelExcelWorksheet extends PHPExcel_Worksheet {% find . -name “*.php” -print | xargs grep LaravelExcelWriter 
%