こんにちは、CTOの小林です。
kickflowにはExcel形式(.xlsx)で帳票出力する機能がありますが、これをPDF形式での出力に対応したいと思い調査しました。 kickflowではインフラにHerokuを使用しているため、HerokuでExcelをPDFに変換する方法を紹介します。
HerokuにLibreOfficeをインストールする
ExcelファイルをPDFに変換する方法として、LibreOfficeをサーバーにインストールしてヘッドレスモードで変換する方法がメジャーなようです。 まずはHerokuにLibreOfficeをインストールします。
こちらのビルドパックを追加することで、Herokuにlibreofficeをインストールすることができます。 elements.heroku.com
ビルドパックの手順書通り、heroku-buildpack-aptも追加し、Aptfileをリポジトリのルートに追加します。手順書にあるフォントの追加は次のセクションで詳しく説明するので、ここではスキップしてください。 elements.heroku.com
Aptfileはこちら。
libsm6 libice6 libxinerama1 libdbus-glib-1-2 libharfbuzz0b libharfbuzz-icu0 libx11-xcb1 libxcb1
ちなみに、「どうせaptのビルドパックを追加するならapt経由でlibreofficeをインストールしてもいいのでは?」と思いましたが、 apt経由の方法だとslugのサイズが上限の500MBを超えてしまいビルドできませんでした。
この状態で、LibreOfficeを使ったPDF変換ができるようになりました。 Rubyだとlibreconvを使うのがメジャーなので、libreconvを追加後、下記のようなコードで簡単にPDFに変換することができます。
require 'libreconv' Libreconv.convert('test.elsx', 'test.pdf')
日本語フォントをインストールする
ここまでで一応ExcelファイルをPDFに変換はできるのですが、Herokuのdynoに日本語フォントがインストールされていないため、変換後のPDFでは日本語が消えてしまいます。
というわけで、サーバーに日本語フォントをインストールしましょう。こうした用途の日本語フォントとしてはIPAフォントやNotoフォントがよく使われているようなので、今回はIPAフォントを使用します。 IPAフォントは最新のIPAexフォントを使用します。以下のリンクからダウンロードできます。
Herokuではfontconfigによりサーバー全体のフォントを管理しています。 fontconfigは ~/.fonts に設置したフォントを認識してくれるため、リポジトリのルートに.fontsフォルダを作成し、その中に必要なフォントファイル(.ttfなど)を置くことでHerokuに新しいフォントを認識させることができます。 他にもビルドパックを使ってインストールする方法もありますが、結局ビルドパックも中では.fontsディレクトリを作成しフォントをコピーしているだけで最終形は同じとなるので、今回はリポジトリに直接追加しました。 ちなみに、aptでIPAフォントのパッケージをインストールする方法も試してみましたが、こちらはうまく認識されませんでした。
リポジトリのルートに .fonts を作成後、IPAからダウンロードした以下の2ファイルを.fontsにコピーします。
- ipaexg.ttf
- IPAexゴシック用のフォントファイル
- ipaexm.ttf
- IPAex明朝用のフォントファイル
この状態でデプロイ後、日本語フォントを含むExcelファイルをPDFに変換すると、以下の様になりました。
- Excel内で直接IPAexゴシックやIPAex明朝を使っていれば、そのまま出力される
- それ以外の日本語フォントを使っていれば、IPAexゴシックで出力される
ちなみに、dynoに入ってfc-listコマンドで確認すると、ちゃんとIPAexフォントが認識されています。
~ $ fc-list | grep IPA /app/.fonts/ipaexg.ttf: IPAexGothic,IPAexゴシック:style=Regular /app/.fonts/ipaexm.ttf: IPAexMincho,IPAex明朝:style=Regular
IPAex明朝以外の明朝体をIPAex明朝に変換する
ここまででも十分と言えば十分なのですが、明朝体のフォント(MS明朝やMS P明朝など)を使用している場合はIPAex明朝で出力されるように設定してみます。 fontconfigのユーザー設定ファイルを作成することで設定可能です。 fontconfigのユーザー設定ファイルは、$HOME/.config/fontconfig/fonts.conf や $HOME/.config/fontconfig/conf.d となります。 今回はリポジトリのルートに .config/fontconfig/fonts.conf ファイルを作成し、以下の内容で保存します。
<?xml version="1.0"?> <!DOCTYPE fontconfig SYSTEM "fonts.dtd"> <fontconfig> <alias> <family>MS 明朝</family> <prefer> <family>IPAex明朝</family> </prefer> </alias> <alias> <family>MS 明朝</family> <prefer> <family>IPAex明朝</family> </prefer> </alias> <alias> <family>MS Mincho</family> <prefer> <family>IPAex明朝</family> </prefer> </alias> <alias> <family>MS P明朝</family> <prefer> <family>IPAex明朝</family> </prefer> </alias> <alias> <family>MS P明朝</family> <prefer> <family>IPAex明朝</family> </prefer> </alias> <alias> <family>MS PMincho</family> <prefer> <family>IPAex明朝</family> </prefer> </alias> <alias> <family>IPAMincho</family> <prefer> <family>IPAex明朝</family> </prefer> </alias> <alias> <family>IPA明朝</family> <prefer> <family>IPAex明朝</family> </prefer> </alias> <alias> <family>IPA P明朝</family> <prefer> <family>IPAex明朝</family> </prefer> </alias> <alias> <family>Yu Mincho Regular</family> <prefer> <family>IPAex明朝</family> </prefer> </alias> <alias> <family>游明朝 Regular</family> <prefer> <family>IPAex明朝</family> </prefer> </alias> </fontconfig>
このファイルでは、MS明朝、MS P明朝、IPA明朝、IPA P明朝、游明朝 Regularに対して「代わりにIPAex明朝を使うよ」というエイリアスを設定しています。 総称型のserifに対してエイリアスを貼る方法も試してみましたが、最初から fontconfig に登録されているMS明朝にしか効かなかったので結局各フォントを指定することにしました。
念の為、fc-matchコマンドでエイリアスが正しく設定できているか確認します。
~ $ fc-match "MS Gothic":lang=ja ipaexg.ttf: "IPAexGothic" "Regular" ~ $ fc-match "MS Mincho":lang=ja ipaexm.ttf: "IPAexMincho" "Regular" ~ $ fc-match "MS PMincho":lang=ja ipaexm.ttf: "IPAexMincho" "Regular"
MSゴシックはIPAexゴシック、MS明朝とMS P明朝はIPAex明朝が返ってくるようになりました。
これで、明朝体のフォントはIPAex明朝、それ以外はIPAexゴシックを使って、LibreOfficeでPDFが出力されるようになりました。
最終結果
最後に、変換結果をご紹介します。各種フォントを含むExcelファイルを変換したPDFはこのようになりました。元のフォントに応じて、IPAexゴシックまたはIPAex明朝が使用されています。
まとめ
Heroku上でLibreOfficeを使ってExcelをPDFに変換する方法をご紹介しました。 LibreOfficeによる変換よりも、日本語フォントのインストールの設定がややこしかったので、この記事も半分以上はフォントの解説になってしまいました。 この記事がExcelをPDFに変換しようとしている誰かの参考になれば幸いです。