Skip to content
By Mikel Lindsaar

WickedPDF and custom fonts in Rails

Recently we had a client project using Wicked PDF and wkhtmltopdf on Rails. The application needed to generate PDFs both in English and Chinese characters using a custom font for printing that was compatible with both Mac and Windows desktops.

This apparently simple problem proved to be a rabbit hole of considerable depth.

You see, PDFs embed fonts, and this is done using the local font available at the time of creation. When generating these programatically, you need to make sure that the font you are using has all the right glyphs of the language you are targeting. So if you want to put a Chinese character into your PDF, you need to make sure you are using a font that contains all those UTF-8 Chinese character code-points you need. The version of Helvetica in your server is probably not going to cut it, and even the quickly becoming standard that is Google's Open-Sans font won't handle it either.

What you need to do is either:

  1. Explain to wkhtmltopdf that you want to use a specific font and provide the font in some way that wkhtmltopdf can find it, or
  2. Install the font on the server you are using and then tell wkhtmltopdf the font family you are using.

Examples of how to do number 1 include base64 encoding the font into your stylesheet, which has the unwelcome side effect of bloating the size of your PDF, as all those font files (which for Asian fonts can be multiple megabytes) are embedded wholesale into your PDF. There are other methods, using CDNs and the like but I found them flakey at best.

However, using the second option of installing the font on the server turned out to be fairly simple, and is what I am going to use here.

wkhtmltopdf uses the local system to generate the PDF, and as a result when you generate a PDF and pass in a font-family declaration in the CSS, it will search for a font which the system knows about to see if it can comply. On unix systems, this font cache is controlled by fc-cache

So to get this working, the first thing we do is install Wicked PDF by following the installation instructions on the GitHub page.

Then in the initializer, we specified our layout file (and that we are using HTTPS by default for all the things):

# config/initializers/wicked_pdf.rb
WickedPdf.config = {
  layout: 'document.html',
  default_protocol: 'https'
}

Our layout file is fairly simple:

<!-- app/views/layouts/document.pdf.erb -->
<!doctype html>
<html>
  <head>
    <meta charset='utf-8' />
    <%= wicked_pdf_stylesheet_link_tag 'documents' -%>
  </head>
  <body>
    <div class='pdf-page'>
      <header class='document-header'>
        <h1 class='page-title'>
          <%= yield :header_title %>
        </h1>
      </header>
      <%= yield %>
    </div>
  </body>
</html>

And then in the stylesheet we include:

// app/assets/stylesheets/documents.css
body {
  font-family: 'Noto Sans SC', 'Noto Sans';
  font-size: 14px;
}

Now we need to get the font files. So get the Noto Sans and Noto Sans SC font files and copy them into your app/assets/fonts directory. Make sure you include the various types of fonts you need for compatibility. We installed eot, ttf, woff and woff2 font files to make sure we were compatible.

Finally, on server deploy you need to make sure the font files are known about by the server; at reinteractive we deploy using our OpsCare service, so this was easily done by putting the following into our after_deploy.sh file:

# config/deploy/hooks/after_deploy.sh

# Add hook to refresh font cache for wkhtmltopdf to work
echo "Linking font dir to ${current_app_path}/app/assets/fonts"
ln -sf ${current_app_path}/app/assets/fonts ~/.fonts
echo "Caching fonts"
fc-cache -v

During the deploy you then see the following happen in the output:

45s - Hook: after_deploy.    
45s - /var/www/tradeline-staging/current/app/assets/fonts:    
46s - caching, new cache contents: 26 fonts, 0 dirs    
var/www/tradeline-staging/current/app/assets/fonts:    
50s - caching, new cache contents: 26 fonts, 0 dirs    
home/app_user/.cache/fontconfig: cleaning cache directory    
fc-cache: succeeded    

Which tells us that the fc-cache command has found its intended targets and cached our fonts.

Now, when we view the PDF it should render the fonts correctly and not produce a blank page. Done!

Latest Articles by Our Team

Our expert team of designers and developers love what the do and enjoy sharing their knowledge with the world.

We Hire Only the Best

reinteractive is Australia’s largest dedicated Ruby on Rails development company. We don’t cut corners and we know what we are doing.

We are an organisation made up of amazing individuals and we take pride in our team. We are 100% remote work enabling us to choose the best talent no matter which part of the country they live in. reinteractive is dedicated to making it a great place for any developer to work.

Free Community Workshops

We created the Ruby on Rails InstallFest and Ruby on Rails Development Hub to help introduce new people to software development and to help existing developers hone their skills. These workshops provide invaluable mentorship to train developers, addressing key skills shortages in the industry. Software development is a great career choice for all ages and these events help you get started and skilled up.

  • Webinars

    Webinars

    Webinars are our online portal for tips, tricks and lessons learned in everything we do. Make the most of this free resource to help you become a better developer.

    Learn more about webinars

  • Installfest

    Installfest

    The Ruby on Rails Installfest includes a full setup of your development environment and step-by-step instructions on how to build your first app hosted on Heroku. Over 1,800 attendees to date and counting.

    Learn more about Installfest

  • Development Hub

    Development Hub

    The Ruby on Rails Development Hub is a monthly event where you will get the chance to spend time with our team and others in the community to improve and hone your Ruby on Rails skills.

    Learn more about Development Hub

Get the “reinteractive Review” Monthly Email