--- title: PHPでPDFを作成するときはphpwkhtmltopdfで戦え [2016年度版] tags: PHP PDF wkhtmltopdf author: morisuke slide: false --- # PDFは相変わらずつらい ブラウザの印刷機能にPDF変換が実装されて久しい、西暦2016年。 今もまだ色々なしがらみに押し負けたPHPerたちの不毛な戦いは続いています。 もう年の瀬ですが来年もPDFと戦っていくための情報をお届けします。 # wkhtmltopdfとphpwkhtmltopdfで幸せになろう ## wkhtmltopdf _http://wkhtmltopdf.org/_ HTMLをWebkitで解釈してPDFに変換するGoogle謹製のツールです。 HTML5 も CSS3 も難なく解釈します。 2016年12月の時点での最新バージョンは0.12.4です。 ## mikehaertl/phpwkhtmltopdf _https://packagist.org/packages/mikehaertl/phpwkhtmltopdf_ wkhtmltopdfをPHPで扱うためのラッパークラスです。 packagistで配布されています。 # 導入方法 wkhtmltopdfは64bit版Linux用バイナリを利用します。 導入環境は、CentOS 6.5 (64bit版) の想定です。 他の環境の場合は、[本家サイト](http://wkhtmltopdf.org/downloads.html)から適切なバージョンを入手しましょう。 また既にcomposerを導入しているプロジェクトを前提として話を進めます。 ## wkhtmltopdfのインストール まずはwkhtmltopdfのインストールから進めていきます。 今回利用するバージョンは0.12.4です。 ```bash $ cd /usr/local/bin $ wget http://download.gna.org/wkhtmltopdf/0.12/0.12.4/wkhtmltox-0.12.4_linux-generic-amd64.tar.xz $ xz -dv wkhtmltox-0.12.4_linux-generic-amd64.tar.xz $ tar -xf wkhtmltox-0.12.4_linux-generic-amd64.tar ``` 上記の操作を終えると、```wkhtmltox``` ディレクトリが解凍されています。 実行ファイルのフルパスは __```/usr/local/bin/wkhtmltox/bin/wkhtmltopdf```__ となります。 バージョンチェックのコマンドを実行してwkhtmltopdfの動確を行いましょう。 ```bash $ /usr/local/bin/wkhtmltox/bin/wkhtmltopdf --version wkhtmltopdf 0.12.4 (with patched qt) ``` __※ たいてい以下のパッケージが足りずに怒られるので、追加でインストールしてください__ ```bash $ yum install -y libXrender libXext ``` ## 日本語フォントのインストール wkhtmltopdfには日本語フォントが入っていないので、日本語を通すとその部分だけが真っ白になります。 必ず日本語フォントを別途インストールしましょう。 今回はIPAフォントのお世話になることにします。 _http://ipafont.ipa.go.jp/ipaexfont/download.html_ ```bash $ wget http://dl.ipafont.ipa.go.jp/IPAexfont/IPAexfont00301.zip $ unzip IPAexfont00301.zip $ mv IPAexfont00301 /usr/share/fonts ``` ## mikehaertl/phpwkhtmltopdfのインストール composerでインストールします。 導入したいプロジェクトで以下のコマンドを実行してください。 ```bash $ composer require mikehaertl/phpwkhtmltopdf ``` # PDFの出力サンプル mikehaertl\wkhtmlto\Pdfをインスタンス化して ```addPage()``` にHTMLを投げ込むと、ページが追加されます。 HTMLファイルの場所をフルパスで渡すこともできます。 ```send()``` を叩けばブラウザにPDFが表示されます。 また```send('xxx.pdf')``` のように第一引数を指定すると、定義したファイル名でPDFがダウンロードされます。 ```php:pdf.php require './vendor/autoload.php'; $html = <<

PDF化してください!

何でもしますから!

EOF; use mikehaertl\wkhtmlto\Pdf; $pdf = new Pdf([ // バイナリの位置とエンコード形式 'binary' => '/usr/local/bin/wkhtmltox/bin/wkhtmltopdf', 'encoding' => 'utf-8', // 以下の指定があるとPDFをページ端まで利用できる 'margin-top' => 0, 'margin-right' => 0, 'margin-bottom' => 0, 'margin-left' => 0, 'no-outline', ]); // ページを追加 $pdf->addPage($html); // ブラウザにPDFを表示 $pdf->send(); ``` ![pdf.php.png](https://qiita-image-store.s3.amazonaws.com/0/33480/00b52037-bdb2-ffa5-e726-c0fbd756abde.png) # 拡張して便利に バイナリの位置とエンコード形式を初期設定。 ```php:pdf.php use mikehaertl\wkhtmlto\Pdf as BasePdf; class Pdf extends BasePdf { const DEFAULT_OPTIONS = [ 'binary' => '/usr/local/bin/wkhtmltox/bin/wkhtmltopdf', 'encoding' => 'utf-8', ]; public function __construct($options = null) { $this->setOptions(self::DEFAULT_OPTIONS); parent::__construct($options); } } ``` ```php:example.php (new Pdf($html))->send(); ``` # 使用上の注意点 _https://github.com/wkhtmltopdf/wkhtmltopdf/issues/1524_ wkhtmltopdfはテーブルを使用すると、2ページ目以降にも自動でヘッダを付与してくれるのですが、 それがズレたり次の列と被ったりしてデザインが大きく崩れます。 こちらのスタイルを付与すると解決できます。 ```css:style.css tr { page-break-inside: avoid; } ``` # まとめ 以前書いたこちらの記事から一年が経ち、色々な変更が見受けれての改訂版でした。 [PHPでPDFを作成する時はwkhtmltopdf + snappyで戦え](http://qiita.com/morisuke/items/b9c18dcba99ba6501d6e) v 0.12.3からwkhtmltopdfのインストール方法が変更され、アーカイブを解凍して配置するだけとなっていたり、 IPAフォントが以前のURLではダウンロード出来なくなっていたり、 SnappyがフォローしてくれていなかったHTTPヘッダの出力までラッピングしたphpwkhtmltopdfの存在を知ったり。 たった一年で色々起こるものです。 今後もPHPでPDFを操作する方法は定期的に調査して行こうと思います。 なにか気付いた点がありましたら、編集リクエストもお待ちしております。