Converting HTML to PDF is a common requirement in web applications, whether for generating invoices, reports, or downloadable content. Today, I’ll show you how to implement PDF generation in your Rails 7 application using the WickedPDF gem.
What is WickedPDF?
WickedPDF is a Ruby gem that uses wkhtmltopdf under the hood to convert HTML to PDF. It’s particularly useful because it allows you to use your existing Rails views as templates for PDFs.
Installation
First, add WickedPDF and its Ruby interface to your Gemfile:
# Gemfile
gem 'wicked_pdf'
gem 'wkhtmltopdf-binary' # Provides the binary for development
Run bundle install:
bundle install
Generate the initializer:
rails generate wicked_pdf
This creates config/initializers/wicked_pdf.rb
with default configurations:
WickedPdf.config = {
# Path to the wkhtmltopdf executable: This usually isn't necessary, as the gem
# includes the binary, but you can override it if needed
# :exe_path => '/usr/local/bin/wkhtmltopdf',
}
Basic Usage
Let’s create a simple example that generates a PDF from a user’s profile.
Controller Setup
class UsersController < ApplicationController
def show
@user = User.find(params[:id])
respond_to do |format|
format.html
format.pdf do
render pdf: "user_profile", # Filename
template: "users/show", # Template to render
layout: "pdf", # Layout file to use
disposition: "inline" # Open in browser instead of download
end
end
end
end
Create a PDF Layout
Create app/views/layouts/pdf.html.erb
:
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8' />
<%= wicked_pdf_stylesheet_link_tag "application" %>
</head>
<body>
<div class='container'>
<%= yield %>
</div>
</body>
</html>
Create Your View Template
Create app/views/users/show.pdf.erb
:
<div class="user-profile">
<h1><%= @user.name %></h1>
<div class="profile-details">
<p>Email: <%= @user.email %></p>
<p>Member since: <%= @user.created_at.strftime("%B %d, %Y") %></p>
</div>
</div>
Adding Styles
WickedPDF can handle your regular CSS, but you might need to make some adjustments for PDF-specific styling. Create app/assets/stylesheets/pdf.scss
:
.user-profile {
font-family: Arial, sans-serif;
h1 {
color: #333;
border-bottom: 1px solid #ccc;
}
.profile-details {
margin-top: 20px;
p {
margin: 10px 0;
}
}
}
Advanced Features
Headers and Footers
You can add headers and footers to your PDFs:
render pdf: "user_profile",
template: "users/show",
layout: "pdf",
header: {
html: {
template: 'shared/pdf_header'
}
},
footer: {
html: {
template: 'shared/pdf_footer'
}
}
Page Numbers
Create app/views/shared/pdf_footer.html.erb
:
<div style="text-align: center; font-size: 12px;">
Page <span class="page"></span> of <span class="topage"></span>
</div>
Configuration Options
WickedPDF offers a wide array of configurable options to enhance your experience. Here are some useful ones:
render pdf: "user_profile",
page_size: 'A4',
orientation: 'Landscape',
lowquality: true,
zoom: 1,
dpi: 75
Troubleshooting Tips
- Missing Images: Make sure to use absolute paths for images:
wicked_pdf_image_tag 'logo.png'
- Styling Issues: If styles aren’t applying, check that you’re using
wicked_pdf_stylesheet_link_tag
instead ofstylesheet_link_tag
- Performance: For large PDFs, consider using background jobs with Active Job
Production Considerations
In production, you might want to use the system’s wkhtmltopdf instead of the bundled binary. Install it on your server:
# Ubuntu/Debian
sudo apt-get install wkhtmltopdf
# CentOS/RHEL
sudo yum install wkhtmltopdf
Then update your initializer:
WickedPdf.config = {
exe_path: '/usr/local/bin/wkhtmltopdf'
}
Conclusion
WickedPDF is a powerful tool for generating PDFs in Rails applications. It’s useful because it lets you use your existing templates and CSS, helping maintain consistency between your web pages and PDFs.
Keep performance in mind when creating large PDFs, and consider using a background job for generation if necessary.
Have you implemented WickedPDF in your Rails applications? What has been your experience? Let me know in the comments below!
0 Comments