【grover】RailsでPDFの生成をする【2020年度版】


Rails で PDF を生成する際はどうされていますか?
少し調べると wicked_pdf や prawn などの gem が出てきます。

今回は grover という Puppeteer/Chromium を使って HTML から PDF や画像を生成する gem の存在を知り、試してみたのでメモを残します。

手順

puppeteer をインストール

npm install puppeteer

Gemfile に記述

gem 'grover'

config/initializers/grover.rb に以下を追加。

# frozen_string_literal: true

Grover.configure do |config|
  config.options = {
    format: 'A4',
    margin: {
      top: '5px',
      bottom: '10cm'
    },
    viewport: {
      width: 640,
      height: 480
    },
    prefer_css_page_size: true,
    emulate_media: 'screen',
    cache: false,
    timeout: 0, # Timeout in ms. A value of `0` means 'no timeout'
    launch_args: ['--font-render-hinting=medium', '--lang=ja'], # 日本語表示のため --lang=ja を追加
    wait_until: 'domcontentloaded'
  }
end

controllers/api/sample_controller.rb に以下を記述。
ルーティングの記述も忘れずに。

# frozen_string_literal: true

module Api
  class SampleController < ApplicationController
    include ActionController::MimeResponds # API モードで respond_to を使うために必要

    def show
      controller = ActionController::Base.new
      html = controller.render_to_string(template: 'api/hoges/show', layout: 'pdf')
      pdf = Grover.new(html).to_pdf
      respond_to do |format|
        format.html
        format.pdf do
          send_data(pdf, filename: 'your_filename.pdf', type: 'application/pdf')
        end
      end
    end

pdf 生成用の layout ファイルを作成

views/layouts/pdf.html.erb

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <style>
    </style>
  </head>
  <body>
    <%= yield %>
  </body>
</html>

api/sample/show.html.erb

<p>請求書</p>

<style>
p { font-size: 20px; }
</style>

結果

最後に

簡単に pdf を生成することができました。
処理時間も気にならないレベルです。