Laravel6.Xにて、PDF出力システムを構築する際に調査した内容覚書

#LaravelでPDF帳票を作成　

業務にて税務処理などで帳票を出力するシステムを構築することになり、Laravelでやることになったのだが、検討時にいろいろと詰った、というか困ったことが多々あり、備忘録がてら情報を纏める。


##出力するためのフレームワーク・環境など
###PC環境
　・Windows10
　・Laravel　6.18.3

###検討対象としたフレームワーク一覧
- [x] TCPDF(+PDFI)
- [x] mPDF
- [ ] FPDF
- [x] Laravel-snappy
- [x] Laravel-dompdf

(調査と記述したものにチェック)


##調査内容
　まずイメージとして、html5で書かれた帳票イメージをPDF化するものと想定。
　帳票ってのは所謂、御役所とかに出す控除申告書とか、届出みたいなもの。
###TCPDF(+PDFI)
　**できないことが多すぎる！**（）
　PDF化する際に解釈できるCSSがかなり限定的。
　つまり、HTMLで見れた帳票そのものが出てくることがまずない。
　[こちらのかた](https://yk0807.com/larablog/posts/20)が調べてくれたことによると以下のようだ。
> 問題はサポートしているCSSプロパティ。こちらによるとこんな感じだそうです。
>>font-family, font-size, font-weight, font-style, color, background-color, text-decoration, width, height, text-align

少なすぎるだろ・・・・余白や上下寄せ、改行間隔すら弄れないってどんだけよ。
帳票みたいな細かいものには向かない。
　⇒なんか縦書き用の説明が公式にありそう・・・・

唯一の利点というか、最大の長所がFPDIを使って他PDFをtemplate、背景のように写し、その上にHTMLのイメージを投射できること。
これを使えば政府が発行している帳票データをtemplateにし、その上にHTMLを描画できる。
また、TCPDFは**座標指定**で文字描画などを行えるので、細かい調整はそちらのほうが効く。

逆にいうとpx単位で地道にあわせていく必要があるので、技術より根気が要する・・・・

###Laravel-snappy
　**CSSが使える！イヤッほ・・・・・あれ？**
　ぬか喜びでした（）
　確かにTCPDFと比べると全くレイアウト崩れが発生しませんし、styleの設定まま出てきてくれるので、純粋なレイアウトならこれ一択といっていい。
　たがしかし、なぜかwrite-mote、つまり**縦書き処理がど派手にバグる。**

　原因は不明、というか、そもそもsnappyのバグなのか、単純に調査中に環境がぶち壊れたせいなのかが切り分けできていない。
　分かったのは、出力されたPDFを見たとき、write-modeのvertical-rlを指定した文字は、単純にrotate(90)を組み込まれていたこと。
　たぶん、snappyが使ってるPDF出力APIがそう解釈している可能性がある。
　それがAPIの仕様なのか、こちらの環境のせいなのかは分からないが・・・・
　あとPFDIがないのでtemplateはない。PDFをpng等に変換して、背景として投射することで似たようなことはできる可能性があるが、業務環境にそういった便利ツールはまだ無かったので。（そもそもそんな荒療治していいのか？という）

###Laravel-dompdf
　**TCPDFよりCSSが使えるけどsnappyより使えない、以上**
　ほとんどsnappyの縦書き問題と、TCPDFのレイアウト調整に集中していたのでこちらはおざなり。

　分かったのはTCPDFよりはやりやすかったぐらい・・・？
　あとプロパティでPHPを有効化ってのがあるのですが、どうも脆弱性を抱えてるので非推奨、という記述が。
　（追記）snappyで使えたテーブル関連のCSSが結構死んでるぽい。特に位置指定関連。
　回りこみとか使えないから、名前記入表を右に配置して左にタイトル・・・という使い方ができない。
　意外と致命。

###（追記）mPDF
　**TCPDFのCSS強化版**
　TCPDFよりCSSの解釈可能タグがひじょーに多い。paddingやvertical-alignが使えるだけでかなり楽になる。それでいて**PDFtemplate**も使える。FPDFを拡張したものなので直接書き込みも自由自在。
　まさにユウコトなし。
　個人的に一番業務にぴったりと思った。

##所感？みたいなもの
　TCPDFがもてはやされてるのは、恐らく座標指定で描画できる自由度の高さからだと思う。
　これを使いこなせれば、確かにHTMLのCSS解釈が適当でも許される。
　でも、さすがに行の入り乱れた表を一つずつ調整してはめ込んでいくのはさすがに疲れる・・・技術よりも、**あきらめないココロ**が要求される笑
　ただやっぱ別PDFをtemplateで読み込めるのはいい。
　とくに細かい表や固定文字が乱立している御役所書類に関しては笑

　snappy、dompdfはHTMLを純粋に出すだけなら最良のフレームワーク。
　確かに縦書きスタイルとか、妙な挙動はするが、それ以外はほぼ良好。
　CSS側さえしっかり組めれば問題ない。
　ただ、templateがないので帳票みたいな仕様がカッチリしてるのは別問題。
　こればっかりはTCPDF+PFDIのほうが圧倒している。


　上記のフレームワークは、どれもHTMLを読み込んでいるだけなので、

```php:pdf.php
\PDF::loadView('html_from_view', [
            'year' => '2020年',
            'name' => 'PDF出力テスト',
        ]);
```

　こんな感じでviewにパラメタを渡せるし、

```php:pdf.blade.php
    @component('title_template')
    @endcomponent
```

　こういったbladeテンプレートという形でヘッダーやタイトルを組み込むことも普通にできる。
　ただCSSの制約は受けるので、TCPDFとsnappyやdomは出力イメージが全く違っちゃうのでそこだけ注意。

　
##参考にした偉大なる先達者たちのサイト
[あるWebプログラマの修行日記 Ver.2](https://yk0807.com/larablog/posts/20)
[Laravel-Snappyでpdfを出力できるようになるまで[1/25更新]](https://qiita.com/ats05/items/cbb2956727cad2681d1d)
[アイネクシオ（inexio） FuelPHPでテンプレートPDFファイルに動的データ追加](https://inexio.jp/20160119-1007/)
[座標を使ってPDFを出力するTCPDFの使い方](https://qiita.com/haruna-nagayoshi/items/85c172cf7c0a68e0c092)
[しんくろぐ LaravelでPDF出力](http://spacetimebubble.net/blog/2019/04/07/laravel%E3%81%A7pdf%E5%87%BA%E5%8A%9B/)
[Laravel・PHP入門 【Laravel】HTMLページをPDF化してダウンロード(TCPDF使用)](http://fresh-engineer.hatenablog.com/entry/2018/06/03/135643)
[Laravel環境で日本語のPDFを作成する方法(Laravel-dompdf)](https://reffect.co.jp/laravel/how_to_create_pdf_in_laravel)
[Laravel環境で日本語のPDFを作成する方法(Laravel-Snappy)](https://reffect.co.jp/laravel/how_to_create_pdf_in_laravel_snappy)
[Top 5 : Best open source PDF generation libraries for PHP](https://ourcodeworld.com/articles/read/226/top-5-best-open-source-pdf-generation-libraries-for-php)

他にも有象無象のサイトを見たのですが、思い出せるのはこれだけ・・・
思い出したり、新しく見つけたら追記していきます。