告别乱码!pdfmake自定义字体完全指南:3步解决中文显示问题

告别乱码!pdfmake自定义字体完全指南:3步解决中文显示问题

【免费下载链接】pdfmake Client/server side PDF printing in pure JavaScript 【免费下载链接】pdfmake 项目地址: https://gitcode.com/gh_mirrors/pd/pdfmake

你是否曾在使用pdfmake生成PDF时遇到中文显示为空白或乱码的问题?作为一款纯JavaScript的PDF生成库,pdfmake凭借其跨平台特性深受开发者喜爱,但字体配置一直是新手的"拦路虎"。本文将通过3个简单步骤,彻底解决中文显示难题,让你轻松掌握自定义字体的所有技巧。读完本文,你将能够:配置任意字体文件、解决中文显示问题、优化字体加载性能,并了解常见错误的排查方法。

一、认识pdfmake字体系统

pdfmake作为一款功能强大的PDF生成库,支持客户端和服务器端两种使用场景README.md。其核心优势包括丰富的文本格式化选项、表格支持、图片嵌入等,但字体管理需要特别配置才能正常显示中文等非西方字符。

字体工作原理

pdfmake使用虚拟文件系统(Virtual File System)管理字体资源,所有字体文件需要通过base64编码嵌入到PDF中。系统默认提供了Roboto字体src/browser-extensions/fonts/Roboto.js,但该字体不包含中文字符,这也是中文显示异常的根本原因。

// 字体配置示例(源自Roboto.js)
var fontContainer = {
  vfs: {
    'Roboto-Regular.ttf': { data: fs.readFileSync('path/to/font.ttf', 'base64'), encoding: 'base64' },
    // 其他字重...
  },
  fonts: {
    Roboto: {
      normal: 'Roboto-Regular.ttf',
      bold: 'Roboto-Medium.ttf',
      italics: 'Roboto-Italic.ttf',
      bolditalics: 'Roboto-MediumItalic.ttf'
    }
  }
};

字体配置结构

每个字体配置包含两个关键部分:

  • vfs:虚拟文件系统,存储base64编码的字体文件
  • fonts:字体定义,映射字重到vfs中的文件

二、3步实现中文显示

步骤1:准备字体文件

首先,选择一个支持中文的字体,如微软雅黑、思源黑体或Noto Sans SC。项目中已提供的示例字体位于examples/fonts/目录,包含了Roboto系列字体文件,但你需要添加中文字体文件到该目录。

步骤2:配置字体文件

创建自定义字体配置文件,参照src/browser-extensions/fonts/Roboto.js的结构,定义中文字体:

// 自定义中文字体配置
var ChineseFont = {
  vfs: {
    'SimHei.ttf': { data: 'base64编码的字体数据', encoding: 'base64' }
  },
  fonts: {
    SimHei: {
      normal: 'SimHei.ttf',
      bold: 'SimHei.ttf',  // 如果没有粗体版本,可复用常规版本
      italics: 'SimHei.ttf',
      bolditalics: 'SimHei.ttf'
    }
  }
};

// 添加字体到pdfmake
pdfmake.addFontContainer(ChineseFont);

步骤3:应用字体到文档

在文档定义中指定中文字体:

// 中文文档示例(修改自examples/basics.js)
var docDefinition = {
  content: [
    { text: '中文标题', font: 'SimHei', fontSize: 20 },
    { text: '这是一段中文内容,现在可以正常显示了。', font: 'SimHei' }
  ],
  defaultStyle: {
    font: 'SimHei'  // 设置全局默认字体
  }
};

// 生成PDF
var pdf = pdfmake.createPdf(docDefinition);
pdf.write('pdfs/chinese-demo.pdf');

三、高级配置与优化

字体子集化

为减小PDF文件体积,可使用字体子集化工具只保留文档中实际使用的字符。这对于中文字体尤为重要,因为完整的中文字体文件通常较大。

多字体 fallback 配置

通过配置字体栈,实现当某个字符在当前字体中不存在时,自动使用后备字体:

var docDefinition = {
  content: [
    { text: '混合文本:English and 中文', font: 'SimHei, Roboto' }
  ]
};

常见问题排查

  1. 字体不生效:检查字体文件路径和base64编码是否正确
  2. 文件体积过大:实施字体子集化,只包含必要字符
  3. 服务器端 vs 客户端差异:服务器端可直接读取文件系统examples/basics.js,客户端需要手动编码字体文件

四、完整示例代码

以下是一个完整的中文PDF生成示例,整合了上述所有技巧:

// 完整中文配置示例
var pdfmake = require('../js/index');
var fs = require('fs');

// 读取中文字体文件并编码为base64
function getFontData(path) {
  return fs.readFileSync(path, 'base64');
}

// 配置中文字体
pdfmake.addFonts({
  SimHei: {
    normal: { data: getFontData('examples/fonts/SimHei.ttf'), encoding: 'base64' },
    bold: { data: getFontData('examples/fonts/SimHei.ttf'), encoding: 'base64' },
    italics: { data: getFontData('examples/fonts/SimHei.ttf'), encoding: 'base64' },
    bolditalics: { data: getFontData('examples/fonts/SimHei.ttf'), encoding: 'base64' }
  }
});

// 创建中文文档
var docDefinition = {
  content: [
    { text: 'pdfmake中文显示示例', font: 'SimHei', fontSize: 18, bold: true },
    { text: '这是一段包含中文的PDF内容,现在可以完美显示了!', font: 'SimHei', fontSize: 12 },
    { 
      text: '表格中的中文也没有问题:', 
      font: 'SimHei', 
      margin: [0, 10, 0, 5] 
    },
    {
      table: {
        body: [
          ['表头1', '表头2'],
          ['内容1', '内容2'],
          ['中文内容', '表格测试']
        ]
      },
      style: { font: 'SimHei' }
    }
  ]
};

// 生成PDF文件
pdfmake.createPdf(docDefinition).write('pdfs/chinese-complete-example.pdf')
  .then(() => console.log('PDF生成成功'))
  .catch(err => console.error('生成失败:', err));

总结与展望

通过本文介绍的3个步骤,你已经掌握了pdfmake自定义字体的核心技巧,成功解决了中文显示问题。字体配置虽然看似简单,但却是实现专业PDF输出的关键一步。随着pdfmake的不断更新,字体管理功能也在持续优化,未来可能会提供更简便的中文字体集成方案。

现在就动手尝试,为你的PDF添加漂亮的中文字体吧!如有任何问题,欢迎在评论区留言讨论。别忘了点赞收藏,关注获取更多pdfmake使用技巧!

【免费下载链接】pdfmake Client/server side PDF printing in pure JavaScript 【免费下载链接】pdfmake 项目地址: https://gitcode.com/gh_mirrors/pd/pdfmake

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值