HTMLをPDFに変換してくれる wkhtmltopdf と、PHP ライブラリ Snappy はとても便利なのですが、ローカルファイルをレンダリングするときはMIMEやファイル拡張子によってレンダリング結果が違うのです。

注意点: wkhtmltopdf のレンダリングは拡張子かMIMEで判断している

wkhtmltopdf はレンダリングをする際に、インターネットから取得する場合は HTTP ヘッダに付与される MIME に基づきレンダリングします。ですが、ローカルファイルはMIMEを取得できないので、ファイル拡張子で判断してレンダリングしています。

そして、困ったことに、コマンドの引数でレンダリングを指定するオプションが存在しないのです。 https://github.com/wkhtmltopdf/wkhtmltopdf/issues/1866

もし拡張子が無かったり、想定外な拡張子ならエラーとなってしまいます。

失敗例: .tmp という判断困難な拡張子を与えてみた場合
wkhtmltopdf /tmp/input.tmp output.pdf
Loading pages (1/6)
Error: Failed loading page /tmp/input.tmp (sometimes it will work
just to ignore this error with --load-error-handling ignore)
Exit with code 1, due to unknown error.

回避方法: 有効な拡張子とレンダリング

有効な拡張子は .txt .text .htm .html .xml .xhtml .xsl の拡張子にしておく必要があります。 これ以外にもいくつか対応してるようですが... レンダリング結果が違うので適切な MIME や 拡張子をあたえてあげれば解決できます。

回避方法: PHP ライブラリ Snappy の場合

wkhtmltopdf のラッパーである PHP ライブラリ Snappy では、そう簡単にいきません。 まずは generateFromHtml() というメソッドが存在します。これは HTML としてレンダリングします。 ですが、Text と XML のレンダリングする関数(メソッド)は存在しないのです。

しかたないので、fork して generateFromXml() と generateFromTxt() メソッドを追加したものを作りました。

https://github.com/14e28f87/snappy

composer.json

{
    "repositories": [
        {
            "type": "vcs",
            "url": "https://github.com/14e28f87/snappy"
        }
    ],
    "require": {
        "knplabs/knp-snappy": "dev-master"
    }
}

Generate local pdf file

$snappy = new Pdf('/usr/local/bin/wkhtmltopdf');
$snappy->generateFromHtml('<h1>Bill</h1><p>You owe me money, dude.</p>', '/tmp/bill-123.pdf');
$snappy = new Pdf('/usr/local/bin/wkhtmltopdf');
$snappy->generateFromTxt('Hello World', '/tmp/bill-123.pdf');
$snappy = new Pdf('/usr/local/bin/wkhtmltopdf');
$snappy->generateFromXml('<svg> ..... </svg>', '/tmp/bill-123.pdf');

Previous Post Next Post

コメントを追加する