【问题标题】:Is it possible to use custom Google web fonts with jsPDF是否可以在 jsPDF 中使用自定义 Google 网络字体
【发布时间】:2020-06-26 21:57:36
【问题描述】:

我正在使用 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 时 - 如果我在浏览器中查看它 - 我可以看到自定义字体。但是 - 如果我使用 Adob​​e Reader 或 Mac Preview 应用程序查看它 - 字体是不可见的。

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

那么 - 有没有办法完成我想要做的事情?

【问题讨论】:

  • 你试过this解决方案吗?
  • @Luca - 我试过了。看起来它可能是一个选项,但看起来它适用于 jsPDF 的 1.4.0 版,但不适用于 1.4.1 版(截至此日期的最新版本)。我有点不愿意依赖一个不适用于最新版本 jsPDF 的库。
  • @Luca - 再次感谢您的评论。最终,确实对我有用。只是花了我一点时间来弄清楚。非常感谢!

标签: javascript jspdf


【解决方案1】:

好的 - 我终于想通了,并且已经开始工作了。如果这对其他人有用 - 这是我正在使用的解决方案...

首先 - 你需要两个库:

  1. jsPDF:https://github.com/MrRio/jsPDF
  2. jsPDF-CustomFonts-支持: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 和 A​​rimo-Bold.ttf - 都来自 Google Fonts。所以,我的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 文件,它会为您提供 Base64 字符串,您可以将其粘贴到 default_vfs.js

您可以在此处使用我的字体查看实际文件的外观: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() 文件中的addFileToVFS() 函数中使用的字体名称
  2. 您在 JavaScript 的 setFont() 函数中使用的字体名称
  3. 您在 JavaScript 的 setFontType() 函数中使用的字体样式

你可以在这里看到这个工作:https://codepen.io/stuehler/pen/pZMdKo

希望这对你和我一样有效。

【讨论】:

    【解决方案2】:

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

    我碰巧在 React 应用程序中使用它并做了以下事情:

    1. npm install jspdf
    2. 创建一个新文件fonts/index.js注意:您可以将 Google 字体下载为 .ttf,然后使用mattstuehler's answer 中的工具将其转换为 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...
    }
    
    // ...
    

    【讨论】:

      【解决方案3】:

      只是想添加一个更新的答案 - 对于 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');      
      

      【讨论】:

        猜你喜欢
        • 2011-10-16
        • 1970-01-01
        • 2017-03-29
        • 1970-01-01
        • 2011-09-24
        • 2022-07-27
        • 1970-01-01
        • 1970-01-01
        • 2016-04-11
        相关资源
        最近更新 更多