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

2020/08/21

wkhtmltopdf で PDF に変換した際に canvas 内の日本語だけが文字化けする

event_note2020/08/21 0:39

wkhtmltopdf を使って HTML を PDF へ変換した際、日本語が文字化けしたり文字コードがそのまま表示されたりして、かなりはまったのでメモしておきます。

尚、先に言っておきますが、原因は不明です。
ただ、一応対策方法は分かったので、それについて書いています。

ちなみに、以下の記事にも書いたように以前にも wkhtmltopdf と canvas ではまりましたが、今回もめちゃくちゃはまりました。

上記記事に書いたように、前提として wkhtmltopdf は現時点で ES6 に対応していないので注意してください。

環境

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

現象と対策

fillText で文字を描画する際、日本語をそのまま指定すると あ のように文字コードがそのまま表示されてしまいました。

ちなみに 12354 の Unicode です。

いろいろ試行錯誤した結果、どうやら文字コードを直接指定してから文字に変換すると上手く描画できることが分かりました。

context.fillText(String.fromCharCode(12354), 0, 0);

意味不明ですが、一応これで上手くいくようなので、以下のようにして描画することにしました。

  • 文字列を文字に分割
  • 各文字の Unicode を取得
  • String.fromCharCode で Unicode を指定して文字を取得
  • 文字を結合して fillText で出力

なんか文字コードへ変換してまたそのまま文字へ戻しているだけのように思いますが、何故かこれで上手くいったのでこうしています。

サロゲートペアへの対応

JavaScript では文字は UTF-16 で扱われているようなので、上記のことをどんな文字でも対応できるようにするには、サロゲートペアも考慮しておく必要があります。

サロゲートペア自体についてはググればいくらでも見つかるので割愛します。

私は JavaScript のコードも Razor で出力しており、各文字の Unicode を取得するのは C# 側でやりました。
たまたま私の環境ではサーバー側の処理で事足り、C# を使ったほうが簡単だったからです。

サロゲートペアを考慮して Unicode から文字を取得するのは以下の記事を参考にさせてもらいました。