I run a web-based timeline maker that lets users create timelines in HTML/JavaScript and then export them to PDF files for printing when they're done.
I have had several users report issues with exporting their timelines to PDFs when the timelines contain certain Unicode characters. Here, for example, is a screenshot showing the web page and the PDF file that is generated:
I've been trying to wrap my head around why some Unicode character blocks like Block Elements and Georgian will export but Chinese and Japanese will not. Also, the export works correctly when I perform it on my local computer, but results in the above output when exporting on Heroku.
Does anyone know what might be causing this?
For completeness, the backend is in Ruby on Rails and it uses the PDFKit gem to convert the HTML page to a PDF and the site is hosted on Heroku.
Having personally experienced this with Rails and Heroku, I can tell you the reason is either (A) fonts on your system not matching the fonts on Heroku, or (B) pdfkit
having trouble loading custom fonts linked through CSS, or some combination of both
Most likely, you are referencing fonts on your local system (which contain glyphs for special characters) that don't match the fonts on Heroku. Run fc-list
in Heroku's bash to get a list of their installed fonts, and substitute your font(s) for one that has the needed extended charset. However, now you will have to ensure that this font is also installed on your local machine. (Even worse, you could use different fonts for dev
and production
.)
You can also try uploading fonts to Heroku, and linking them from there. However, I've found this method to be unreliable when spanning across multiple systems or dev/staging/production environments, because each and every system has to have the required fonts installed. And even then, PDFkit
makes you jump through hoops to get CSS fonts to work (for example, because of subtle variation in interpretation of font names by different operating systems).
The best solution I've found is to encode and embed fonts directly into CSS. Base-64 encode a font, and add it to the stylesheet:
@font-face {
font-family: 'OpenSans';
src: url(data:font/truetype;charset=utf-8;base64,AAEAAAATAQA...
}
Now you have a bulletproof stylesheet that's portable and self-compatible with every system.
It sounds like it might be an issue with the fonts on the server. The webpage version of the timeline renders correctly because you obviously have the correct font on the client machine that is running the browser. The PDF on the other hand is generated on the server, and thus has to use a font available to it there.
If that's the case, then using a font that both exists on the server and supports the correct CJK characters should fix this issue.
If you do use Docker and is having the same issue above then try installing Japanese fonts at Docker: apt-get install fonts-takao-mincho
If it works then add it to your Dockerfile:
If you do use Docker and is having the same issue, just install japanese fonts at Docker: apt-get install fonts-takao-mincho
If it works then add it to your Dockerfile:
apt update && apt install -y \
# japanese fonts
fonts-takao-mincho