PHP
PDF
wkhtmltopdf

PHPでPDFを作成する時はwkhtmltopdf + snappyで戦え

More than 1 year has passed since last update.


!!最新情報は以下の記事を参照して下さい!!

PHPでPDFを作成するときはphpwkhtmltopdfで戦え [2016年度版]


HTMLをPDFに変換するアプローチのつらみ

・インラインのCSSしか受け付けない

・そもそもCSS2.0系のプロパティしか受け付けない

・セレクタで要素が絞り込めない

mPDF、主に君のことだ。


wkhtmltopdfとsnappyで幸せになろう


wkhtmltopdf

http://wkhtmltopdf.org/

Webkit html to pdf の略。

名前からも分かるようにHTMLをWebkitで解釈してPDFに変換するGoogle謹製のツールです。

もちろん、HTML5 も CSS3.0 も難なく解釈します

最高感ある。


knplabs/knp-snappy

https://packagist.org/packages/knplabs/knp-snappy

wkhtmltopdfをPHPで扱うためのラッパークラスです。

packagistで配布されています。


導入方法

CentOS 6.5 (64bit版) を想定しています。

他の環境の場合は必要なバージョンが異なるので、本家サイトから適切なwkhtmltopdfパッケージを入手しましょう。


wkhtmltopdfのインストール

まずはwkhtmltopdfのインストールから進めていきます。

rpm -ivh 実行時にエラーが発生した場合は、エラーを見ながらyumで足りないパッケージを入れましょう。

$ cd /usr/local/src

$ wget http://download.gna.org/wkhtmltopdf/0.12/0.12.2.1/wkhtmltox-0.12.2.1_linux-centos6-amd64.rpm
$ rpm -ivh wkhtmltox-0.12.2.1_linux-centos6-amd64.rpm


日本語フォントのインストール

wkhtmltopdfには日本語フォントが入っていないので、日本語を通すとその部分だけが真っ白になります。

なので必ず日本語フォントを別途インストールしましょう。

今回はIPAフォントのお世話になることにします。

http://ipafont.ipa.go.jp/ipaexfont/download.html

$ wget http://ipafont.ipa.go.jp/ipaexfont/ipaexm00201.php

$ unzip ipaexm00201.php
$ mv ipaexm00201/ /usr/share/fonts


snappyの導入

composerで持ってきます。

導入したいPHPのプロジェクトで以下のコマンドを実行してください。

composer require knplabs/knp-snappy


PDFの出力サンプル

HTMLを用意してSnappyのgetOutputFromHtmlメソッドに投げるだけです。

Smartyなどのテンプレートエンジンと組み合わせると、サクサクと帳票のたぐいを組んでいけると思います。


sample

require './vendor/autoload.php';

$html = <<<EOF
<style>
.red {
color:red;
background-color: black;
font-size:30px;
}
.opacity {
opacity: 0.3;
}
</style>

<div class="red">
<p>祝ってやる</p>
<p>祝ってやる</p>
<p>祝ってやる</p>
<p>祝ってやる</p>
<p class="opacity">祝ってやる</p>
<p>祝ってやる</p>
<p>祝ってやる</p>
<p>祝ってやる</p>
<p class="opacity">祝ってやる</p>
<p>祝ってやる</p>
<p>祝ってやる</p>
</div>
EOF;

// wkhtmltopdfの位置をコンストラクタに渡す
$pdf = new Knp\Snappy\Pdf('/usr/local/bin/wkhtmltopdf');

// encoding = utf-8をセット
$pdf->setOption('encoding', 'utf-8');

// PDFをブラウザに出力
header("Content-Type: application/pdf");
echo $pdf->getOutputFromHtml($html);


test.php.png

CSS3のプロパティであるopacityも正しく解釈されていることが分かると思います。


拡張してもうちょい便利に


pdf.php

class Pdf extends \Knp\Snappy\Pdf

{
// 初期値にwkhtmltopdfの位置を登録、エンコード設定をUTF-8に変更
public function __construct($binary = '/usr/local/bin/wkhtmltopdf', array $options = [], array $env = null)
{
parent::__construct($binary, $options, $env);
$this->setOption('encoding', 'utf-8');
}

// headerの出力も自動で行う
public function output($html)
{
header("Content-Type: application/pdf");
return $this->getOutputFromHtml($html);
}
}



example

echo (new Pdf)->output($html);



使用上の注意点

https://github.com/wkhtmltopdf/wkhtmltopdf/issues/1524

wkhtmltopdfはテーブルを使用すると、2ページ目以降にも自動でヘッダを付与してくれるのですが、それが凄い勢いでズレたり次の列と被ったりします。

こちらのスタイルを付与すると解決できます。

tr {

page-break-inside: avoid;
}


まとめ

割とどんな書き方しても解釈してくれるんでもうPDFなんて怖くありません。

PDF出力機能のチケットを切られて他の人へたらい回しにするのはもうやめましょう。

もうやめましょう(念押し)