Debian / Ubuntu の apt install wkhtmltopdf で入る wkhtmltopdf は「unpatched qt」版で、--footer-center などのフッター・ヘッダー指定を無視し、ローカルのCSSや画像も file:// では読みません。PDFのページ番号が消える、スタイルが当たらない、という症状はこの2点が原因です。公式配布の「patched qt」版の .deb を入れ、0.12.6以降ではローカルファイルの読み込みを明示的に許可すれば直ります。
症状からunpatched qtだと判定する
wkhtmltopdf の標準エラー出力に、次のどちらかが出ていればこの記事の対象です。
The switch --footer-center, is not support using unpatched qt, and will be ignored.
Blocked access to file /path/to/app/assets/css/style.css
1つ目はフッター・ヘッダー・目次など「Qtに手を入れないと実装できない」オプションを使ったときに出ます。エラーにはならず、警告だけ出してPDFは生成されるので、ページ番号が無いPDFを見て初めて気付きます。2つ目は 0.12.6 で入った既定の制限で、HTMLから file:// で参照したCSS・画像・フォントを読まなくなりました。こちらも警告だけでPDF自体は出ます。
入っている版がどちらかは wkhtmltopdf --version で分かります。apt版は wkhtmltopdf 0.12.6 (unpatched qt) のように、公式版は (with patched qt) と表示されます。
Dockerfileで公式の.debを入れる
公式版は wkhtmltopdf/packaging でOSごとに .deb が配布されています。php:8.2-fpm-bookworm に入れる場合の例です。
RUN apt-get update && apt-get install -y --no-install-recommends \
fontconfig libfontconfig1 libx11-6 libxcb1 libxrender1 libxext6 libjpeg62-turbo \
xfonts-75dpi xfonts-base fonts-ipafont-gothic fonts-ipafont-mincho \
&& rm -rf /var/lib/apt/lists/*
RUN set -eux; \
arch="$(dpkg --print-architecture)"; \
curl -fsSL -o /tmp/wkhtmltox.deb \
"https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6.1-3/wkhtmltox_0.12.6.1-3.bookworm_${arch}.deb"; \
dpkg -i /tmp/wkhtmltox.deb; \
rm -f /tmp/wkhtmltox.deb; \
/usr/local/bin/wkhtmltopdf --version
依存パッケージを先に入れるのが要点です。.deb は依存を自動解決しないので、最初に依存なしで dpkg -i したビルドは次のエラーで止まりました。
dpkg: dependency problems prevent configuration of wkhtmltox:
wkhtmltox depends on fontconfig; however:
Package fontconfig is not installed.
上のリストは 0.12.6.1-3 の bookworm 版が要求する依存と、日本語PDFに必要なフォント(IPAフォント)をまとめたものです。dpkg --print-architecture で amd64 / arm64 を切り替えているので、Apple Silicon のMacで作ったイメージも x86_64 のサーバーでも同じDockerfileで動きます。最後の --version はビルド時の動作確認で、ここで (with patched qt) と出れば、フッターが使える版が入っています。公式版は /usr/local/bin に入るので、apt版を /usr/bin に残していると呼び分けを間違えます。apt版は入れないでください。
ローカルファイルの読み込みを許可する
0.12.6以降は patched qt 版でも file:// の参照は既定で拒否されます。コマンドラインなら --enable-local-file-access を付けます。
wkhtmltopdf --enable-local-file-access --footer-center '[page] / [topage]' input.html output.pdf
PHPから knp-snappy 経由で呼んでいる場合は、オプションを設定に持たせます。
# knp_snappy.yaml
knp_snappy:
pdf:
enabled: true
binary: '%env(WKHTMLTOPDF_PATH)%'
options:
enable-local-file-access: true
この許可は「HTML内で file:// 参照しているものを読む」だけで、HTTP経由の参照には関係ありません。CSSをHTMLにインライン展開しているなら不要です。
直ったことの確認はPDFではなく標準エラーで見る
生成されたPDFを目で見て確認するより、標準エラーに will be ignored と Blocked access to file が出ていないことを確認する方が確実です。フッターは全ページに出るとは限らず、CSSの欠落も見落としやすいためです。2つの警告が消えたうえで、ページ番号とスタイルが載ったPDFが出ていれば完了です。