最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - pdfmake - using own fonts not working - Stack Overflow

programmeradmin2浏览0评论

I am using pdfmake to create PDF's on the client side. We have a WYSIWYG editor that allows the users to created a pdf. This is then parsed to work with the pdfmake.

However, i cannot get normal fonts to work. The plugin uses vfs_fonts.js to create the font on the PDF, default is Roboto.

I am trying to get it to work with the likes of Times New Roman etc etc.

I have tried to alter the file like this:

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"
  }
}

I am using pdfmake to create PDF's on the client side. We have a WYSIWYG editor that allows the users to created a pdf. This is then parsed to work with the pdfmake.

However, i cannot get normal fonts to work. The plugin uses vfs_fonts.js to create the font on the PDF, default is Roboto.

I am trying to get it to work with the likes of Times New Roman etc etc.

I have tried to alter the file like this:

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"
  }
}

I have used the same fonts as the Roboto as a test but it still doesn't work. Here is the error I get back

Uncaught Error: No unicode cmap for font

Here is my code below. You paste this string into the pdf tester here and see the result

{  
   "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
   ]
}

Has anyone else used this library? If so, did you use custom fonts, and how did you get them to work? I can post more code if needed, thanks

Share Improve this question asked Nov 17, 2016 at 13:49 PooshonkPooshonk 1,3242 gold badges25 silver badges49 bronze badges
Add a comment  | 

6 Answers 6

Reset to default 13

Pdfmake documentation on how to use custom fonts on client-side here.

The vfs_fonts.js file format is something like:

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

Therefore, you should define it like the following:

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

After that, you still need to assign 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'
    }
};

Then, you can use both Robot and TimesNewRoman as font on your pdf definition as you are doing now:

{  
   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'
      }
   }
}

Based on @spm answer I build a github repository with the Times New Roman font javascript file, and instructions on how to use it!

PDFMake-Fonts: I plan on adding new fonts eventually.

Easy way to add custom fonts to pdfMake (client-side)

  1. Download all fonts you need from Google Fonts or wherever. You'll need the .ttf files.

  2. Download pdfMake from github. Take the 3 files in pdfMake-master/build - pdfmake.min.js, pdfmake.min.js.map, vfs_fonts.js - move this to your Public directory where clientside JS can access.

  3. vfs_fonts.js is the file that "holds" custom fonts. By default it includes Roboto, which is used by default by pdfMake.

  4. Convert needed TTF files to base64 (use https://www.giftofspeed.com/base64-encoder/)

  5. Edit vfs_fonts.js, adding lines in the format:

'font_name-font_weight.ttf' : 'corresponding_base64_code'

For example, say you wanted to add the font 'Lora' in the 'Regular' and 'Italic' weight:

'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. Final step: in client-side JS, add
pdfMake.fonts = {
        Lora: {
            normal: 'Lora-Regular.ttf',
            italics: 'Lora-Italic.ttf', //Use the same name used in vfs_fonts.js
        },
    }

P.S. you do not need to add Roboto to this definition, only the extra lines you add manually.

  1. The fonts can now be used in pdfMake content definition

I hope this helps somebody Googling around, as the documentation for this library is bad IMO.

Cheating is always a better way:

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',
    }
}
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: [...]
}
import * as pdfMake from 'pdfmake/build/pdfmake';
import * as jszip from 'jszip';

pdfMake.vfs = {};
pdfMake.jszip = jszip;
pdfMake.DynamicContent = {
    content: {
        widths: '100%'
    }
};
pdfMake.fonts = {
    Roboto: {
        normal: 'https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.66/fonts/Roboto/Roboto-Regular.ttf',
        bold: 'https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.66/fonts/Roboto/Roboto-Medium.ttf',
        italics: 'https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.66/fonts/Roboto/Roboto-Italic.ttf',
        bolditalics: 'https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.66/fonts/Roboto/Roboto-MediumItalic.ttf'
    },
};

export default pdfMake;
发布评论

评论列表(0)

  1. 暂无评论