Yak shaving logs


My life is just yak shaving.

[Rails5] wicked_pdfを使用してHTMLをPDFに変換する(開発環境編)

2018/05/24 #rails #gem #wicked_pdf

HTMLをPDFに変換する必要があったので実装しました。
環境は以下の通りです。
テンプレートエンジンはhamlを使っています。

Rails 5.2.0.beta2
ruby 2.4.2p198 (2017-09-14 revision 59899) [x86_64-darwin16]

最終的にはこんな感じでPDF出力ボタンからPDFが閲覧できるのがゴールです。

https://gyazo.com/f614aaf2c4a4ca1107602644537bbf9e

Gem選定

pdfで定番のgemを探してみたのですが、以下の表が一番参考になりました。

https://gyazo.com/be4a5ab6042ce0d1d7c462767c28704e
引用:http://ruby-rails.hatenadiary.com/entry/20140906/1409995011

上記の記事が古いこともあり、2018/05/21 12:00 時点のスター数も確認してみました。


Todo: テーブルのレイアウトが見にくいので修正する

名称 スター数 備考
prawn 3,590
wicked_pdf 2,611
pdfkit 2,505
thinreports - おそらくリポジトリ細分化されており、複数のリポジトリが存在する。その影響かスター数が少ない。

今回は複雑な要件はなく、HTMLをPDFにするだけです。
ユーザー画面でPDFをGUIで作成する必要がないので、thinreportsは候補から外れ、スター数の多いprawnを第一候補として検討しつつ、そこまで柔軟性は不要なのでwicked_pdfを採用しました。。

READMEなども読み比べて比較検討する時間もないので、wicked_pdfで実装しつつ、微妙であれば他を検討する方針でいきます。

wicked_pdfでHTMLからPDFに変換する

gemを入れて rails generate wicked_pdf したりすることろは基本的にREADMEそのままです。
wicked_pdfは、HTMLをPDFに変換するオープンソースのwkhtmltopdfのラッパーなので、wkhtmltopdfとそのgemのwkhtmltopdf-binaryもインストールする必要があります。

+# PDF                                                                                               
+gem 'wicked_pdf'
+gem 'wkhtmltopdf-binary'

bundle install --path vendor/bundle が終わったらMINEタイプを設定しましょう。
MINEタイプは忘れるとだいぶハマるので忘れずに追加しましょう。

# config/initializers/mime_types.rb
Mime::Type.register 'application/pdf', :pdf

次にwkhtmltopdfをインストールします。
MacOSでbrewをお使いであれば $ brew cask install wkhtmltopdf でwkhtmltopdfはインストールできます。
その他のOSはこちらを参考にしてください。
https://wkhtmltopdf.org/downloads.html

インストールしたwkhtmltopdfのpathを指定します。

# config/initializers/wicked_pdf.rb
WickedPdf.config = {
  # Path to the wkhtmltopdf executable: This usually isn't needed if using
  # one of the wkhtmltopdf-binary family of gems.
  # exe_path: '/usr/local/bin/wkhtmltopdf',
  #   or
+  exe_path: Gem.bin_path('wkhtmltopdf-binary', 'wkhtmltopdf')
  # Layout file to be used for all PDFs
  # (but can be overridden in `render :pdf` calls)
  # layout: 'pdf.html',
}

config/initializer/*rails server 起動時しか読み込まれないので、ここでサーバーを先どうしておきましょう。

次はコントローラーに処理を追加します。
layoutもtemplateもファイルの拡張子まで指定しないと、
テンプレートがないというエラーになります。

+    respond_to do |format|
+      format.html
+      format.pdf do
+        render pdf: "#{@project.code}_詳細情報",
+          layout:   'layouts/pdf.html.haml',
+          template: 'hoge/fuga/pdf.html.haml'
+      end
+    end

コントローラーから呼び出すViewを追加します。
今回はpdfの内容を少し変えたいので、pdf用のファイルを用意しました。

app/views/hoge/fuga/pdf.html.haml にはpdfにしたい内容を記載します。

# app/views/layouts/pdf.html.haml
+!!!
+%html
+  %head
+    %meta{ content: "text/html; charset=UTF-8", "http-equiv": "Content-Type" }
+    %meta{ charset: 'utf-8' }
+    = wicked_pdf_stylesheet_link_tag 'application'
+  %body
+    = yield

注意点としては、 wicked_pdf_stylesheet_link_tagwicked_pdf_javascript_include_tag などのヘルパーが用意されているのでそれを使います。

ここまでできたらpdfを表示してみましょう。
URLに .pdf をつけるとPDFを表示されるはずです。

表示が確認できたら「PDFを出力」ボタンをつけて完成です。
ポイントは format: :pdf です。

+ = link_to 'PDF出力', hoge_path(@fuga, format: :pdf), class: %i[btn btn-default], target: '_blank'

HTMLとアセットの内容によってはPDF変換に時間がかかってしまうため、サービスによってはそのあたりがネックになってしまうと思います。
その場合は、先にPDFを作成しておく、ローディングマークを表示するなどの対応が必要そうです。

以上!

参考

https://github.com/mileszs/wicked_pdf
https://wkhtmltopdf.org/downloads.html
https://qiita.com/s-mori/items/00aef46e6a10499f8254
https://medium.com/@yazed.jamal/using-wicked-pdf-with-rails-5-3d1a4b0a09ba
https://stackoverflow.com/questions/25502322/rails-4-how-to-make-a-link-to-a-pdf-file-name-pdf

このエントリーをはてなブックマークに追加

categories


最新記事


tags