pdf libraries

pdf libraries

Ruby on rails

Ruby on rails

How to Generate PDF from HTML Using PDFKit with Ruby on Rails

Marcelo Abreu, founder of pdforge

Marcelo | Founder

Marcelo | Founder

Oct 30, 2024

Oct 30, 2024

Introduction to PDF Generation in Ruby on Rails with PDFKit

PDFKit is a powerful Ruby library for converting HTML views into PDFs within Rails applications, ideal for SaaS platforms that need scalable, automated document generation. Compared to other libraries like Prawn, HexaPDF, WickedPDF, and Grover, PDFKit provides a straightforward solution for turning web views into polished PDF reports.

You can check their full documentation here.

Comparison Between PDFKit and Other Ruby PDF Libraries

Number of downloads from bestgems of pdfkit

Ruby offers a range of PDF generation libraries, each with unique features:

HexaPDF is great for complex PDF editing but is not designed for HTML-based conversion.

WickedPDF uses wkhtmltopdf for HTML conversion but may lack advanced customization.

Prawn offers extensive control over PDF elements, suited for custom layouts but less intuitive for HTML.

Grover and Puppeteer-ruby leverage headless Chrome for precise HTML rendering, though they require more configuration.

For those focused on converting HTML templates, PDFKit provides an efficient balance between simplicity and functionality.

Guide to generate pdf from html using Ruby on rails pdfkit
Guide to generate pdf from html using Ruby on rails pdfkit

Setting Up PDFKit in a Ruby on Rails Project

To integrate PDFKit into Rails, start by adding it to your Gemfile and configuring it for PDF rendering.

Installing and Configuring PDFKit for Rails

Add PDFKit to your project by including it in the Gemfile:

gem 'pdfkit'

Run bundle install and set up middleware in config/application.rb:

config.middleware.use PDFKit::Middleware, print_media_type: true

For PDFKit to function, you’ll also need the wkhtmltopdf binary. Install it with:

sudo apt install wkhtmltopdf  # Linux
brew install wkhtmltopdf       # macOS

This configuration allows PDFKit to convert HTML views to PDFs using simple routing.

Integrating PDFKit with Rails Controllers

To generate a PDF from a specific action, configure the controller to render HTML and convert it:

class InvoicesController < ApplicationController
  def show
    @invoice = Invoice.find(params[:id])

    respond_to do |format|
      format.html  # renders the HTML view by default
      format.pdf do
        render pdf: "invoice_#{@invoice.id}",       # sets the PDF filename
               template: "invoices/show.html.erb",   # specifies the HTML template
               layout: "pdf",                        # optional, specify a PDF-specific layout
               page_size: 'A4',                      # optional, sets the page size
               show_as_html: params.key?('debug')    # helpful for debugging HTML before PDF conversion
      end
    end
  end
end

Now, accessing /invoices/1.pdf will render a PDF of the HTML view in app/views/invoices/show.html.erb.

PDFKit Main Features

PDFKit offers various essential features:

  • CSS Styling: Full control over document layout and design.

  • Javascript Execution: Support for dynamic elements.

  • Headers and Footers: Customizable headers and footers for branding.

These capabilities make PDFKit a flexible choice for Rails applications that require dynamic, styled PDFs.

Generating PDF from HTML Using PDFKit

With PDFKit set up, the next step is to design an HTML template for a high-quality PDF document.

Designing HTML Templates for High-Quality PDFs

Carefully structured HTML templates ensure your PDFs are well-formatted. Here’s an example of a basic invoice template in ERB, located in app/views/invoices/show.html.erb:

<!DOCTYPE html>
<html>
<head>
  <style>
    body { font-family: Arial, sans-serif; }
    .invoice { margin: auto; width: 70%; padding: 20px; }
    .header, .footer { text-align: center; font-size: 12px; }
    .content { padding: 20px; }
    .table { width: 100%; border-collapse: collapse; }
    .table, .table th, .table td { border: 1px solid black; padding: 8px; }
  </style>
</head>
<body>
  <div class="invoice">
    <div class="header"><h2>Invoice</h2></div>
    <div class="content">
      <p><strong>Invoice #: </strong><%= @invoice.id %></p>
      <p><strong>Date: </strong><%= @invoice.date %></p>
      <table class="table">
        <thead><tr><th>Description</th><th>Amount</th></tr></thead>
        <tbody>
          <% @invoice.items.each do |item| %>
            <tr><td><%= item.description %></td><td><%= item.amount %></td></tr>
          <% end %>
        </tbody>
      </table>
    </div>
    <div class="footer">Thank you for your business!</div>

This layout includes a consistent header, footer, and itemized table to ensure a professional look and feel.

Converting HTML to PDF with PDFKit and Rails

To generate a PDF, visit the show action endpoint with .pdf appended to the URL. For example, /invoices/1.pdf will render the invoice with ID 1 as a PDF, based on the HTML defined in app/views/invoices/show.html.erb.

This setup allows you to quickly convert HTML views to PDF by simply accessing the .pdf format.

How to Use a PDF API to Automate PDF Creation at Scale

For SaaS platforms, automating PDF generation at scale might require offloading the heavy lifting to a PDF API.

It's also an option to integrate with third-party APIs like pdforge you can handle high-volume PDF generation, complex formatting, and post-processing, all from a single backend call.

Here’s an example of how to integrate pdforge in Rails to convert HTML content into a PDF via an API call:

require 'net/http'
require 'json'
require 'uri'

class PdfApiService
  def self.generate_pdf(html_content)
    uri = URI("https://api.pdforge.com/v1/pdf/sync")
    http = Net::HTTP.new(uri.host, uri.port)
    http.use_ssl = true
    request = Net::HTTP::Post.new(uri.path, {
      'Content-Type' => 'application/json',
      'Authorization' => "Bearer your-api-key"
    })
    request.body = {
      templateId: 'your-template',
      data: { html: html_content }
    }.to_json
    response = http.request(request)
    response.body if response.is_a?(Net::HTTPSuccess)
  end
end

This code sends a POST request to the pdforge API, receives the generated PDF, and saves it locally.

Conclusion

For simple HTML-to-PDF conversions, PDFKit is an accessible and reliable solution for Rails applications.

When detailed control over layout is necessary, Prawn offers a more customizable approach.

For high-scale environments, a third-party PDF API like pdforge provides efficiency and scalability, ensuring high-performance PDF generation.

Generating pdfs at scale can be quite complicated!

Generating pdfs at scale can be quite complicated!

We take care of all of this, so you focus on what trully matters on your Product!

We take care of all of this, so you focus on what trully matters on your Product!

Try for free

7-day free trial

Table of contents

Title