!!最新情報は以下の記事を参照して下さい!!
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などのテンプレートエンジンと組み合わせると、サクサクと帳票のたぐいを組んでいけると思います。
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);
CSS3のプロパティであるopacityも正しく解釈されていることが分かると思います。
拡張してもうちょい便利に
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);
}
}
echo (new Pdf)->output($html);
使用上の注意点
https://github.com/wkhtmltopdf/wkhtmltopdf/issues/1524
wkhtmltopdfはテーブルを使用すると、2ページ目以降にも自動でヘッダを付与してくれるのですが、それが凄い勢いでズレたり次の列と被ったりします。
こちらのスタイルを付与すると解決できます。
tr {
page-break-inside: avoid;
}
まとめ
割とどんな書き方しても解釈してくれるんでもうPDFなんて怖くありません。
PDF出力機能のチケットを切られて他の人へたらい回しにするのはもうやめましょう。
もうやめましょう(念押し)