6

I'm trying to add a custom font to jsPDF. I converted my file to base64 and did the following:

doc.addFileToVFS("font/rajdhani-regular-webfont.woff", base64enc);

where base64enc is the base 64 encoded string

then I add the font as follows:

doc.addFont('font/rajdhani-regular-webfont.woff', 'rajdhani', 'normal');

doc.setFont('rajdhani');

however, I keep getting the following error

[Error] jsPDF PubSub Error – "No unicode cmap for font" – Error: No unicode cmap for font — jspdf.min.js:9068
Error: No unicode cmap for font — jspdf.min.js:9068registerTTF — jspdf.min.js:9068i — jspdf.min.js:9027:86open — jspdf.min.js:9032(anonymous function) — jspdf.min.js:6031publish — jspdf.min.js:308yt — jspdf.min.js:729:166addFont — jspdf.min.js:1286callme — freport.php:500onclick — freport.php:100
    publish (jspdf.min.js:29:5989)
    yt (jspdf.min.js:29:18435)
    addFont (jspdf.min.js:29:33701)
    callme (freport.php:500)
    onclick (freport.php:100)

I don't know why this is happening.

Simon Bengtsson
  • 7,573
  • 3
  • 58
  • 87
user130996
  • 71
  • 1
  • 4

4 Answers4

4

I've been struggling too but I finally found how to do it!

As mentioned here there is a font converter made by jsPDF Contributers which you can find on here.

First upload your font here and then type the name of your font. It will generate JS file which then you need to includ in your project. This can be your js folder if you wish.

And once its in your folder add this script tag to your index.html (or whichever html file you need the jsPDF for).

<script src="./fontName.js"></script>

Now that you have the font automatically added to the jsPDF Api for you with that file, you can go ahead and delete below two lines from your code.

doc.addFileToVFS("font/rajdhani-regular-webfont.woff", base64enc);
doc.addFont('font/rajdhani-regular-webfont.woff', 'rajdhani', 'normal');

Once you do that just check the file you downloaded from the converter and you should see at the very bottom, your font name on the second parameter of below code.

this.addFont('fontFile.woff', 'THIS IS FONT NAME' , '.......');

Copy that name. Lets say its "rajdhani" for this example. So you simply just put this before any text you create on the instance of jsPDF (doc).

doc.setFont('rajdhani');

You can simply test it with below

/* 
"p" for portrait page orientation
"pt" for points. default is mm
"a4" is page size 
*/
var doc = new jsPDF("p","pt","a4"); 
doc.setFont('rajdhani');
doc.text('This is a test', 20,20);
doc.save('filename.pdf');

Now you should see a pdf with 20px left 20px top margin ssaying "This is a test" with your font style.

Hope this helps :)

Tunc Gerdan
  • 81
  • 1
  • 6
  • I'm experiencing the same error as the OP and following your steps, but I'm still getting the same error message. I posted a new question and would appreciate your input. Here's the link: https://stackoverflow.com/questions/58178191/no-unicode-cmap-error-importing-custom-font-in-jspdf – John S Oct 01 '19 at 04:53
1

Also for ES6 module users the steps are very similar.

if you are here looking for a solution on Ionic 4 angular typescript like I was, below is the solution that worked for me!

First you need to install the package via npm as below.

npm install jspdf@latest --save

After that as mentioned in my previous reply there is a font converter made by jsPDF Contributers which you can find on here. Use this to upload your font file and include it in your project somewhere easy to reference inside your TS file so it could be in the same folder as the ts file for example.

-fontname-style.js // <<--- Here (This is the file you downloaded from converter)
-custom.page.module.ts
-custom.page.html
-custom.page.scss
-custom.page.spec.ts
-custom.page.ts

Now in your custom.page.ts import the following;

import * as jsPDF from 'jspdf';
import './fontname-style.js';

//OPTIONAL (Only import if you want to use autotable)
import 'jspdf-autotable';
import { autoTable as AutoTable } from 'jspdf-autotable';

Once you do that just check the file you downloaded from the converter and you should see at the very bottom, your font name on the second parameter of below code.

this.addFont('fontFile.ttf', 'fontName' , '.......');

Now you can create a function like this inside the custom.page.ts;

//custom.component.ts or custom.page.ts etc.
exportPDF(){
  var doc = new jsPDF("p","pt","a4"); // You can set your own  paramaters
  doc.setFont('fontName');
  doc.text('This is a test', 20,20); // You can set your own margins
  return doc.save('filename.pdf');
}

Now you should see a pdf with 20px left 20px top margin ssaying "This is a test" with your font style :)

OPTIONAL PLUGIN - AutoTable for jsPDF

If you want to use autotable plugin for jsPDF, install the following package from npm.

npm install jspdf-autotable@latest --save

Once installed add this two imports to your custom.page.ts.

import 'jspdf-autotable';
import { autoTable as AutoTable } from 'jspdf-autotable';

You can create a data of columns and headers if you like

and inside the exportPDF() function we created before add those lines;

//custom.component.ts or custom.page.ts etc.
exportPDF(){
  var doc = new jsPDF("p","pt","a4");
  doc.setFont('fontName');
  doc.text('This is a test', 20,20); // <-- Remove this line
  ((doc as any).autoTable as AutoTable)({
    head: [['Name', 'Email', 'Country']], // <-- Table headers
    body: [                               // <-- Table body
            ['David', 'david@example.com', 'Sweden'],
            ['Castille', 'castille@example.com', 'Norway'],
            // ...
          ],
    styles: { font: "fontName" } /* <-- This is for the font to work in your 
  table */
  });

  return doc.save('filename.pdf');
}

Now you should get a pdf with the table inside it using your font :)

I hope this helps to someone.

Tunc Gerdan
  • 81
  • 1
  • 6
0

i faced the same issue and followed the steps @TuncGerdan explained. My errors got cleared but i am getting the following warning in console.

jspdf.min.js:29 Unable to look up font label for font 'font name', 'normal'. Refer to getFontList() for available fonts.

When i get the fonts list using doc.getFontList(), i can see the custom font i included in the list.

Could somebody help with this.

B0se
  • 1
  • 4
0

I also got Error: No unicode cmap for font when trying to add a new font in binary form without their converter like mentioned in the docs. I think the crucial line in their example is this:

const myFont = ... // load the *.ttf font file as binary string

where for me it was unclear what they mean with binary string. However looking at their converter makes it clear that binary string should be a base64 encoded string.

So for me fetching a font from remote and adding it works with this:

/**
 * load a font from remote and add it to jsPDF doc
 * @param path the path of the font, e.g. '/app/fonts/My-Font.ttf'
 * @param doc the jsPDF doc instance to install the font to
 * @return {Promise<void>}
 */
async function loadFont(path, doc) {
    let response = await fetch(path).catch((e) => console.error(e));
    if (!response) {
        return;
    }
    let fontName = path.substring(path.lastIndexOf("/") + 1);
    console.log("using font", fontName);
    let contentBuffer = await response.arrayBuffer();
    let contentString = util.arrayBufferToBase64(contentBuffer)
    if (contentString) {
        doc.addFileToVFS(fontName, contentString);
        doc.addFont(fontName, fontName, "normal");
        doc.setFont(fontName);
    }
}

For util.arrayBufferToBase64 I'm using the function from this Stackoverflow answer.

klues
  • 847
  • 12
  • 21