STEP09：Laravel5.7 でデータを埋め込んだPDFを生成する

※ 2018/11/20 Laravel5.6 から 5.7 に記述を更新


Laravel で PDFファイルを生成してみる
PDFはデータベースの値を埋め込んで動的に内容を変えられるようにしとく
この記事はPDF生成を確認するサンプル



環境設定他関連記事はこちら
[Laravel + Vue + Vuetify で業務サイト作ってみる](https://qiita.com/nobu-maple/items/d1e7170d62ab07890a7a)
https://qiita.com/nobu-maple/items/d1e7170d62ab07890a7a

－－追記ここから－－
この記事の後にLaravelでPDFを生成してVueで受け取って保存（表示）する記事を書きました
ファイル名はVue側でつけるので日本語ファイル名も問題なくつけられます
https://qiita.com/nobu-maple/items/5c4a84dffc35d011375d
－－ここまで－－

PDFの生成にはいろいろ調べたところ [TCPDF](https://tcpdf.org/) が良いらしいので使ってみた

ただし、AndroidのGooglePDFアプリだと日本語が表示できないっ！
Adobe純正を利用していただくと表示できるので、、そのうち調べます


この辺を参考にさせていただきました
[TCPDFでサポートされているHTMLタグ、CSSプロパティ](http://yk0807.com/larablog/posts/20)
[TCPDFマニュアル（勝手訳）](http://tcpdf.penlabo.net/method/w/writeHTML.html)
[【Laravel】HTMLページをPDF化してダウンロード(TCPDF使用)](http://fresh-engineer.hatenablog.com/entry/2018/06/03/135643)
[LaravelでPDFを作成する](http://cly7796.net/wp/php/to-create-a-pdf-with-laravel/)
[Qiita: Laravel5.1でbladeテンプレートを用いてPDFを作る](https://qiita.com/mu_sette/items/1346bb47ec19fac266b3)



#１．TCPDFのインストール

```bash
composer require tecnickcom/tcpdf
```

```json:composer.json
{
    "name": "laravel/laravel",
    "description": "The Laravel Framework.",
    "keywords": ["framework", "laravel"],
    "license": "MIT",
    "type": "project",
    "require": {
        "php": "^7.1.3",
        "fideloper/proxy": "^4.0",
        "goodby/csv": "^1.3",
        "laravel/framework": "5.7.*",
        "laravel/tinker": "^1.0",
        "tecnickcom/tcpdf": "^6.2"
    },
～～～
```

tcpdf 6.2 がインストールされました




#２．Bladeでテンプレートを作成

TCPDFは使えるタグもCSSも限定されているみたいなので、Bladeでは単純なHTMLで組むことにしときます

タグ：
a, b, blockquote, br, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, img, li, ol, p, pre, small, span, strong, sub, sup, table, tcpdf, td, th, thead, tr, tt, u, ul

CSS:
font-family, font-size, font-weight, font-style, color, background-color, text-decoration, width, height, text-align



```html:resources/views/pdf_test.blade.php
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<style type="text/css">
  .title25 { width: 25%; }
  .title50 { width: 50%; }
  .left {  text-align: left; }
  .center {  text-align: center; }
  .right {  text-align: right; }
  .color_white { background-color: #fff; }
  .color_blue  { background-color: #99f; }
  .font_s { font-size: 8; }
  .font_m { font-size: 12; }
</style>
</head>
<body class="color_white"><table border="1" width="100%" cellpadding="10" cellspacing="10">
    <tr class="color_blue">
      <td class="title25 font_s left  ">@isset($test01) {{ $test01 }} @endisset</td>
      <td class="title50 font_m center">@isset($test02) {{ $test02 }} @endisset</td>
      <td class="title25 font_s right ">@isset($test03) {{ $test03 }} @endisset</td>
    </tr>
  </table>
</body>
</html>
```

もし、Laravel側からわたっていない変数を参照したりするとエラーになってしまうので
@isset で存在を確認してから利用してます
メンドクサイネ。。



#３．Laravelからデータを渡してPDFを生成

Laravelから渡した変数を展開してHTMLを表示 －＞　PDF生成って流れになります
PDFファイル名に日本語は使えない模様..残念
いったんサーバ上で保存してから別手段でダウンロードさせるか..

コントローラのひな形を生成して

```
php artisan make:controller DocumentController
```

中身を記述
ダミーデータを渡してPDFを生成です


```php:app/Http/Controllers/DocumentController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use TCPDF;
use TCPDF_FONTS;

class DocumentController extends Controller
{
    public function downloadPdf()
    {
        // ダミーデータ設定
        $data['test01'] = "01 - あいうえお - left";
        $data['test02'] = "02 - あいうえお - center";
        $data['test03'] = "03 - あいうえお - right";

        // PDF 生成メイン　－　A4 縦に設定
        $pdf = new TCPDF("P", "mm", "A4", true, "UTF-8" );
        $pdf->setPrintHeader(false);
        $pdf->setPrintFooter(false);

        // PDF プロパティ設定
        $pdf->SetTitle('Title aiueo あいうえお');  // PDFドキュメントのタイトルを設定  http://tcpdf.penlabo.net/method/s/SetTitle.html
        $pdf->SetAuthor('Author aiueo あいうえお');  // PDFドキュメントの著者名を設定  http://tcpdf.penlabo.net/method/s/SetAuthor.html
        $pdf->SetSubject('Subject aiueo あいうえお');  // PDFドキュメントのサブジェクト(表題)を設定  http://tcpdf.penlabo.net/method/s/SetSubject.html
        $pdf->SetKeywords('KEY1 KEY2 KEY3 あいうえお'); // PDFドキュメントのキーワードを設定 http://tcpdf.penlabo.net/method/s/SetKeywords.html
        $pdf->SetCreator('Creator aiueo あいうえお');  // PDFドキュメントの製作者名を設定  http://tcpdf.penlabo.net/method/s/SetCreator.html

        // 日本語フォント設定
        $pdf->setFont('kozminproregular','',10);

        // ページ追加
        $pdf->addPage();

        // HTMLを描画、viewの指定と変数代入 - pdf_test.blade.php
        $pdf->writeHTML(view("pdf_test", $data)->render());

        // 出力指定 ファイル名、拡張子、D(ダウンロード)
        $pdf->output('test' . '.pdf', 'D');
        return;
   }
}
```

各種プロパティも設定しておきます



#４．Laravelルーティング設定

とりあえず、直にURL叩いて生成テストできるように追記しときます

```php:routes/web.php

Route::get('/pdf', 'DocumentController@downloadPdf');

```

#５．動作確認

サーバを起動して

```bash

php artisan serve --host=172.16.0.100  --port=8000

```

ブラウザでアクセスして
http://172.16.0.100:8000/pdf


生成されたPDFを表示する
![z03.png](https://qiita-image-store.s3.amazonaws.com/0/153259/aad597ec-6208-2cd5-a5de-4666bf9a9a49.png)

文字サイズや文字寄せ、色、幅等も反映されているようです



PDFのプロパティにもちゃんと設定されてる（日本語も）
![z04.png](https://qiita-image-store.s3.amazonaws.com/0/153259/cb5e262c-bf60-eba9-4414-fa30a0699c3f.png)




#検証
ちなみにbladeで１点変？なところがあります

```html

<body class="color_white"><table border="1" width="100%" cellpadding="10" cellspacing="10">
    <tr class="color_blue">

```

body と table をくっつけて書いてます
これをキレイに？書くと

```html

<body class="color_white">
  <table border="1" width="100%" cellpadding="10" cellspacing="10">
    <tr class="color_blue">

```

どういうわけか、テーブルの左上が欠けます
![z06.png](https://qiita-image-store.s3.amazonaws.com/0/153259/a28ed05f-a0b9-06a2-b054-0464cb40c06d.png)


どうも改行とか空白とかを描写して線がつぶれている模様
もし線が欠けたりした場合はこの辺を確認してみてくださいです



以上

Laravel でPDFを動的に生成してダウンロードすることには成功
思ってたよりも簡単に使えるようです
tcpdfの作者様に感謝です


－－追記ここから－－
この記事の後にLaravelでPDFを生成してVueで受け取って保存（表示）する記事を書きました
ファイル名はVue側でつけるので日本語ファイル名も問題なくつけられます
https://qiita.com/nobu-maple/items/5c4a84dffc35d011375d
－－ここまで－－


今回もソースはこちら
https://github.com/u9m31/u9m31/tree/step09