wkhtmltopdfは、HTMLをQt WebKitで描画してPDFや画像にするコマンドラインツールです。請求書や納品書の帳票出力に長く使われてきましたが、最終版は2020年6月の0.12.6で、GitHubのリポジトリは2023年1月にアーカイブされました。この記事では、wkhtmltopdfの仕組みと現在の入手方法、A4帳票を出すコマンド例、日本語の文字化けと改ページずれの対処、CVE-2022-35583を踏まえた安全な使い方、WeasyPrint・Gotenberg・Playwrightへの移行判断までを実装者向けに整理します。
まとめ:wkhtmltopdfの新規採用は見送り、既存の帳票は期限を決めて移行
新しく作るシステムでwkhtmltopdfを選ぶ理由は、2026年10月時点でほぼ残っていません。描画エンジンのQtWebKitは2016年にQtから外れ、本体も更新が止まっています。Debian 13の公式リポジトリからも消えました。
既存の帳票出力で動いているなら、すぐ止める必要はありません。条件は2つで、変換するHTMLを自社のテンプレートだけで組み立てていること、変換プロセスを外部ネットワークから切り離していることです。どちらかを満たせないなら移行を優先します。移行先は、自社で管理するHTMLの帳票ならWeasyPrint、複数のアプリから共通で呼ぶならGotenberg、JavaScriptの描画が要る画面ならPlaywrightが第一候補になります。
帳票の出力・保存まで含めて業務システムを作り直す場合は、文書管理システム開発として、テンプレートの移植と電子保存の要件をまとめて設計するほうが手戻りが少なくなります。
wkhtmltopdfの仕組みと、Qt WebKitに縛られた0.12.6系の現状
HTMLをQt WebKitで描画しPDFへ書き出すコマンドラインツールの構造
wkhtmltopdfは、ブラウザのレンダリングエンジンであるWebKitをQt経由で呼び出し、画面を持たないまま描画結果をPDFに書き出します。入力はURL・ローカルのHTMLファイル・標準入力のいずれでもよく、1回の実行で複数ページや目次(toc)、表紙(cover)を1つのPDFにまとめられます。ライセンスはLGPL-3.0です。
PythonのpdfkitやRubyのwicked_pdf・PDFKitといったライブラリは、内部でこのコマンドを子プロセスとして起動しています。ライブラリ側を最新にしても、描画の品質と安全性は呼び出す先のwkhtmltopdfの版で決まる点に注意してください。
0.12.6が最終版、2023年1月のリポジトリのアーカイブまでの経緯
公式サイトのダウンロードページは、安定版を「0.12.6系、2020年6月11日リリース」と案内しています。プロジェクトの状況ページには、Qt 4が2015年以降サポートされず、QtWebKitも2015年に非推奨、2016年に削除されたと書かれています。上流に修正を返す先が無い、という説明です。
本体のGitHubリポジトリは2023年1月2日にアーカイブされ、読み取り専用になりました。配布用パッケージを作るpackagingリポジトリも2023年8月28日にアーカイブ済みです。最後の配布物は0.12.6.1-3で、Debian 12(bookworm)やAlmaLinux 9向けのパッケージが置かれています。
状況ページは「0.12.7を最後に出す」と予告していましたが、2026年10月時点で0.12.7は出ていません。
Debian 13で消えた公式パッケージとUbuntu 24.04に残る0.12.6の差
OS標準のパッケージで入れる場合、ディストリビューションごとに状況が分かれます。Debian 12の標準パッケージはフォーク版Qtではないため、一部オプションに対応せず、X11サーバが必要です。
| OS | 標準リポジトリの版 | 注意点 |
|---|---|---|
| Debian 12(bookworm) | 0.12.6-2 | 非フォークQt:一部機能非対応・X11サーバ必須 |
| Debian 13(trixie) | 提供なし | 2025年2月5日にtestingから削除 |
| Ubuntu 22.04(jammy) | 0.12.6-2 | Debian由来の非パッチ版 |
| Ubuntu 24.04(noble) | 0.12.6-2build2 | Debian由来の非パッチ版 |
出典はDebianのパッケージ情報とDebianのパッケージ追跡ページ、Ubuntuのパッケージ検索です。Debian 13へ上げるとapt-getで入らなくなるため、OS更新の計画とwkhtmltopdfの扱いは同時に決める必要があります。
wkhtmltopdfを入れてHTMLの帳票をA4のPDFに変換する手順と設定
公式配布のパッチ版とOS標準パッケージで使えるオプションが変わる理由
公式サイトの配布物は、wkhtmltopdf向けに手を入れたQt(patched qt)でビルドされています。wkhtmltopdf --versionの出力に「with patched qt」と出るのがこの版です。ダウンロードページは、一部の機能がパッチ版Qtでしか動かず、ディストリビューションごとに挙動が変わると明記しています。
実務で差が出るのはヘッダー・フッター、PDFのしおり(アウトライン)、複数ページの結合です。Debianのパッケージ説明にも「一部のオプションは非対応」とあります。フッターにページ番号が出ないという相談の多くは、OS標準パッケージを入れていることが原因です。
コンテナで動かすなら、bookworm用のパッチ版debと日本語フォントをまとめて入れます。
# Debian 12(bookworm)amd64:公式配布のパッチ版+日本語フォント
FROM debian:bookworm-slim
RUN apt-get update \
&& apt-get install -y --no-install-recommends curl ca-certificates fonts-noto-cjk \
&& curl -LO https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6.1-3/wkhtmltox_0.12.6.1-3.bookworm_amd64.deb \
&& apt-get install -y --no-install-recommends ./wkhtmltox_0.12.6.1-3.bookworm_amd64.deb \
&& rm -f wkhtmltox_*.deb && rm -rf /var/lib/apt/lists/*
RUN wkhtmltopdf --version
ビルドの最後で版を表示させておくと、非パッチ版が混ざったときにCIのログで気づけます。
請求書HTMLをA4・余白15mm・ページ番号付きでPDFにするコマンド例
オプション名と既定値は公式のusageに一覧があります。帳票でよく使う組み合わせは次のとおりです。
wkhtmltopdf \
--page-size A4 \
--margin-top 15mm --margin-bottom 15mm \
--margin-left 10mm --margin-right 10mm \
--encoding utf-8 \
--print-media-type \
--footer-center "[page] / [topage]" \
--footer-font-size 8 \
--disable-javascript \
invoice.html invoice.pdf
[page]は現在のページ番号、[topage]は最終ページ番号に置き換わります。[date]や[title]も使用できる変数です。--print-media-typeを付けると、HTML側の印刷用CSSが効くようになります。余白の既定は左右10mmで、上下は帳票の印字位置に合わせて決めます。
PythonのpdfkitからHTMLを変換するときのパス指定とオプション
pdfkitの最新版は2021年11月の1.0.0です。値を持たないフラグはNoneで渡します。
import pdfkit
# which wkhtmltopdf で確かめたパスを指定する
config = pdfkit.configuration(wkhtmltopdf="/usr/local/bin/wkhtmltopdf")
options = {
"page-size": "A4",
"encoding": "UTF-8",
"margin-top": "15mm",
"margin-bottom": "15mm",
"footer-center": "[page] / [topage]",
"disable-javascript": None,
}
pdfkit.from_file("invoice.html", "invoice.pdf", options=options, configuration=config)
pdfkit自体も2021年から更新が止まっています。移行するときはwkhtmltopdfと一緒に置き換える前提で、呼び出し箇所を1つの関数にまとめておくと差し替えが楽になります。
日本語の文字化けと改ページずれ、帳票出力で詰まる3つの箇所と対処
日本語が豆腐や空白になる原因はフォント不足、fc-listで有無を確認
日本語が□(いわゆる豆腐)や空白になるとき、原因の大半はサーバーに日本語フォントが無いことです。slim系のDockerイメージには日本語フォントが入っていません。Debian系ならfonts-noto-cjkを入れ、fc-list :lang=jaで日本語フォントが1件以上出ることを確かめます。
文字が「ã‚」のように崩れる場合は別の原因です。HTMLの読み込み時の文字コードの取り違えなので、HTMLの先頭に<meta charset="utf-8">を置き、--encoding utf-8も付けます。フォントを入れても、誤って読み込んだ文字は直りません。
CSSのfont-familyには「Noto Sans CJK JP」のように実際に入れたフォント名を書きます。指定が無いと既定のフォントに落ち、サーバーごとに字形が変わります。
表の行の途中で改ページされる問題をCSSのpage-break指定で抑える
明細の多い請求書では、表の1行が上下のページに割れたり、2ページ目以降に見出し行が出なかったりします。印刷用CSSで次のように指定します。
@media print {
thead { display: table-header-group; } /* 各ページに見出し行を繰り返す */
tr, .keep { page-break-inside: avoid; } /* 行やブロックの途中で割らない */
.page-break { page-break-before: always; }
}
QtWebKitは2016年にQtから外れたエンジンです。CSS GridやPaged Mediaの@pageの余白ボックスなど、それ以降に普及した指定は前提にできません。レイアウトはtableとfloatで組み、行の高さが揃わない明細は1ページの行数をサーバー側で区切って出力する方法が確実です。
画面と印刷で縮尺が合わないときは、--disable-smart-shrinkingで自動縮小を止め、--zoomで倍率を固定します。
ヘッダー・フッターが出ない、ローカル画像が読めないときに見る設定
フッターが出ない場合は、まずwkhtmltopdf --versionで「with patched qt」の有無を見ます。無ければOS標準パッケージなので、公式配布版へ入れ替えます。
ロゴ画像や外部CSSが空になる場合は、ローカルファイルの読み込み制限が原因です。usageでは--disable-local-file-accessが既定で、他のローカルファイルを読むには--allow <path>でフォルダを指定するか、--enable-local-file-accessを付けます。後者はすべてのローカルファイルを開けるため、帳票用のアセットを置いたフォルダだけを--allowで許す形を勧めます。
信頼できないHTMLを渡さないための、CVE-2022-35583とSSRFの守り方
公式が警告するサーバー乗っ取りの危険とCVSS 9.8のSSRF
状況ページには「Do not use wkhtmltopdf with any untrusted HTML」と書かれ、信頼できないHTMLを処理するとサーバーを完全に乗っ取られうると警告しています。NVDのCVE-2022-35583は、0.12.6のSSRF(サーバー側リクエストフォージェリ)としてCVSS 3.1で9.8(Critical)と評価されています。iframeに内部のIPアドレスを埋めると、変換するサーバーから社内ネットワークへアクセスできるという内容です。
本体の更新は止まっているため、修正版は出ません。クラウド上で動かしていれば、メタデータの取得経由で認証情報が漏れる経路にもなります。仕組みと防御の全体像はSSRFの仕組みとクラウドメタデータ悪用の防御実装で解説しています。
利用者の入力を帳票に差し込むときのエスケープとネットワーク遮断
宛名や備考欄など利用者の入力を帳票に入れる場合、守りは次の順で重ねます。
- テンプレートエンジンの自動エスケープを有効にし、入力をHTMLとして解釈させない
--disable-javascriptを付け、テンプレートからscriptを除く- 変換プロセスをネットワークの無いコンテナで動かす(
docker run --network none) - 画像やCSSはローカルに置き、
--allowで許したフォルダだけを読ませる
3番目を満たせない構成なら、使い続ける判断はできません。状況ページもAppArmorやSELinuxでの強制アクセス制御を勧めています。
wkhtmltopdfを使い続ける条件と帳票の性質に応じた移行先の判断
WeasyPrint・Gotenberg・Playwrightを帳票の性質で選ぶ比較
状況ページは、自社で管理するHTMLの帳票にはWeasyPrintか商用のPrince、JavaScriptで動くサイトにはPuppeteerなどを勧めています。この推奨に、複数アプリから呼ぶ構成を加えて整理すると次のとおりです。
| 移行先 | 描画エンジン | 向く帳票 | 導入の形 |
|---|---|---|---|
| WeasyPrint 70.0系 | 独自(CSS組版) | 請求書・報告書など自社テンプレート | Pythonライブラリ |
| Gotenberg 8系 | Chromium | 複数システムから共通で出すPDF | Docker上のHTTP API |
| Playwright | Chromium | グラフなどJavaScript描画が要る画面 | Node.js・Pythonなど |
WeasyPrintは2026年10月時点で70.0が最新で、Python 3.10以上が必要です。GotenbergはChromium・LibreOffice入りのgotenberg/gotenberg:8と、Chromiumだけの8-chromiumを選べます。Playwrightのpage.pdf()は印刷用CSSで描画し、ヘッダーテンプレートにpageNumber・totalPagesのクラスでページ番号を入れられます。
使い続けてよいのは社内生成のHTMLを隔離環境で変換する場合だけ
判断を言い切ります。wkhtmltopdfを使い続けてよいのは、変換するHTMLが自社のテンプレートと自社DBの値だけで作られ、変換プロセスがネットワークから切り離されている場合に限ります。この条件で動いている社内帳票なら、OS更新やセキュリティ診断の時期を移行の期限にして、それまでは維持して構いません。
次の場面では採用しませんし、既存でも移行を急ぎます。利用者がアップロードしたHTMLやURLを変換する機能、外部サイトのURLを渡してPDF化する機能、Debian 13以降へOSを上げる予定のサーバーです。また、新規開発でwkhtmltopdfを選ぶ場面は無いと考えてください。
WeasyPrintとGotenbergへ置き換えるときのコードと見た目の差の確認
WeasyPrintへの置き換えは、公式のFirst Stepsに沿えば数行です。用紙と余白は、コマンドのオプションではなくCSSの@pageで指定します。
from weasyprint import HTML
# 用紙と余白はHTML側のCSSに書く:@page { size: A4; margin: 15mm 10mm; }
HTML(filename="invoice.html").write_pdf("invoice.pdf")
Gotenbergは、HTMLファイルをindex.htmlという名前で送る決まりがあります。
docker run --rm -p "3000:3000" gotenberg/gotenberg:8
curl --request POST http://localhost:3000/forms/chromium/convert/html \
--form files=@index.html \
--form paperWidth=8.27 --form paperHeight=11.69 \
-o invoice.pdf
A4は8.27×11.69インチです。エンジンが変わるため、wkhtmltopdfと同じPDFにはなりません。過去の帳票を10件ほど選び、新旧のPDFをページ数・改ページ位置・金額欄の折り返しの3点で並べて比べると、テンプレートの直し漏れを見つけやすくなります。Chromium系でNode.jsから組む場合は、Puppeteerのpage.pdfの設定とAWS Lambdaでの動かし方が参考になります。
帳票出力を業務システムに組み込み直すときの発注範囲と移行の進め方
移行の工数を大きく左右するのは、ライブラリの差し替えよりテンプレートの数です。帳票が数種類なら社内で直せます。数十種類あり、電子帳簿保存法に沿った保存や取引先への配信まで絡む場合は、出力・配信・保存をまとめて設計し直す時期と考えてください。進める順序は帳票電子化の進め方:出力・配信・保存の順序と電子帳簿保存法の要件で整理しています。
一創では、帳票テンプレートの移植から保存・検索の仕組みまでを文書管理システム開発として受託しています。請求書の発行そのものを見直す場合は、請求書発行システムの比較と選定軸も判断材料になります。
よくある質問
wkhtmltopdfの導入・保守・移行の場面で寄せられやすい質問をまとめました。
wkhtmltopdfは今でもダウンロードして使えますか?
使えます。公式サイトのダウンロードページから、Windows・macOS・主要なLinux向けの0.12.6系の配布物を入手できます。ただしGitHubのリポジトリは2023年1月にアーカイブされ、バグ報告や修正は受け付けられません。Debian 13の標準リポジトリにも入っていないため、新しいOSでは公式配布のdebを手で入れるか、別のツールへ移る判断が要ります。
Windowsでwkhtmltopdfを使うときの注意点は?
公式サイトにはVista以降向けのインストーラーと7z形式のアーカイブがあり、64bit版と32bit版が選べます。インストール先がPATHに入らない場合があるため、pdfkitなどから呼ぶときはconfiguration(wkhtmltopdf=...)で実行ファイルのフルパスを指定してください。導入後はwkhtmltopdf --versionで「with patched qt」の表示と版を確かめておくと、サーバーとの挙動差を切り分けやすくなります。
wkhtmltopdfで日本語が文字化けするのはなぜですか?
□や空白になるならフォント不足、意味の通らない記号になるなら文字コードの取り違えです。前者はfonts-noto-cjkなどの日本語フォントを入れてfc-list :lang=jaで確認してください。後者はHTMLに<meta charset="utf-8">を書き、--encoding utf-8を付けます。Dockerのslimイメージでは前者がよく起きます。
wkhtmltopdfの代わりになるツールはどれですか?
自社で管理するHTMLの帳票ならWeasyPrint、複数のシステムから共通で使うならDockerで動くGotenberg、JavaScriptで描画する画面ならPlaywrightやPuppeteerが候補です。公式の状況ページも、WeasyPrint・商用のPrince・Puppeteerを挙げています。どれもwkhtmltopdfと同じ見た目にはならないため、帳票ごとに新旧のPDFを並べて確認してください。
wkhtmltopdfに脆弱性はありますか?
脆弱性の登録があります。NVDはCVE-2022-35583として、0.12.6のSSRFをCVSS 9.8で登録したものです。公式の状況ページも、信頼できないHTMLを渡すとサーバーを乗っ取られうると警告しています。開発が止まっているため修正版は出ません。利用者の入力を含む帳票では、エスケープ・JavaScriptの無効化・ネットワークの遮断を重ね、満たせなければ移行してください。
関連記事
- PuppeteerでPDFを生成する方法|page.pdfの設定とAWS Lambda(@sparticuz/chromium)での動かし方:Chromium系へ移るときの実装手順です。
- Playwright(プレイライト)とは?仕組み・できること・Seleniumとの違いを解説:移行先の候補であるPlaywrightの全体像です。
- SSRFとは?仕組み・クラウドメタデータ悪用と防御実装を解説:CVE-2022-35583の背景にある攻撃の仕組みです。
- 帳票電子化の進め方:出力・配信・保存の順序と電子帳簿保存法の要件【2026年時点】:帳票出力の作り直しを業務全体で考える手順です。
- 金融機関の電子帳票システムとは:帳票の生成・配信・保存要件と移行判断【2026年時点】:帳票の生成から保存までの要件を移行判断の観点で整理しています。