20
23

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Laravel 7とSnappyでPDFを出力する

Last updated at Posted at 2020-07-21

はじめに

LaravelでPDFを出力する方法です。

完成版のソースは以下に置いてあります。
https://github.com/naga3/snappy-sample

Laravelで使えるPDF出力ライブラリ

今回はバランスを考えてLaravel Snappyを選択しました。

Laravelプロジェクト作成

コチラを参考に適当なプロジェクトを作成します。Composerがインストールされていれば簡単に作成できます。

composer create-project --prefer-dist laravel/laravel snappy-sample
cd snappy-sample

Laravel Snappyのインストール

Laravel Snappyのドキュメントを見て進めて行きます。

まずwkhtmltopdfをインストールしますが、こちらもComposerで簡単に導入できます。WindowsやMacなど、バイナリが適合しない場合は上記ドキュメントを参照してください。

composer require h4cc/wkhtmltopdf-amd64 0.12.x

次にLaravel Snappy本体をインストールします。

composer require barryvdh/laravel-snappy

configファイルを作ります。

php artisan vendor:publish --provider="Barryvdh\Snappy\ServiceProvider"

configファイルにwkhtmltopdfの場所を書きます。上記のようにComposerからインストールした場合は

config/snappy.php
'binary' => base_path('vendor/h4cc/wkhtmltopdf-amd64/bin/wkhtmltopdf-amd64'),

PDF出力のテスト

正常にインストールできたかチェックしてみます。

routes/web.php
Route::get('/hello', function () {
    return PDF::loadHTML('<h1>Hello!</h1>')->inline();
});

image.png

 大丈夫そうですね。

Bladeを使ってPDFを出力する。

Snappyは、BladeにそのままHTMLを書いて出力できるので大変楽です。CSSも2くらいまでは正確に効きます。

まずRouteの部分です。

routes/web.php
Route::get('/members', function () {
    $member = Faker\Factory::create('ja_JP');
    return PDF::loadView('members', compact('member'))->inline();
});

Fakerでランダムなデータを生成してviewに渡しています。

次にテンプレートの部分です。

resources/views/members.blade.php
<!DOCTYPE html>
<html lang="ja">

<head>
  <meta charset="UTF-8">
  <title>名簿</title>
  <style>
    table {
      border-collapse: collapse;
    }

    tr {
      page-break-inside: avoid;
    }

    th,
    td {
      border: 1px solid black;
    }
  </style>
</head>

<body>
  <h1>名簿</h1>
  <table>
    <tr>
      <th>No.</th>
      <th>氏名</th>
      <th>住所</th>
      <th>電話番号</th>
      <th>備考</th>
      @for ($no = 1; $no <= 50; $no++) <tr>
        <td>{{ $no }}</td>
        <td style="white-space: nowrap">{{ $member->name }}</td>
        <td>{{ $member->address }}</td>
        <td>{{ $member->phoneNumber }}</td>
        <td>{{ $member->realText }}</td>
    </tr>
    @endfor
  </table>
</body>

</html>

ブラウザで確認してみます。

image.png

良さそうですね。

tr要素にpage-break-inside: avoid;を適用することによって、セルの途中で改ページされなくなります。

こんな感じ。

image.png

20
23
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20
23

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?