To install and use wicked_pdf
try articles like below.


Here when using wicked pdf internally it uses wkhtmltopdf binary to convert HTML to PDF. When one process uses this binary others have to wait until the operation is done. When creating multiple PDF files concurrently in rails background jobs we seen it take lot of time to generate PDF.
So the idea is to move this part alone to some server-less solutions. We are using Google cloud function

Create a folder pdf-generator and then add Gemfile
mkdir pdf-generation
cd pdf-generation
touch Gemfile
touch app.rb
# download wkhtmltopdf linux binary and put it inside this folder
source "https://rubygems.org"
# Include the Ruby Functions Framework as a dependency.
gem "functions_framework", "~> 0.5"
gem 'wicked_pdf'
gem 'pry'
Gemfile
require "functions_framework"
require "wicked_pdf"
require 'json'
require 'pry'
wk_path = if RbConfig::CONFIG['host_os'].match? /linux/
'./wkhtmltopdf_ubuntu'
else
'./wkhtmltopdf_mac'
end
WickedPdf.config = {
exe_path: wk_path,
enable_local_file_access: true
}
FunctionsFramework.http "create" do |request|
json = JSON.parse(request.body.read) rescue {}
margin_top, margin_bottom = if json['margins']
json['margins']
elsif json['header_html']
[60, 10]
else
[0, 0]
end
header = json['header_html'] ? { content: json['header_html'] } : {}
WickedPdf.new.pdf_from_string(
json['body_html'],
margin: { top: margin_top, bottom: margin_bottom },
header: header,
encoding: 'utf8',
orientation: (json['orientation'] || 'Portrait')
)
end
app.rb
run this command bundle exec functions-framework-ruby --target create
Inside rails app run this code
export PDF_GEN_URL=http://localhost:8080
Write this code in your application
class GeneratePdf
include HTTParty
def self.do(body_html, header_html = nil, margins = [], **options)
body = { body_html: body_html }
body.merge!(margins: margins) if margins.present?
body.merge!(header_html: header_html) if header_html.present?
body.merge!(**options)
return "" if Rails.env.test?
post("#{ENV['PDF_GEN_URL']}", body: body.to_json).response.body
end
end
app/services/generate_pdf.rb
bundle exec rails c
File.open("#{Rails.root}/tmp/new.pdf", 'wb') {|f| f.write(GeneratePdf.do('<p style="color: red">Hello</p>')) }
Then you host it to google cloud functions and change the url in production. Since it is autoscaled we generated upto 1,00 PDF concurrently. We generate around 200K PDF files per month which cost around less than $2 including discounts.
Notes:
It's 2024 wkhtmltopdf has been deprecated and there is also a discussion in wicked_pdf gem about this. Use it if you don't have any other choice.
Thanks for the above article authors and Thanks for reading!