Custom font faces in jsPDF?

2019-02-03 12:20发布

问题:

Is it possible to include custom fonts in jsPDF ?

With the basic library, if I console log 'doc.getFontList()' I get:

Courier, Helvetica, Times, courier, helvetica, times

But, say I want to use 'Comic Sans' ( not that I would ;o) ) can it be done ?

Even better, could I use a font is locally stored and has been declared in the site with @font-face ?

回答1:

I found this was possible by modifying jsPDF.js to expose the existing addFont method in the public API.

In jsPDF.js, look for:

//---------------------------------------
// Public API

Add the following:

    API.addFont = function(postScriptName, fontName, fontStyle) {
      addFont(postScriptName, fontName, fontStyle, 'StandardEncoding');
    };

I put this method near other font methods for clarity - API.setFont, API.setFontSize, API.setFontType, etc.

Now in your code, use:

doc.addFont('ComicSansMS', 'Comic Sans', 'normal');
doc.setFont('Comic Sans');
doc.text(50,50,'Hello World');

This works for me with @font-face fonts included with css before loading jsPDF, as well as system fonts. There's probably a better way to do this using jsPDF's plugin framework, but this quick and dirty solution should at least get you going.

Note that doc.getFontList() will not show added fonts:

// TODO: iterate over fonts array or return copy of fontmap instead in case more are ever added.


回答2:

Here is the solution I'm using...

First, as others have mentioned - you need these two libraries:

  1. jsPDF: https://github.com/MrRio/jsPDF
  2. jsPDF-CustomFonts-support: https://github.com/sphilee/jsPDF-CustomFonts-support

Next - the second library requires that you provide it with at least one custom font in a file named default_vfs.js. I'm using two custom fonts - Arimo-Regular.ttf and Arimo-Bold.ttf - both from Google Fonts. So, my default_vfs.js file looks like this:

(

(function (jsPDFAPI) { 
    "use strict";
    jsPDFAPI.addFileToVFS('Arimo-Regular.ttf','[Base64-encoded string of your font]');
    jsPDFAPI.addFileToVFS('Arimo-Bold.ttf','[Base64-encoded string of your font]');
})(jsPDF.API);

Obviously, you version would look different, depending on the font(s) you're using.

There's a bunch of ways to get the Base64-encoded string for your font, but I used this: https://www.giftofspeed.com/base64-encoder/.

It lets you upload a font .ttf file, and it'll give you the Base64 string that you can paste into default_vfs.js.

You can see what the actual file looks like, with my fonts, here: https://cdn.rawgit.com/stuehler/jsPDF-CustomFonts-support/master/dist/default_vfs.js

So, once your fonts are stored in that file, your HTML should look like this:

    <script src="js/jspdf.min.js"></script>
    <script src="js/jspdf.customfonts.min.js"></script>
    <script src="js/default_vfs.js"></script>

Finally, your JavaScript code looks something like this:

const doc = new jsPDF({
      unit: 'pt',
      orientation: 'p',
      lineHeight: 1.2
    });

doc.addFont("Arimo-Regular.ttf", "Arimo", "normal");
doc.addFont("Arimo-Bold.ttf", "Arimo", "bold");

doc.setFont("Arimo");
doc.setFontType("normal");
doc.setFontSize(28);

doc.text("Hello, World!", 100, 100);

doc.setFontType("bold");

doc.text("Hello, BOLD World!", 100, 150);

doc.save("customFonts.pdf");

This is probably obvious to most, but in that addFont() method, the three parameters are:

  1. The font's name you used in the addFileToVFS() function in the default_vfs.js file
  2. The font's name you use in the setFont() function in your JavaScript
  3. The font's style you use in the setFontType() function in your JavaScript

You can see this working here: https://codepen.io/stuehler/pen/pZMdKo

Hope this works as well for you as it did for me.



标签: jspdf