pdfmake - 使用自己的字体不起作用

pdfmake - using own fonts not working

我正在使用 pdfmake 在客户端创建 PDF。我们有一个所见即所得的编辑器,允许用户创建 pdf。然后将其解析以与 pdfmake 一起使用。

但是,我无法使用普通字体。该插件使用 vfs_fonts.js 在 PDF 上创建字体,默认为 Roboto。

我正在尝试让它与 Times New Roman 等类似的作品一起使用

我试过这样修改文件:

window.pdfMake = window.pdfMake || {};
window.pdfMake.vfs = {
  Roboto: {
  "Roboto-Italic.ttf": "BASE 64 HERE",
        "Roboto-Medium.ttf": "BASE 64 HERE",
        "Roboto-Regular.ttf": "BASE 64 HERE"
  },
  TimesNewRoman: {
        "Roboto-Italic.ttf": "BASE 64 HERE",
        "Roboto-Medium.ttf": "BASE 64 HERE",
        "Roboto-Regular.ttf": "BASE 64 HERE"
  }
}

我已经使用了与 Roboto 相同的字体作为测试,但它仍然不起作用。这是我返回的错误

Uncaught Error: No unicode cmap for font

下面是我的代码。您将此字符串粘贴到 pdf tester here 中并查看结果

{  
   "content":[  
      {  
         "stack":[  
            {  
               "text":[  
                  {  
                     "text":""
                  }
               ]
            },
            {  
               "text":"ygjjkjgjkhjkjghk",
               "style":"style_2",
               "lineHeight":"1"
            }
         ],
         "style":"style_1"
      },
      {  
         "stack":[  
            {  
               "text":[  
                  {  
                     "text":""
                  }
               ]
            },
            {  
               "text":" ",
               "style":"style_4",
               "lineHeight":"1"
            }
         ],
         "style":"style_3"
      },
      {  
         "stack":[  
            {  
               "text":[  
                  {  
                     "text":""
                  }
               ]
            },
            {  
               "text":"",
               "style":"style_7",
               "font":"TimesNewRoman",
               "lineHeight":"1"
            },
            {  
               "text":"sdfghfdghfghdgfgfh",
               "style":"style_8",
               "font":"TimesNewRoman",
               "lineHeight":"1"
            }
         ],
         "style":"style_5"
      }
   ],
   "styles":{  
      "style_1":{  
         "opacity":"1"
      },
      "style_2":{  
         "opacity":"1"
      },
      "style_3":{  
         "opacity":"1"
      },
      "style_4":{  
         "opacity":"1"
      },
      "style_5":{  
         "opacity":"1"
      },
      "style_6":{  
         "opacity":"1"
      },
      "style_7":{  
         "font":"TimesNewRoman",
         "opacity":"1"
      },
      "style_8":{  
         "opacity":"1"
      }
   },
   "pageSize":"A4",
   "pageOrientation":"portrait",
   "pageMargins":[  
      40,
      20,
      40,
      20
   ]
}

还有其他人用过这个库吗?如果是这样,您是否使用了自定义字体,您是如何让它们工作的?如果需要,我可以 post 更多代码,谢谢

有关如何在客户端使用自定义字体的 Pdfmake 文档 here

vfs_fonts.js 文件格式类似于:

this.pdfMake = this.pdfMake || {}; this.pdfMake.vfs = {
  "Roboto-Italic.ttf": "AAEAAAASAQAABAAgR0RFRtRX1"
}

因此,您应该像下面这样定义它:

window.pdfMake.vfs["Times-New-Roman-Regular.ttf"] = "BASE 64 HERE";
window.pdfMake.vfs["Times-New-Roman-Medium.ttf"] = "BASE 64 HERE";
window.pdfMake.vfs["Times-New-Roman-Italic.ttf"] = "BASE 64 HERE";

之后还需要赋值pdfMake.fonts:

pdfMake.fonts = {
    // Default font should still be available
    Roboto: {
        normal: 'Roboto-Regular.ttf',
        bold: 'Roboto-Medium.ttf',
        italics: 'Roboto-Italic.ttf',
        bolditalics: 'Roboto-Italic.ttf'
    },
    // Make sure you define all 4 components - normal, bold, italics, bolditalics - (even if they all point to the same font file)
    TimesNewRoman: {
        normal: 'Times-New-Roman-Regular.ttf',
        bold: 'Times-New-Roman-Bold.ttf',
        italics: 'Times-New-Roman-Italics.ttf',
        bolditalics: 'Times-New-Roman-Italics.ttf'
    }
};

然后,您可以像现在一样在 pdf 定义中同时使用 RobotTimesNewRoman 作为字体:

{  
   content:[  
      {  
         text: 'some text using Roboto font'
         style: 'style_1'
      },
      {  
         text: 'some text using Times New Roman font'
         font: 'TimesNewRoman'
      }
   ],
   styles:{  
      style_1:{  
         opacity: '1',
         font: 'Roboto'
      }
   }
}

基于 的回答,我用 Times New Roman 字体 javascript 文件构建了一个 github 存储库,以及如何使用它的说明!

PDFMake-Fonts: 我计划最终添加新字体。

作弊总是更好的方法:

window.pdfMake.fonts = {
    "Roboto": {
        normal: 'your-custom-font-url-here',
        bold: 'your-custom-font-url-here',
        italics: 'your-custom-font-url-here',
        bolditalics: 'your-custom-font-url-here',
    }
}

我无法将新字体添加到我在 Vue 2.6 中使用的 pdfmake 库,直到我在 youtube 上观看了这个视频: "Generating and previewing PDF in Angular 10 - Custom Fonts & Icons - Using virtual file system (VFS)"

这是使它起作用的唯一解释。

向 pdfMake 添加自定义字体的简便方法 (client-side)

  1. 从 Google 字体或任何地方下载您需要的所有字体。您将需要 .ttf 文件。

  2. 从 github 下载 pdfMake。将 pdfMake-master/build 中的 3 个文件 - pdfmake.min.js、pdfmake.min.js.map、vfs_fonts.js - 将其移动到客户端 JS 可以访问的 Public 目录。

  3. vfs_fonts.js 是“保存”自定义字体的文件。默认情况下,它包括 Roboto,pdfMake 默认使用它。

  4. 将需要的 TTF 文件转换为 base64(使用 https://www.giftofspeed.com/base64-encoder/

  5. 编辑 vfs_fonts.js,添加以下格式的行:

'font_name-font_weight.ttf' : 'corresponding_base64_code'

例如,假设您想在 'Regular' 和 'Italic' 字重中添加字体 'Lora':

'Lora-Regular.ttf' : <converted base64 of Lora-Regular.ttf from Step 4>,

'Lora-Italic.ttf' : <converted base64 of Lora-Italic.ttf from Step 4>,
  1. 最后一步:在 client-side JS 中,添加
pdfMake.fonts = {
        Lora: {
            normal: 'Lora-Regular.ttf',
            italics: 'Lora-Italic.ttf', //Use the same name used in vfs_fonts.js
        },
    }

P.S。您不需要将 Roboto 添加到此定义中,只需手动添加额外的行即可。

  1. 现在可以在 pdf 中使用字体制作内容定义

我希望这有助于谷歌搜索,因为这个库的文档在我看来很糟糕。

import pdfMake from "pdfmake/build/pdfmake";
import pdfFonts from "pdfmake/build/vfs_fonts";

pdfMake.vfs = {
  ...pdfFonts.pdfMake.vfs,
  'Your-font-name-normal.ttf': 'Your font as base64 format'
};

// add font to fonts collection before generate pdf
pdfMake.fonts = {
  YourFontName: {
    normal: 'Your-font-name-normal.ttf',
  },
};

const docDefinition = {
  defaultStyle: {
    font: 'YourFontName', // use your font name here
  },
  content: [...]
}