プログラムを中心とした個人的なメモ用のブログです。 タイトルは迷走中。
内容の保証はできませんのであしからずご了承ください。

2020/08/19

wkhtmltopdf で canvas に何も描画されない

update2020/08/23 event_note2020/08/18 23:41

wkhtmltopdf を使って HTML を PDF へ変換していたのですが、canvas に JavaScript で描画しているはずの内容が全く表示されず、かなりはまったのでメモしておきます。

環境

実際には ASP.NET Core で Rotativa.AspNetCore を使っており、その中で HTML から PDF への変換に wkhtmltopdf が使われています。

原因

結論から先に書くと、現時点で wkhtmltopdf は ES6 に対応していないため、ES6 で追加されたコードを書くと正しく実行されないようです。

具体的には、私の場合、以下のようなコードを書いていたことが原因でした、

  • 変数宣言で let を使っていた
  • codePointAt で文字コードを取得していた

対策

let ならば var に置き換えるとかで簡単に対応可能ですが、中には対応が難しいものもあるかと思います。

一応対策として、babel を使って ES5 以前のコードにコンパイルするという手があります。

babel のインストール方法や使い方はググればいくらでも見つかるので割愛します。

ただ、私は JavaScript のコードも Razor で出力していたため、事前コンパイルせず(できず)、以下のようにブラウザ(この場合は wkhtmltopdf) 内でコンパイルせざるを得ませんでした。

<script type="text/babel">

  // do something

</script>

そして、これだと処理速度が異常に遅くて使い物にならなかったので、結局 ES6 のコードを使わないように書き直して対応しました。

原因が分かるまでの経緯

「wkhtmltopdf canvas」などでググってみると、ChartJS が描画されないといった内容が多くヒットしますが、canvas を使っているのは同じはずなので、まずはそれを参考にいろいろ試してみました。

具体的には以下です。

  • canvasdiv で括ってサイズを同じにする
  • --no-stop-slow-scripts --javascript-delay 1000 を指定する(時間は適宜変更)

これらについては参考 URL やググってみるといろいろヒットするので、割愛します。

しかし、これらのことをやっても状況は変わらず、それ以上の情報はいくらググっても見つかりませんでした。
ただ、canvas 内の表示だけがおかしいので、JavaScript に問題があるのではないかということは推測できました。

デバッグが非常にやりづらく、仕方ないので少しずつ JavaScript コードを埋め込んで動作確認していたら、どうも途中から JavaScript のコードが実行されていないような感じでした。

そこでふと let を見て、比較的最近追加された仕様だったなぁと思い、var に変更したところ上手く描画されるようになりました。

いや、これ本当にはまった。

尚、wkhtmltopdf を現時点で最新の 0.12.6 に変更しても同様でした。

また、上述した

  • canvasdiv で括ってサイズを同じにする
  • --no-stop-slow-scripts --javascript-delay 1000 を指定する(時間は適宜変更)

ですが、私の環境では前者が不要でしたが、後者は必要でした。