简体   繁体   English

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

[英]Is it possible to use custom Google web fonts with jsPDF

I'm using jsPDF ( https://parall.ax/products/jspdf , https://github.com/MrRio/jsPDF ) to produce dynamic PDFs in a web application.我正在使用 jsPDF ( https://parall.ax/products/jspdf , https://github.com/MrRio/jsPDF ) 在 Web 应用程序中生成动态 PDF。

It works well, but I'd like to figure out whether it's possible to use Google web fonts in the resulting PDF.它运行良好,但我想弄清楚是否可以在生成的 PDF 中使用 Google 网络字体。

I've found a variety of links that are related to this question (including other questions on SO), but most are out of date, and nothing looks definitive, so I'm hoping someone clarify whether/how this would work.我找到了与这个问题相关的各种链接(包括关于 SO 的其他问题),但大多数都已过时,而且没有什么看起来是确定的,所以我希望有人澄清这是否/如何工作。

Here's what I've tried so far, with no success:这是我迄今为止尝试过的,但没有成功:

First, load the font, and cache it as a base64-encoded string:首先,加载字体,并将其缓存为 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()

Next, create the pdf doc :接下来,创建 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");

When the PDF is saved - if I view it in my browser - I can see the custom font.保存 PDF 后 - 如果我在浏览器中查看它 - 我可以看到自定义字体。 However - if I view it using Adobe Reader or the Mac Preview app - the fonts are not visible.但是 - 如果我使用 Adob​​e Reader 或 Mac Preview 应用程序查看它 - 字体是不可见的。

I assume that's because the font is rendered in the browser using the browser's font cache, but the font is not actually embedded in the PDF, which is why it's not visible using Adobe Reader.我认为这是因为字体是使用浏览器的字体缓存在浏览器中呈现的,但字体实际上并未嵌入 PDF,这就是使用 Adob​​e Reader 看不到它的原因。

So - is there a way to accomplish what I'm trying to do?那么 - 有没有办法完成我想要做的事情?

OK - I finally figured it out, and have gotten it to work.好的 - 我终于想通了,并且已经开始工作了。 In case this is useful for anyone else - here is the solution I'm using...如果这对其他人有用 - 这是我正在使用的解决方案......

First - you need two libraries:首先 - 你需要两个库:

  1. jsPDF: https://github.com/MrRio/jsPDF jsPDF: https : //github.com/MrRio/jsPDF
  2. jsPDF-CustomFonts-support: https://github.com/sphilee/jsPDF-CustomFonts-support 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 .接下来 - 第二个库要求您在名为default_vfs.js的文件中为其提供至少一种自定义字体。

That file should look like this:该文件应如下所示:

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

I'm using two custom fonts - Arimo-Regular.ttf and Arimo-Bold.ttf - both from Google Fonts.我正在使用两种自定义字体 - Arimo-Regular.ttf 和 A​​rimo-Bold.ttf - 均来自 Google Fonts。 So, my default_vfs.js file looks like this:因此,我的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);

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/ .有很多方法可以为您的字体获取 Base64 编码的字符串,但我使用了这个: 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 .它允许您上传字体 .ttf 文件,它会为您提供 Base64 字符串,您可以将其粘贴到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您可以在此处使用我的字体查看实际文件的外观: 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:因此,一旦您的字体存储在该文件中,您的 HTML 应如下所示:

    <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:最后,您的 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");

This is probably obvious to most, but in that addFont() method, the three parameters are:这对大多数人来说可能是显而易见的,但是在那个addFont()方法中,三个参数是:

  1. The font's name you used in the addFileToVFS() function in the default_vfs.js file您在default_vfs.js文件的addFileToVFS()函数中使用的字体名称
  2. The font's name you use in the setFont() function in your JavaScript您在 JavaScript 的setFont()函数中使用的字体名称
  3. The font's style you use in the setFontType() function in your JavaScript您在 JavaScript 的setFontType()函数中使用的字体样式

You can see this working here: https://codepen.io/stuehler/pen/pZMdKo你可以在这里看到这个工作: https : //codepen.io/stuehler/pen/pZMdKo

Hope this works as well for you as it did for me.希望这对你和我一样有效。

I recently ran into this same issue, but it looks like the jsPDF-CustomFonts-support repo was rolled into MrRio's jsPDF repository, so you no longer need it to get this working.我最近遇到了同样的问题,但看起来 jsPDF-CustomFonts-support 存储库已被纳入 MrRio 的 jsPDF 存储库,因此您不再需要它来使其正常工作。

I happen to be using it in a React App and did the following:我碰巧在 React 应用程序中使用它并执行以下操作:

  1. npm install jspdf
  2. Create a new file fonts/index.js ( Note: You can download the Google Font as a .ttf and turn it into the Base64 encoded string using the tool in mattstuehler's answer )创建一个新文件fonts/index.js注意:您可以将 Google 字体下载为 .ttf 并使用mattstuehler 的答案中的工具将其转换为 Base64 编码的字符串
export const PlexFont = "[BASE64 Encoded String here]";
  1. Import that file where you need it:在需要的地方导入该文件:
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...
}

// ...

Just wanted to add an updated answer - for version 1.5.3:只是想添加一个更新的答案 - 对于 1.5.3 版:

Convert the font file to base64 = https://www.giftofspeed.com/base64-encoder/将字体文件转换为 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');      

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM