2017/06/10
Rails4でPDFを作成しようとした際に、結構ハマりましたので、備忘として残します。
構成
Ruby on Rails 4
Amazon Linux
PDFKit
wkhtmltopdf 12.4
手順
RailsでPDF作成をするにはいろいろな方法があると思いますが、今回はPDFKitとwkhtmltopdfを使います。
まず、wkhtmltopdfをインストールします。(https://wkhtmltopdf.org/)
$ sudo wget https://downloads.wkhtmltopdf.org/0.12/0.12.4/wkhtmltox-0.12.4_linux-generic-amd64.tar.xz
$ sudo tar -xvf wkhtmltox-0.12.4_linux-generic-amd64.tar.xz
$ sudo mv wkhtmltox /usr/local/lib/
$ sudo cd /usr/local/lib
$ sudo ln -s /usr/local/lib/wkhtmltox/bin/wkhtmltopdf /usr/local/bin/wkhtmltopdf
$ /usr/local/bin/wkhtmltopdf --version
$ wkhtmltopdf 0.12.4 (with patched qt)
動作確認をして、エラーが出ないことを確認します。
$ wkhtmltopdf http://google.com google.pdf
$ ls
google.pdf
日本語フォントが必要な場合は、IPAが提供しているIPAexフォントをダウンロードします。(http://ipafont.ipa.go.jp/)
$ cd /usr/share/fonts/
$ wget http://dl.ipafont.ipa.go.jp/IPAexfont/IPAexfont00301.zip
$ unzip IPAexfont00301.zip
Gemfileを編集して、bundleします。
gem 'pdfkit'
gem 'wkhtmltopdf'
Railsにpdfkit.rbを追加します。
私の環境では文字サイズの自動調整がlocalとAmazonLinuxでは異なったので、Linuxの方では「disable_smart_shrinking: true」にして、別途レイアウトを調整しています。(下記のmarginは適当です。)
config.wkhtmltopdf = `which wkhtmltopdf`.to_s.strip
if Rails.env.production?
config.default_options = {
encoding: "UTF-8",
page_size: "A4",
margin_top: "0.0in",
margin_right: "0.0in",
margin_bottom: "0.0in",
margin_left: "0.0in",
disable_smart_shrinking: true
}
else
config.default_options = {
encoding: "UTF-8"
}
end
PDFを作る際、Controllerでは次のようなコードを書きます。
PDFKitではscssを読み込めないので、production環境では直接ファイルを見に行っています。production以外の環境ではviewからファイルを見ています。(個人的にはこの辺のハマりがクライマックスでした。)
respond_to do |format|
format.html do
# 省略
end
format.pdf do
html = render_to_string template: "hogehoge"
pdf = PDFKit.new(html, encoding: "UTF-8", :footer_center => "[page]", :footer_font_size => 7)
# productionではprecompileされたファイルを読みにいく
if Rails.env.production?
css_path = ActionController::Base.helpers.asset_path "xxxx.css"
pdf.stylesheets << "#{Rails.root}/public#{css_path}"
end
#
send_data pdf.to_pdf,
filename: "title",
type: "application/pdf",
disposition: "inline"
end
end
<head>
<style>
<%= Rails.application.assets["hoge.css"].to_s %>
</style>
</head>
以上です。
追記 20200405
3年ぶりぐらいに同様のコードを書いてみると、development環境でも普通にprecompileすればいいと気づきました。
なんというか、不要な苦労をしていました。