是否可以在jsPDF中使用自定义Google网络字体

时间:2018-08-13 20:10:29

标签: javascript jspdf

我正在使用jsPDF(https://parall.ax/products/jspdfhttps://github.com/MrRio/jsPDF)在Web应用程序中生成动态PDF。

效果很好,但是我想弄清楚是否可以在生成的PDF中使用Google网络字体。

我找到了许多与此问题相关的链接(包括关于SO的其他问题),但是大多数链接已过时,并且没有什么是确定的,因此我希望有人阐明这是否/如何工作

这是到目前为止我尝试过的,但没有成功:

首先,加载字体,并将其缓存为base64编码的字符串:

var arimoBase64;
var request = new XMLHttpRequest()
request.open('GET', './fonts/Arimo-Regular.ttf');
request.responseType = 'blob';
request.onload = function() {
    var reader = new FileReader();
    reader.onloadend = function() {
        arimoBase64 = this.result.split(',')[1];
    }
    reader.readAsDataURL(this.response);
};
request.send()

接下来,创建pdf doc

doc = new jsPDF({
    orientation: "landscape",
    unit: "pt", 
    format: "letter"
});

doc.addFileToVFS("Arimo-Regular.ttf", arimoBase64);
doc.addFont("Arimo-Regular.ttf", "Arimo Regular", "normal");

doc.setFont("Arimo Regular", "normal");

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

保存PDF后-如果在浏览器中查看它-我可以看到自定义字体。但是-如果我使用Adobe Reader或Mac Preview应用查看它,则字体不可见。

我认为这是因为该字体是使用浏览器的字体缓存在浏览器中呈现的,但是该字体实际上并未嵌入PDF中,这就是为什么在Adobe Reader中看不到该字体的原因。

所以-有没有办法完成我想做的事情?

3 个答案:

答案 0 :(得分:4)

好的-我终于弄明白了,并且已经可以使用了。万一这对其他人有用的话-这是我正在使用的解决方案...

首先-您需要两个库:

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

下一步-第二个库需要,您必须在名为default_vfs.js的文件中为其提供至少一种自定义字体。

该文件应如下所示:

(function (jsPDFAPI) { 
    "use strict";
    jsPDFAPI.addFileToVFS("[Your font's name]","[Base64-encoded string of your font]");
})(jsPDF.API);

我正在使用两种自定义字体-Arimo-Regular.ttf和Arimo-Bold.ttf-都来自Google字体。因此,我的default_vfs.js文件如下所示:

(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);

有很多方法可以获取字体的Base64编码的字符串,但是我使用了这种方法:https://www.giftofspeed.com/base64-encoder/

它使您可以上传.ttf字体文件,并为您提供可粘贴到default_vfs.js中的Base64字符串。

您可以在这里使用https://cdn.rawgit.com/stuehler/jsPDF-CustomFonts-support/master/dist/default_vfs.js

查看带有我的字体的实际文件的外观。

因此,一旦将字体存储在该文件中,您的HTML应该如下所示:

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

最后,您的JavaScript代码如下所示:

const doc = new jsPDF({
      unit: 'pt'
    });

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");

这对于大多数人来说可能是显而易见的,但是在该addFont()方法中,三个参数是:

  1. 您在addFileToVFS()文件的default_vfs.js函数中使用的字体名称
  2. 您在JavaScript的setFont()函数中使用的字体名称
  3. 您在JavaScript中的setFontType()函数中使用的字体样式

您可以在这里看到此方法:https://codepen.io/stuehler/pen/pZMdKo

希望这对您和我都一样。

答案 1 :(得分:2)

只想添加更新的答案-对于1.5.3版:

将字体文件转换为base64 = https://www.giftofspeed.com/base64-encoder/

const yanone = "AAWW...DSES"; // base64 string
doc.addFileToVFS('YanoneKaffeesatz-Medium.ttf', yanone);
doc.addFont('YanoneKaffeesatz-Medium.ttf', 'YanoneKaffeesatz', 'normal');
doc.setFont('YanoneKaffeesatz');      

答案 2 :(得分:0)

我最近也遇到了同样的问题,但是jsPDF-CustomFonts-support仓库似乎已卷入MrRio的jsPDF存储库中,因此您不再需要它来使它正常工作。

我碰巧在React App中使用它,并且执行了以下操作:

  1. npm install jspdf
  2. 创建新文件fonts/index.js注意:您可以使用mattstuehler's answer 中的工具将Google字体下载为.ttf并将其转换为Base64编码的字符串)
export const PlexFont = "[BASE64 Encoded String here]";
  1. 将文件导入您需要的位置:
import jsPDF from 'jspdf';
import { PlexFont } from '../fonts';

// Other Reacty things...

exportPDF = () => {

  const doc = new jsPDF();
  doc.addFileToVFS('IBMPlexSans-Bold.ttf', PlexBold);
  doc.addFont('IBMPlexSans-Bold.ttf', 'PlexBold', 'normal')
  doc.setFont('PlexBold');
  doc.text("Some Text with Google Fonts", 0, 0);

  // Save PDF...
}

// ...