Help us understand the problem. What is going on with this article?

Railsでwicked_pdfを使って画像入りのPDFを生成する

More than 1 year has passed since last update.

Gemのwicked_pdfを使ってPDF出力機能を作った際に、いくつか気をつけなければならない箇所がありましたので、まとめておきます。
wicked_pdf

利用方法

この辺りの記事が参考になります。
Railsでwickedpdfを用いてPDF出力する方法
Rails で Wicked PDF 使って PDF を出力してみた ( 日本語もバッチリ )

wicked_pdfは、内部でwkhtmltopdfを使用します。準備として必要なことは以下のみですが、これではAmazon S3の画像を表示できませんでした。詳細は後述します。
※2016年7月に、wkhtmltopdf-binaryのバージョンが0.12.3に更新され、この問題は解決したと思われます。

Gemfile
gem 'wicked_pdf'
gem 'wkhtmltopdf-binary'
config/initializers/wicked_pdf.rb
WickedPdf.config = {
  exe_path: "#{Gem.loaded_specs['wkhtmltopdf-binary'].full_gem_path}/bin/wkhtmltopdf"
}

コントローラで以下の例のようにレンダリングすると、HTMLをPDFに変換して出力してくれます。

app/controllers/my_model_controller.rb
def pdf
  respond_to do |format|
    format.html { redirect_to action: :pdf, format: :pdf, debug: true) }
    format.pdf do
      render pdf: "title-#{Time.now.to_date.to_s}",
             encoding: 'UTF-8',
             template: 'pdf/pdf.html.erb',
             layout: 'pdf.html',
             orientation: 'Landscape',
             page_size:   'A4',
             show_as_html: params[:debug].present?
    end
  end
end

タグの利用方法

多くの記事の中で、wicked_pdfではRailsでよく使うタグをそのまま使用できず、js、css、imageを出力する場合は以下のタグで置き換えるように説明されています。

# js
<%= wicked_pdf_javascript_include_tag "filename" %>
# css
<%= wicked_pdf_stylesheet_link_tag "filename" %>
# image
<%= wicked_pdf_image_tag 'filename' %>

これらのタグは、あくまでRailsから見ると外部プロセスであるwkhtmltopdfに対して、Rails内部の相対パスを絶対パスに変換して渡しているに過ぎません。つまり、ファイル名を相対パスで渡している箇所には、wicked_pdf_*のタグを使う必要がありますが、そうでない場所は通常のimage_tagなどを使えばよいことになります。例えば、URLを指定している箇所などが当てはまります。

# 正
<%= wicked_pdf_image_tag('my_images/original.jpg') %>
<%= image_tag('https://s3-ap-northeast-1.amazonaws.com/my-bucket/photos/my_models/1/original.jpg') %>
<%= image_tag(@my_model.image.url) %>

# 誤
<%= image_tag('my_images/original.jpg') %>
<%= wicked_pdf_image_tag('https://s3-ap-northeast-1.amazonaws.com/my-bucket/photos/my_models/1/original.jpg') %>
<%= wicked_pdf_image_tag(@my_model.image.url) %>

また、wicked_pdf_image_tagがうまく動かないことに関する記事には、これとは別問題に関するものも散見されます。
wicked_pdf_image_tag given undefined pathname for image
これは、Rails内で画像を置くディレクトリに、app/assets/images以下とpublic以下の二種類があることによります。public以下の画像を指定する場合、Rails内部でのファイルパスは/から始めます。これをwicked_pdf_image_tagに直接渡しても絶対パスへの変換がうまくいかないので、wicked_pdf_image_tagの定義をオーバーライドして書き換えましょうというお話です。
つまり、まとめると、以下のようになります。

  • app/assets/images以下に配置した画像には、wicked_pdf_image_tagをそのまま使う
  • public以下に配置した画像には、wicked_pdf_image_tagを書き換えて使う
  • URLで指定する画像には、通常のimage_tagを使う

Amazon S3 上の画像を取得する際の注意

※2016年7月に、wkhtmltopdf-binaryのバージョンが0.12.3に更新され、この問題は解決したと思われます。
https://rubygems.org/gems/wkhtmltopdf-binary
以前のwkhtmltopdf-binaryでは、このGemによって使用されるwkhtmltopdfが最新ではなく、そのバージョンでAmazon S3上の画像を表示することができませんでした。
wicked pdf not displaying amazon s3 images
対応については、以下の記事がとても参考になりました。
【Rails】wicked_pdf導入にあたってつまづいたところメモ
結論としては、Gemを以下に置き換えればRailsに閉じた形で解決できます。

Gemfile
gem 'wicked_pdf'
gem 'wkhtmltopdf-binary-aml', git: 'https://github.com/insphire/wkhtmltopdf-binary-aml'
config/initializers/wicked_pdf.rb
WickedPdf.config = {
  exe_path: "#{Gem.loaded_specs['wkhtmltopdf-binary-aml'].full_gem_path}/bin/wkhtmltopdf"
}

改ページの方法

以下のようにpagebreakを定義すれば、PDF内で改ページすることが出来ます。

app/stylesheets/application.css
p.pagebreak {page-break-before: always; }
...
<p class='pagebreak'/>
...
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした