【问题标题】:Custom font faces in jsPDF?jsPDF中的自定义字体?
【发布时间】:2014-11-13 11:50:46
【问题描述】:

是否可以在 jsPDF 中包含自定义字体?

使用基本库,如果我在控制台登录“doc.getFontList()”,我会得到:

Courier, Helvetica, 时代, 快递, helvetica, 时代

但是,假设我想使用“Comic Sans”(不是我会;o))可以做到吗?

更好的是,我可以使用本地存储并已在站点中使用@font-face 声明的字体吗?

【问题讨论】:

    标签: jspdf


    【解决方案1】:

    我发现这可以通过修改 jsPDF.js 以在公共 API 中公开现有的 addFont 方法来实现。

    jsPDF.js,查找:

    //---------------------------------------
    // Public API
    

    添加以下内容:

        API.addFont = function(postScriptName, fontName, fontStyle) {
          addFont(postScriptName, fontName, fontStyle, 'StandardEncoding');
        };
    

    为了清晰起见,我将此方法放在其他字体方法附近 - API.setFontAPI.setFontSizeAPI.setFontType 等。

    现在在您的代码中,使用:

    doc.addFont('ComicSansMS', 'Comic Sans', 'normal');
    doc.setFont('Comic Sans');
    doc.text(50,50,'Hello World');
    

    这适用于我在加载 jsPDF 之前包含在 css 中的 @font-face 字体以及系统字体。使用 jsPDF 的插件框架可能有更好的方法来做到这一点,但这个快速而肮脏的解决方案至少应该让你继续前进。

    请注意,doc.getFontList()显示添加的字体:

    // TODO: iterate over fonts array or return copy of fontmap instead in case more are ever added.
    

    【讨论】:

    • 感谢您发布此信息。我拿了你的工作,发了一个PR(github.com/MrRio/jsPDF/pull/475),刚刚合并到jsPDF的master里。这是:github.com/MrRio/jsPDF/blob/master/jspdf.js#L1595。再次感谢!
    • 这个不适合我使用谷歌字体。没有添加任何内容,没有显示错误。
    • 请注意,字体从未嵌入到 pdf 本身中,而是从浏览器字体库中读取。如果您尝试保存 pdf,使用自定义字体的部分将不可见。
    • jsPDF 不能。但是,pdfmake - 另一个处理 pdf 的 Javascript 库 - 可以。
    • 不工作。请给出完整的例子来添加字体
    【解决方案2】:

    使用最新版本的jsPDF (1.5.3) 似乎要容易得多:

    如果您查看文件夹jsPDF-master > fontconverter,则有一个文件fontconverter.html。在浏览器中打开并使用Browse... 按钮导航到并选择您的.ttf 字体文件。

    点击“创建”。

    该页面将提供要保存的“下载”。这将生成一个名为 [类似] RopaSans-Regular-normal.js.js 文件。这需要包含在生成 PDF 的页面中。就个人而言,我已经在主页的标题中完成了它(请注意scripts的顺序):

    <!-- pdf creation -->
    <script src="FileSaver.js-master/src/FileSaver.js"></script>
    <script src="jsPDF-master/dist/jspdf.debug.js"></script>
    
    <!-- custom font definition -->
    <script src="path-to-the-file-just-saved/RopaSans-Regular-normal.js" type="module"></script>
    

    现在在你的 js 中的 PDF 生成方法中:

    doc.setFont('RopaSans-Regular');
    doc.setFontType('normal');
    

    【讨论】:

    • 嗨,伙计,我怎么能把它应用到我的 angular´s 7 项目中?我试图将脚本放在脚本会话中的 angular.json 中,但没有执行。然后我尝试将 index.html 放在 header 的会话中,再次没有工作。你能建议我另一种方式吗?
    • 这很有帮助,让我免于加载 TTF 文件和挂起浏览器。谢谢
    【解决方案3】:

    这是我正在使用的解决方案...

    首先,正如其他人所提到的 - 您需要这两个库:

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

    下一步 - 第二个库要求您在名为 default_vfs.js 的文件中为其提供至少一种自定义字体。我正在使用 两个 自定义字体 - 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',
          orientation: 'p',
          lineHeight: 1.2
        });
    
    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

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

    【讨论】:

      【解决方案4】:

      我正在使用 Angular 8,Todd's answer 为我工作。

      从 fontconverter.html 获取 .js 文件后,您可以将其导入到 typescript 中,如下所示:

      import fontref = require('path/to/font/CustomFont-normal.js')
      

      那么加载字体所需要做的就是“调用”fontref:

      makePdf() {
          let doc = new jsPDF();
      
          fontref;                             // 'call' .js to load font
      
          doc.getFontList();                   // contains a key-value pair for CustomFont
      
          doc.setFont("CustomFont");           // set font
          doc.setFontType("normal");
          doc.setFontSize(28);
          doc.text("Hello", 20, 20);
      
          window.open(doc.output('bloburl'));  // open pdf in new tab
        }
      

      【讨论】:

      • 请注意,您可能需要更改 polyfills.ts 以将 import * as jsPDF from "jspdf";(window as any).jsPDF = jsPDF;jsPDF 添加到窗口。
      【解决方案5】:

      查看 fontconverter.html 后,发现它只是将 TTF 文件打包到 JS 文件中的 base64 字符串中,我想出了在创建文档之前调用的以下方法。它基本上完成了由 fontconverter.html 生成的各个文件所做的事情,只是按需:

      async function loadFont(src, name, style, weight) {
          const fontBytes = await fetch(src).then(res => res.arrayBuffer());
          
          var filename = src.split('\\').pop().split('/').pop();
          var base64String = btoa(String.fromCharCode.apply(null, new Uint8Array(fontBytes)));
      
          var callAddFont = function () {
              this.addFileToVFS(filename, base64String);
              this.addFont(filename, name, style, weight );
              };
          jsPDF.API.events.push(['addFonts', callAddFont]);
      }
      

      这样称呼它:

      await loadFont("/css/fonts/exo-2-v9-latin-ext_latin-italic.ttf", "Exo-2", "italic", 400);
      await loadFont("/css/fonts/exo-2-v9-latin-ext_latin-regular.ttf", "Exo-2", "normal", 400);
      await loadFont("/css/fonts/exo-2-v9-latin-ext_latin-500.ttf", "Exo-2", "normal", 500);
      await loadFont("/css/fonts/exo-2-v9-latin-ext_latin-500italic.ttf", "Exo-2", "italic", 500);
      

      它从 URL 加载字体,并将其添加到 VFS 和字体管理器。重要提示:字体名称不能包含空格。您不会收到任何警告,但生成的 PDF 要么无法打开,要么文本看起来很有趣。

      【讨论】:

      • 这实际上是我正在寻找的答案。我认为很多 ao 文件夹的答案已经过时,或者依靠很多第三方工具来回答它的一半。
      • 对我来说类似的故事,在查看了所有答案之后,我想出了上面的代码来简单地按需加载字体。我真的不知道转换器的想法是什么,因为它并没有真正转换任何东西,只是重新打包文件,同时让它变得更大。不直接从 TTF 文件按需加载的理由为零。
      • 我发现你不需要通过(也许)最近版本的 lib 中的事件系统。您现在可以直接使用呼叫。也应该更容易
      • @SebastianSchürmann 将检查。我想避免在我的开发 Web 服务器上可能发生的任何时间问题,但我在生产环境中提出了问题,所以我使用了事件系统。
      【解决方案6】:

      其中一些答案已经过时,因此我将 Rio 先生本人的自述文件链接到这篇文章的最新版本。下面是该自述文件中段落的副本,后面是自述文件本身的链接。希望这个额外的资源对您有所帮助:

      使用 UTF-8 / TTF: PDF 中的 14 种标准字体仅限于 ASCII 码页。如果你想使用 UTF-8,你必须集成一个 自定义字体,提供所需的字形。 jsPDF 支持 .ttf 文件。所以如果你想在你的 pdf,你的字体必须有必要的中文字形。所以检查是否 您的字体支持所需的字形,否则它将显示空白 空格而不是文本。

      要将字体添加到 jsPDF,请使用我们的 fontconverter /fontconverter/fontconverter.html 。 fontconverter 将创建一个 js 文件,其中提供的 ttf 文件的内容为 base64 编码 jsPDF 的字符串和附加代码。你只需要添加这个 为您的项目生成 js 文件。然后你就可以开始使用了 在您的代码中设置字体方法并编写您的 UTF-8 编码文本。

      https://github.com/MrRio/jsPDF/blob/master/README.md#use-of-utf-8--ttf

      【讨论】:

        【解决方案7】:

        到目前为止,我发现的最简单的方法是使用 jspdf-customfonts 包。 只需通过以下方式安装软件包 npm i jspdf-customfonts 然后在 index.html 的 head 标签中添加以下文件以进行默认配置

        script src="https://unpkg.com/jspdf@latest/dist/jspdf.min.js"></script> 
        <script src="dist/jspdf.customfonts.min.js"></script> 
        <script src="dist/default_vfs.js"></script> 
        

        现在您可以下载您想要的任何字体的 ttf 文件。然后去this站点,选择你的字体并复制代码,你就完成了!

        【讨论】:

          猜你喜欢
          • 2018-06-25
          • 1970-01-01
          • 2022-07-27
          • 2019-10-24
          • 1970-01-01
          • 2014-08-25
          • 1970-01-01
          • 1970-01-01
          • 2022-11-30
          相关资源
          最近更新 更多