[Grover] Generate PDF with Rails [2020 version]

What do you do when you generate a PDF in Rails? A little research reveals gems such as wicked_pdf and prawn.

This time, I found out about the existence of a gem that generates PDFs and images from HTML using Puppeteer / Chromium called grover and tried it, so I will leave a note.

procedure

Install puppeteer

npm install puppeteer

Described in Gemfile

gem 'grover'

Add the following to 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'], #For Japanese display--lang=add ja
    wait_until: 'domcontentloaded'
  }
end

Describe the following in controllers / api / sample_controller.rb. Don't forget to describe the routing.

# frozen_string_literal: true

module Api
  class SampleController < ApplicationController
    include ActionController::MimeResponds #Respond in API mode_Required to use 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

Create layout file for pdf generation

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>Invoice</p>

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

result

スクリーンショット 2020-05-30 11.48.01.png

Finally

I was able to easily generate a pdf. The processing time is also a level that does not matter. If you include puppeteer, you don't need to set fonts, so it looks good.

Recommended Posts

[Grover] Generate PDF with Rails [2020 version]
Rails deploy with Docker
[Rails 6] RuntimeError with $ rails s
How to manually generate a JWT with Rails Knock
Rails version upgrade memorandum 5.0 → 5.1
Handle devise with Rails
[Rails] Learning with Rails tutorial
[Rails] Test with RSpec
[Rails version control] rails version downgrade
[Rails] Development with MySQL
Supports multilingualization with Rails!
Generate JavaScript with Thymeleaf
Double polymorphic with Rails
[Rails] Create an email sending function with ActionMailer (complete version)
Generate barcode with Spring Boot
Ruby version switching with rbenv
[Rails] Upload videos with Rails (ActiveStorage)
Try using view_component with rails
[Vue Rails] "Hello Vue!" Displayed with Vue + Rails
Japaneseize using i18n with Rails
Version control Java with SDKMAN
API creation with Rails + GraphQL
Programmably generate Logger with logback
Paging PDF with Java + PDFBox.jar
Run Rails whenever with docker
Java version control with jenv
[Docker] Rails 5.2 environment construction with docker
Use multiple databases with Rails 6.0
[Rails] Specify format with link_to
[Rails] Rails version upgrade error memorandum
Version control CocoaPods with Docker
Login function implementation with rails
[Docker] Use whenever with Docker + Rails
Can't output PDF in production environment (EC2, Amazon Linux) with Rails
How to build Rails + Vue + MySQL environment with Docker [2020/09 latest version]