jsPDF PubSub错误 - “没有适用于字体的Unicode cmap”

6

我正在尝试将自定义字体添加到jsPDF中。 我将我的文件转换为base64格式并执行了以下操作:

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

其中base64enc是base64编码字符串。

接着我按照以下方式添加字体:

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

doc.setFont('rajdhani');

然而,我一直收到以下错误。
[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)

我不知道为什么会发生这种情况。

4个回答

5

我也曾经挣扎过,但最终找到了方法!

此处所述,jsPDF的贡献者制作了一个字体转换器,你可以在这里找到。

首先在此上传你的字体,然后输入字体的名称。它将生成JS文件,然后你需要将其包含在你的项目中。如果你愿意,可以放在你的js文件夹下。

一旦它在你的文件夹中,请将此脚本标签添加到你的index.html(或任何需要jsPDF的html文件)中。

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

现在,由于该文件已经自动将字体添加到了jsPDF Api中,您可以继续执行以下操作:从您的代码中删除下面两行

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

完成上述步骤后,检查您从转换器下载的文件,您应该在下面的代码第二个参数中看到您的字体名称。

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

复制那个名称。我们以“rajdhani”为例。因此,您只需将其放置在jsPDF(doc)实例上创建的任何文本之前即可。

doc.setFont('rajdhani');

你可以使用以下方法进行简单测试。
/* 
"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');

现在您应该看到一个带有20px左边、20px顶部边距并显示“这是一个测试”的PDF,字体样式与您的相同。
希望这能帮到您 :)

我遇到了与 OP 相同的错误,并按照您的步骤进行操作,但仍然收到相同的错误消息。我发布了一个新问题,希望得到您的输入。这是链接: https://stackoverflow.com/questions/58178191/no-unicode-cmap-error-importing-custom-font-in-jspdf - John S

1

对于使用ES6模块的用户,步骤非常相似。

如果你像我一样在寻找Ionic 4 angular typescript的解决方案,下面是适用于我的解决方案!

首先,您需要通过npm安装以下软件包。

npm install jspdf@latest --save

接下来,如我之前的回复所提到的,有一个由jsPDF贡献者制作的字体转换器,您可以在这里找到。使用它来上传您的字体文件并将其包含在项目中某个易于引用的位置,例如与ts文件在同一文件夹中。

-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

现在在你的 custom.page.ts 中导入以下内容;
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';

一旦完成上述步骤,检查从转换器下载的文件,在下方代码的第二个参数中应该能看到您的字体名称。

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

现在您可以在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');
}

现在,您应该看到一个带有20px左边距和20px顶部边距的pdf,上面写着“这是一个测试”,字体样式与您相同。 可选插件 - jsPDF的AutoTable 如果您想要使用jsPDF的autotable插件,请从npm安装以下软件包。
npm install jspdf-autotable@latest --save

安装完成后,请将以下两个导入添加到您的custom.page.ts中。

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

你可以创建一个包含列和标题的数据,如果你想要的话。
在我们之前创建的exportPDF()函数中添加以下代码。
//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');
}

现在,您应该使用您的字体获得包含表格的pdf :)
我希望这对某人有所帮助。

0

我遇到了同样的问题,并按照@TuncGerdan解释的步骤操作。我的错误已经被清除,但是我在控制台中得到以下警告。

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

当我使用doc.getFontList()获取字体列表时,可以看到我包含在列表中的自定义字体。
有人可以帮忙吗。

0

我在尝试添加一个没有转换器的二进制字体时,也遇到了Error: No unicode cmap for font错误,就像docs中提到的那样。我认为他们示例中关键的一行是:

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

对我来说,他们所说的“二进制字符串”是不清楚的。然而,看了他们的转换器后,可以明确得知“二进制字符串”应该是一个base64编码的字符串。

因此,对于我来说,从远程获取并添加字体的工作方式如下:

/**
 * 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);
    }
}

对于util.arrayBufferToBase64,我正在使用这个Stackoverflow答案中的函数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接