You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

jsPDF如何插入Zapfdingbats带圈数字及问题解决方案

问题根因

你的代码存在两个核心认知错误,导致带圈数字无法正常渲染:

  1. jsPDF内置的courier是PDF规范定义的14种核心标准字体之一,这类内置字体仅支持Windows-1252编码的基础拉丁字符,完全没有收录①这类Unicode特殊字符,渲染时自然会出现缺字、乱码。你提到的Courier New是系统安装的第三方字体,jsPDF不会直接调用系统本地字体,你代码里设置的courier根本不是Courier New。
  2. 你参考的ZapfDingbats字体方案无效,是因为该字体的字符映射表中没有对应标准带圈数字的字形,对应编码位置都是其他装饰类符号,无法匹配你输入的带圈数字字符。
可落地解决方案

根据你的需求复杂度,二选一即可:

方案1:零字体依赖手绘实现(仅需①-⑩时首选)

不需要加载任何外部资源,直接通过jsPDF的绘图+文本接口拼接出带圈数字,生成的PDF体积极小,渲染效果100%一致。
封装好的可直接复用的代码如下:

/**
 * 绘制带圈数字
 * @param {jsPDF} doc - jsPDF实例对象
 * @param {number} num - 要展示的数字,支持1-10
 * @param {number} x - 带圈数字左上角横坐标
 * @param {number} y - 文本基线纵坐标
 * @param {number} fontSize - 整体字号,和周围文本保持一致即可
 */
function addCircledNum(doc, num, x, y, fontSize) {
  const circleR = fontSize * 0.32;
  const centerY = y - fontSize * 0.35;
  // 绘制空心圆圈
  doc.circle(x + circleR, centerY, circleR, 'S');
  // 写入圈内数字,自动居中
  const originFontSize = doc.getFontSize();
  doc.setFontSize(fontSize * 0.7);
  doc.text(String(num), x + circleR, centerY + fontSize * 0.22, { align: 'center' });
  // 恢复原有字号设置
  doc.setFontSize(originFontSize);
}

// 调用示例
const doc = new jsPDF('landscape', 'mm', 'a4');
doc.setFont('courier', 'normal');
doc.setFontSize(22);
const prefixText = 'Go to ';
doc.text(prefixText, 20, 20);
// 计算前缀文本宽度,在文本后拼接带圈数字1
const prefixWidth = doc.getTextWidth(prefixText);
addCircledNum(doc, 1, 20 + prefixWidth, 20, 22);
doc.save('mypdf.pdf');
  • 优点:无额外依赖、无版权风险、PDF体积最小
  • 缺点:仅支持1-10的带圈数字,需要更大数值的带圈字符时需要手动调整样式

方案2:嵌入开源字体实现(支持全量带圈字符首选)

如果需要用到⑩以上的带圈数字,直接把支持带圈数字的字体嵌入PDF即可,注意jsPDF无法直接调用系统安装的字体,必须把字体转成base64格式打包进代码里:

  1. 选择SIL开源协议、无版权风险的字体(比如Noto Sans、思源黑体),这类字体完整收录了所有标准带圈数字字形。不要嵌入Courier New,该字体为微软版权所有,商用存在侵权风险
  2. 用jsPDF官方提供的字体转换工具,把准备好的TTF格式字体转成jsPDF可识别的js格式文件,如果只需要用到带圈数字和基础英文字符,可以先用字体裁剪工具删掉无用字形,最终生成的字体文件体积可以控制在几十KB。
  3. 在代码中引入转换好的字体文件,注册后即可正常使用,示例代码如下:
// 引入转换好的字体文件
import './noto-sans-normal.js';

const doc = new jsPDF('landscape', 'mm', 'a4');
// 注册并设置嵌入字体
doc.addFont('NotoSans-Regular.ttf', 'NotoSans', 'normal');
doc.setFont('NotoSans');
doc.setFontSize(22);
// 可直接写入任意带圈数字,无需额外处理
const content = 'Go to ① ② ③ ⑳';
doc.text(content, 20, 20);
doc.save('mypdf.pdf');
  • 优点:支持所有标准Unicode带圈字符,不需要手动拼接绘制,文本排版更自然
  • 缺点:会小幅增加PDF体积,裁剪字体后体积影响可以忽略

内容的提问来源于stack exchange,提问作者0101012

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 13:24:21