1. 问题背景与核心痛点
最近在做一个后台管理系统时,遇到了一个典型的需求:需要将页面中的表格数据导出为PDF文件。这个看似简单的功能,在实际开发中却遇到了中文乱码的"拦路虎"。使用流行的jsPDF库时,英文和数字都能正常显示,但一到中文就变成了"口口口"这样的乱码。
这个问题其实困扰过不少前端开发者。jsPDF作为一款轻量级的纯JavaScript PDF生成库,虽然使用方便,但对中文的支持确实存在先天不足。经过多次尝试和查阅资料,我发现这主要与字体缺失和编码处理有关。下面就把我的完整解决方案分享给大家,包括原理分析、具体实现和避坑指南。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术原理深度解析
2.1 为什么会出现中文乱码?
要解决这个问题,首先需要理解乱码产生的根本原因。PDF文件本质上是一种复杂的文档格式,它对文本的显示有严格要求:
- 字体嵌入机制:PDF要求所有显示文本必须使用嵌入的字体文件,而jsPDF默认只携带了基础的英文ASCII字符集
- 编码方式差异:中文字符通常采用Unicode编码,而PDF内部使用特定的编码映射表(CMAP)
- 字体度量信息:中文等宽字体需要正确的字符宽度信息才能正确排版
2.2 jsPDF的字体处理机制
jsPDF内部使用ttf格式的字体文件,通过将字体转换为JavaScript数组的方式嵌入。默认情况下,它只包含以下字体:
- 标准字体:courier, helvetica, times, symbol
- 这些字体仅支持ISO-8859-1编码(即拉丁字符集)
这就是为什么直接使用doc.text('中文内容', 10, 10)会出现乱码的根本原因。
3. 完整解决方案实现
3.1 方案选型对比
经过调研,解决中文乱码主要有以下几种方案:
| 方案 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 使用jsPDF自带的亚洲字体 | 简单直接 | 字体选择有限 | 简单需求 |
| 自定义TTF字体 | 灵活自由 | 需要处理字体版权 | 企业级应用 |
| 将文本转为图片 | 兼容性好 | 文件体积大 | 复杂排版 |
| 使用pdf-lib等替代库 | 功能强大 | 学习成本高 | 复杂需求 |
综合考虑后,我选择了自定义TTF字体的方案,因为它既保持了jsPDF的轻量优势,又能灵活支持各种中文字体。
3.2 具体实现步骤
3.2.1 准备字体文件
首先需要获取合法的中文字体文件(.ttf)。这里以"思源黑体"为例:
- 从官方渠道下载字体文件(如SourceHanSansCN-Regular.ttf)
- 使用在线转换工具将ttf转为jsPDF可用的格式
- 推荐使用:https://rawgit.com/MrRio/jsPDF/master/fontconverter/fontconverter.html
- 转换后会得到两个文件:
- 字体定义文件(如SourceHanSansCN-normal.js)
- 度量文件(如SourceHanSansCN-normal.metrics.js)
3.2.2 集成字体到项目中
将生成的两个JS文件放入项目目录,然后在代码中引入:
javascript复制// 引入字体文件
import './fonts/SourceHanSansCN-normal.js';
import './fonts/SourceHanSansCN-normal.metrics.js';
