39

I am trying to use custom fonts in my PDF generated with wkhtmltopdf. I read that you can't use google webfonts and that wkhtmltopdf uses truetype .ttf file. Can anyone confirm that? So I downloaded a .ttf file from google webfont and put in on my server, then used the font face:

    @font-face {
        font-family: Jolly;
        src: url('../fonts/JollyLodger-Regular.ttf') format('truetype');
    }

and font family:

    <style type = "text/css">
        p { font-family: 'Jolly', cursive; }
    </style>

And now the text that is supposed to render with Jolly Lodger font doesn't appear at all, page is blank.

What am I doing wrong?

PS: I tried with different .ttf files.

fkoessler
  • 6,932
  • 11
  • 60
  • 92
  • I tested this and was able to get a TTF working without an issue. Are you sure the src url is correct? Are you sure the TTF is working (did you try it on your system)? You might have better luck if you install the font on your server and just call it via regular CSS. – Chords May 21 '12 at 15:34
  • http://g33kinfo.com/info/archives/1806 – Chords May 21 '12 at 15:35
  • 1
    It's working fine when using google web fonts with . Maybe there was actually some problem with my .ttf file in the end... – fkoessler May 28 '12 at 09:41
  • Hi Marronsuisse, can you explain a little more what you used? Im having the same problem but it doesnt work anyway. – Gustavo Jun 13 '13 at 17:50

11 Answers11

30

Since it is a Google Web font you need not to write @font-face in you style sheet just use following link tag in your source code:

<link href='http://fonts.googleapis.com/css?family=Jolly+Lodger' rel='stylesheet' type='text/css'>

and

 <style type = "text/css">
    p { font-family: 'Jolly Lodger', cursive; }
</style>

will work.

By the way, in your code you are defining @font-face family as font-family: Jolly; and using it as p { font-family: 'Jolly Lodger', cursive; } that is wrong, because it's mismatching font-family name.

István
  • 5,057
  • 10
  • 38
  • 67
Daljit
  • 685
  • 5
  • 12
  • 4
    I don't use the link tag on purpose because I read that wkhtmltopdf doesn't work when retrieving the font directly from google webfonts. That is why I download the font and include it in my project. Using the tag works fine when I use the font in a html page though. You're right there is a mistake in my code I will edit it, but even though the name matches, the font still won't appear in the pdf file. I tried with a ttf file and a otf file. – fkoessler May 16 '12 at 07:34
  • I used the code in this answer and it worked fine (using wkhtmltoimage). Maybe the current version of the wkhtmltox tools have been updated to support this? – Lessan Vaezi Jul 26 '14 at 09:49
  • 2
    Doesn't work for me, for wkhtmltopdf on Linux 0.12.2.1 (nor on MacOS) – Wilfred Springer Apr 03 '15 at 08:30
22

I am betting you are calling wkhtmltopdf from a web wrapper using IIS. That's why some folks are saying that it does work for them. They are probably calling wkhtmltopdf from the command line, in which case it can resolve relative links in CSS URL()s but if you are calling it from snappy or the like you can get around the problem by specifying a URL like say URL('http://localhost/myfolder/fonts/JollyLodger-Regular.ttf') instead.

The inability to properly resolve relative links in CSS URL() tags appears to be broken in wkhtmltopdf 0.11.0_rc1 but some earlier versions might work okay. The same problem happens with other CSS URL() tags like when calling a background images - resolving the file location is broken. Interestingly though, in the case of images, if you use <IMG SRC=>, 0.11.0_rc1 is able to find the file, even if a relative path is provided. The problem appears to be limited to URL() tags inside CSS.

EDIT: I found out that if you use file:/// with all forward slashes in the path then it works. In other words URL('file:///D:/InetPub/wwwroot/myfolder/fonts/JollyLodger-Regular.ttf') should work.

Bezinga
  • 221
  • 2
  • 3
  • 2
    Thanks. `file://` URLs seem to be the thing with local fonts and font-face. E.g. `url(file:///my/dir/font.ttf)` on Linux. I mistakedly tried `local()`, but I think that's for something like referencing fonts without paths (out of the installed fonts directories). – Henrik N Apr 30 '13 at 14:23
  • Resolving relative links is still broken in 0.12.* using wrapper on *nix. – Kristen Waite May 05 '16 at 13:24
  • Using `src: url(file://myFont.ttf);` worked with one Font I am using (Note 2 forward slashes). For another Font there was no way to include it locally so I had to keep reference to googleFonts `@import url('https://fonts.googleapis.com/css?family=myFont&display=swap');` otherwise the content was not rendered at all by wkhtmltopdf. Strangely it does not fall back on other fonts defined. – nhaggen May 14 '20 at 14:50
  • I have two questions on this topic. First, how can I apply this solution on a ssl project. Then can I add a format after the urls call? – LucasLaurens Dec 23 '21 at 13:34
18

As stated above by Yardboy we've found that base64 encoding the truetype font in our CSS works well. But I wanted to share some additional insight.

We use 4 custom fonts all uniquely named 'Light' 'Medium' etc..

I use openssl toolkit to base64 encode with good results. But you could alternatively use fontsquirrel. Just be sure to strip out all other font types ('woff' 'otf' .. ). We found that using truetype exclusively worked mysteriously.

Encode file, trim output and add to clipboard

openssl base64 -in bold.ttf | tr -d '\n' | pbcopy

In Windows you should install openssl and add it to path then

openssl base64 -in bold.ttf | tr -d '\n' | clip

or simply use this kind of websites

Add to css font src property

   @font-face {
      font-family: 'Bold';
      font-style: normal;
      font-weight: normal;
      src: url(data:font/truetype;charset=utf-8;base64,BASE64...) format("truetype");
    }

Rendered output will depend on your wkhtmltopdf version and flavor. Because our servers run Debian and I develop on OSX I tested on a VM locally.

Community
  • 1
  • 1
tgk
  • 3,857
  • 2
  • 27
  • 42
  • 1
    Do you mean this will embed the font in the generated PDF documents? – LowLevel May 31 '19 at 12:55
  • Did you encode the whole url (with the base http: // ...) or just the path with font (/ fonts / ...) ? – LucasLaurens Dec 23 '21 at 10:13
  • this should help? https://stackoverflow.com/a/35120327/3384225 it’s not a URL, the string IS the font file encoded in base64 – tgk Dec 24 '21 at 16:11
  • Worked ! I recommend using https://www.fontsquirrel.com/tools/webfont-generator under the "expert" option. to upload your fonts and convert them to Base64. as mentioned in https://stackoverflow.com/a/16204485/473040. – equivalent8 Jan 10 '22 at 15:11
9

If you have .ttf file or .woff file then use following syntax

@font-face {
   font-family: 'Sample Name';
   src: url(/PathToFolderWhereContained/fontName.ttf) format('truetype');
   }

don't use ttf that will not work rather use full name 'truetype' and if you have .woff then use 'woff' in format. For my case it worked.

However the best practice is to use links to Google fonts API that is best if not getting that matching your criteria then use this above technique it will work

eckes
  • 10,103
  • 1
  • 59
  • 71
Husrat Mehmood
  • 2,270
  • 1
  • 20
  • 22
4

I found that Arman H.'s solution (base64 encoding the fonts) over on this question worked like a charm: Google Web Fonts and PDF generation from HTML with wkhtmltopdf

Community
  • 1
  • 1
Yardboy
  • 2,777
  • 1
  • 23
  • 29
3

I'll just add my answer here too, in case someone might need it.

I've been using Rotativa which builds upon wkhtmltopdf, and what I ended up using was the following:

@font-face {
    font-family: "testfont";
    src: url("/UI/Fonts/609beecf-8d23-4a8c-bbf5-d22ee8db2fc9.woff") format("woff"),
         url("/UI/Fonts/1cd9ef2f-b358-4d39-8628-6481d9e1c8ce.svg#1cd9ef2f-b358-4d39-8628-6481d9e1c8ce") format("svg");
}

...and it seem's Rotativa is picking up the SVG-version. If I reorder them it still works, but if I remove the SVG-version, it stops working.

Might be worth a shot. Can't find any good documentation on why this is so, however

Arve Systad
  • 5,471
  • 1
  • 32
  • 58
1

After doing all the workarounds suggested (some which actually worked), I came across a way easier solution:

<style>
@import 'https://fonts.googleapis.com/css?family=Montserrat';
</style>

You can simply use the @import notation to include the font.

gdvalderrama
  • 713
  • 1
  • 17
  • 26
  • 1
    Does not work for me in wkhtmltopdf 0.12.3.2 (with patched qt) - win 8.1 – xtian Oct 08 '16 at 15:51
  • @xtian It worked for me with django-wkhtmltopdf==2.0.3 – gdvalderrama Oct 10 '16 at 07:36
  • Further investigation revealed that what didn't work in my test was importing and using a font with different weights: only one weight was used in all the document regardless of the css setting. This has been fixed in v0.13 alpha apparently. – xtian Oct 11 '16 at 13:24
  • @xtian that's good to know, so the weight of the font can't be specified? Would you mind linking to the bug? – gdvalderrama Oct 11 '16 at 14:25
  • I closed this bug report when I found out that the alpha version was working. I didn't get any official confirmation, but you can do the tests I detail in the report to see if it affects you: https://github.com/wkhtmltopdf/wkhtmltopdf/issues/3151 – xtian Oct 11 '16 at 17:41
1

I personally had to set the font family on a div (I initially wanted a span)

<style>
@font-face {
    font-family: 'CenturyGothic';
    src: url("fonts/century-gothic.ttf") format('truetype');
}

.title {
    font-family: 'CenturyGothic', sans-serif;
    font-size: 22pt;
}
</style>

...

<div class="title">This is Century Gothic</div>
Benoit Duffez
  • 11,839
  • 12
  • 77
  • 125
0

using @import not fetching the font, you need to add .ttf file to the project

ITbug
  • 45
  • 5
0

Just in case nothing has worked out for you yet:

Please try the standalone version of wkhtmltopdf instead of installable.

I had a similar issue but its resolved by using:

https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6-1/wkhtmltox-0.12.6-1.mxe-cross-win64.7z

Unzip the file > go to bin folder > run your command.

pixlboy
  • 1,452
  • 13
  • 30
0

Option for unix based systems

I was generating these pdfs server side. I was finding that fetching the font in the above ways was blowing up my pdfs e.g. 24kb vs 1Mb. I found this very helpful https://sanjay.cc/ubuntu-font-install.

Basically wkhtmltopdf looks in /usr/share/fonts/truetype for system fonts. So all you really have to do is add the font you want to this folder and make it accessible. Then you can just reference the font. e.g. if I want to use calibri then I can do the following.

  1. Add the font
cp -r calibri /usr/share/fonts/truetype/
  1. Cache font
fc-cache -f -v
  1. Use the font
html {
    font-family: Calibri;
}

Note: add all font variations for best results

calibri
├── calibri-bold-italic.ttf
├── calibri-bold.ttf
├── calibri-italic.ttf
└── calibri-regular.ttf
Glen Thompson
  • 9,071
  • 4
  • 54
  • 50