After importing some orders and items with
rake db:seed, we can review them:
Generating PDF files
We will be using wickedpdf to generate PDF files. Wicketdpdf is a wrapper around shell utility wkhtmltopdf, which serves PDF files from plain HTML. Wickedpdf doesn't require us to use any specific DSL to create PDF files. Instead it utilizes HTML views that we, Rails developers, are accustomed to. Wickedpdf requires installed wkhtmltopdf, luckily there is a binary version released as a gem, that works on Linux, Mac OS X and Windows. We can start off by adding wicked_pdf and wkhtmltopdf-binary to
bundle install, we can move on to adding support for PDF format in
respond_to do |format|
render pdf: @order.payer_name, # file name
layout: 'layouts/application.pdf.haml', # layout used
show_as_html: params[:debug].present? # allow debuging
Wicked_pdf supports many more options, we can easily start off with these three. Let's create a layout for our PDF files:
%h1 Generate PDF example
We still have to create a show view for PDF format (copied from scaffold HTML version):
%b Payer name:
# the rest is omitted for brevity
If we navigate to our first order and add
Great, we didn't add so much code and we are able to generate PDF files. What if we want to use custom fonts?
Adding custom fonts
To use them in our PDF we have to create a CSS file:
font-family: 'Open Sans';
And include it in our PDF layout with
+ = wicked_pdf_stylesheet_link_tag "pdf"
%h1 Generate PDF example
We still need to add these fonts in our operating system, it may vary depending on what OS you are using. In case of Mac OS X you can add them via native Font Book app. In Ubuntu installing fonts is either done by double clicking or by adding them to
/usr/share/fonts directories and rebuilding fonts cache with
Let's try to generate the PDF again:
Fonts are rendered correctly! We can deploy our application to production.
Deploying on Shelly Cloud
We have installed fonts on our local machine. If we deploy our application to Shelly Cloud, we will notice that our neat fonts are gone. This is because they are missing on Shelly Cloud's virtual servers.
To keep our fonts in one place, we can add them to
app/assets/fontsdirectory. To make sure they are always present on our virtual servers we will create a before_restart hookwith the following content:
ln -sf ~/app/current/app/assets/fonts ~/.fonts
app/assets/fonts directory to
~/.fonts and scans the font directories on the system to rebuild font information cache files. Now our PDF will be generated with proper fonts. We are done.
I did some research on adding fonts to wkhtmltopdf generated PDF. I found a few other possible solutions to this problem, however none of them worked or I had different results on development and production environments.
The first one was to add either absolute paths to fonts or URLs to external sources. I tried both but with no luck. The HTML was correctly rendered but the generated PDFs were actually blank.
The other solution was to encode fonts with base64 and use @font-face rule in CSS. The only restriction was to use Truetype fonts. It worked, however there were problems when multiple @font-face rules were specified for normal and bold fonts. Also rendered fonts looked different, they were not clean and crisp. I found out, on wkhtmltopdf issue tracker, that this is actually a qt-webkit bug. I have created a separate github branch with the last commit showing this technique.