Generating PDFs In Rails Application Using DocRaptor
4 min read

Generating PDFs In Rails Application Using DocRaptor

Generating PDFs In Rails Application Using DocRaptor
This post is sponsored by DocRaptor.com

One of the most common & requested feature I come across when building applications is supporting export data in popular formats like pdf and excel. In the past, I have used multiple libraries to generate these format but the no. of dependencies required to make it all work goes it usually goes out of hand pretty quickly. I have spent countless no. of hours getting the formatting right, debugging why the library is not picking up right styling or worse compiling/maintaining dependencies for these libraries. Moreover, making it all work on hosting providers like Heroku is a task in itself.

DocRaptor.com is a nice service to which I can delegate all the heavy lifting of generating documents by using their simple API. Using their service I can be pretty confident in providing exporting functionality to my users without worrying about eating up all the RAM of my server.

Let me show you how to integrate DocRaptor in your Rails application in a few simple steps

Generate a pdf for an invoice using DocRaptor

Let's first add their gem

gem "docraptor"

For demo purpose add a route

root "invoices#show"

then we will generate a config file & mention our API key

DocRaptor.configure do |config|
  config.username = "YOUR_API_KEY_HERE"
end

Now we will generate our controller

rails g controller Invoice show

Before we start designing our invoice view. We will drop TailwindCSS CDN code in our "app/views/layouts/application.html.erb". We can now move to designing our view inside "app/views/invoices/show.html.erb"

<main class="w-full mt-20 flex flex-col bg-white rounded p-8 text-lg">
  <section class="flex w-full justify-center py-4">
    <img src="https://res.cloudinary.com/bilalbudhani/image/upload/v1577093397/muzica_rryfmx.png" class="w-1/3">
  </section>
  <section class="flex justify-between w-full">
    <div class="flex flex-col">
      <strong>Invoice #001</strong>
      <span class="text-gray-600 mt-4">BILL TO</span>
      <span>Docraptor Demo LLC</span>
      <span>California, USA</span>
    </div>
    <div class="flex flex-col">
      <strong>Invoice Date: 2020-09-10</strong>
      <strong class="mt-8">Status: <span class="text-green-800">PAID</span></strong>
    </div>
  </section>
  <section class="mt-8 w-full">
    <table class="w-full">
      <thead>
        <tr class="border-b border-b-2">
          <th class="text-left py-2">Item</th>
          <th class="text-left py-2">Unit Cost</th>
          <th class="text-left py-2">Quantity</th>
          <th class="text-left py-2">Amount</th>
        </tr>
      </thead>
      <tbody>
        <tr class="border-b">
          <td class="py-4">
            Lite Plan Subscription
          </td>
          <td class="py-4">
            $19.00
          </td>
          <td class="py-4">
            1
          </td>
          <td class="py-4">
            $19.00
          </td>
        </tr>
        <tr class="border-b">
          <td colspan="2"></td>
          <td class="py-4">
            Subtotal
          </td>
          <td class="py-4">
            $19.00
          </td>
        </tr>
        <tr class="border-b">
          <td colspan="2"></td>
          <td class="py-4">
            Tax Rate
          </td>
          <td class="py-4">
            0%
          </td>
        </tr>
        <tr class="border-b">
          <td colspan="2"></td>
          <td class="py-4">
            Amount due
          </td>
          <td class="py-4">
            $19.00
          </td>
        </tr>
      </tbody>
      <tfoot>
        <tr>
          <td colspan="4" class="py-4">
            <p>Please write us at <a href="mailto:[email protected]">[email protected]</a> in case of any questions</p>
          </td>
        </tr>
      </tfoot>
    </table>
  </section>
</main>

This view should look like

invoice show preview

We can tweak our view as per need. Once we're done with designing our view. We can move to calling DocRaptor API to generate PDF.

To get the output of the final view contents we will use Rails' "render_to_string" method and pass it to DocRaptor API

class InvoicesController < ApplicationController

  def show
    docraptor = DocRaptor::DocApi.new
    resp = docraptor.create_doc(
      test: true,
      document_content: render_to_string,
      name: "invoice-001.pdf",
      document_type: "pdf",
      prince_options: {
        media: "screen"
      }
    )
    send_data resp, filename: "invoice-001.pdf", type: "application/pdf"
  end
end

Rerunning the above code should generate pdf and start downloading in our browser.

Hosted Document Feature

Another great feature of DocRaptor.com is we can ask it to generate & host the document as well for us. This allows us to skip another major step of uploading document to a third party service & save us effort of maintaining uploading code. To use this feature we will use create_hosted_doc method and redirect user to download url

docraptor = DocRaptor::DocApi.new
resp = docraptor.create_hosted_doc(
  test: true,
  document_content: render_to_string,
  name: "invoice-001.pdf",
  document_type: "pdf",
  prince_options: {
    media: "screen"
  }
 )
 
 # We can save the download URL to a model
 
 redirect_to resp.download_url

Voila! It is just as easy. All the above code is available on Github https://github.com/BilalBudhani/docraptor-rails-demo

Closing thoughts

When James from DocRaptor.com reached out to me to review their service, I jumped on to it as I have experienced the problems of generating documents on my own first hand. I'm quite impressed with this service & its response time, I will plan to start migrating export functionality inside my projects to use this service.