Generating PDF in Rails – Handling special characters

Prawn is a great tool for generating PDFs. And the “prawn” gem works really well for Rails and Ruby. Getting started with might take some time, since it has a somewhat steep learning curve. Working with texts is the easiest. As you move on you will start worrying about formatting, styles, tables, images etc. Although you might take some time to get your hands dirty, they are not very complex. Documentation is good, and with a little bit of effort, you should be able to follow along.

The one thing that I found challenging while working with prawn pdf: Handling special characters. And in my Rails app, I frequently got this error:

Prawn::Errors::IncompatibleStringEncoding (Your document includes text that’s not compatible with the Windows-1252 character set. If you need full UTF-8 support, use TTF fonts instead of PDF’s built-in fonts.):

or this error:

PDF’s built-in fonts have very limited support for internationalized text. If you need full UTF-8 support, consider using a TTF font instead.

And the app kept crashing. The app that I was working on had a lot of user generated content, and people were copying and pasting stuff from multiple source (Websites, PDFs, Excel files) to create content for the website. So, there was a lot of special characters to handle. Displaying the content on the website itself wasn’t a problem. Rails, by default, uses “UTF-8” encoding, which worked for most of the modern special characters.

However, while generating PDFs, this isn’t the case. As the error clearly mentions here that, “By default, Prawn doesn’t use UTF-8 font”.

So, the obvious solution was to use a TTF font, which supports UTF-8 encoding. For my case, although, some special characters won’t be rendered correctly or display properly on the PDF files that I generated, the app at least wouldn’t crash anymore. I was fine with that. So, let’s see how to switch to a TTF font. It’s really simple.

1. Choose a TTF font

Search for a font that supports UTF-8 charset. Most of them would. And you could download them for free. I used “Open Sans” font from here. Download the zip file. Unzip all the variants.

2. Move the fonts into the Rails app

Copy all these files into this folder: “/vendor/assets/fonts/Open_Sans”

You might not have this folder structure in your app. Just create the folders if required.

3. Initialise and setup Prawn to use this font
def initialize()
    super(page_size: 'A4', page_layout: :landscape)
    self.font_families.update("OpenSans" => {
      :normal => Rails.root.join("vendor/assets/fonts/Open_Sans/OpenSans-Regular.ttf"),
      :italic => Rails.root.join("vendor/assets/fonts/Open_Sans/OpenSans-Italic.ttf"),
      :bold => Rails.root.join("vendor/assets/fonts/Open_Sans/OpenSans-Bold.ttf"),
      :bold_italic => Rails.root.join("vendor/assets/fonts/Open_Sans/OpenSans-BoldItalic.ttf")
    })

    font "OpenSans"
    ...
    ...
    ...
 end

That’s it. My app didn’t crash anymore, and I could continue generating my PDFs from all the content on my website.