使用jsPDF生成天城文(尼泊尔/印地语)PDF时部分文字显示异常求助
解决jsPDF中天城文(尼泊尔语/印地语)文本拆分显示的问题
我之前也踩过jsPDF渲染天城文的坑,你遇到的हाम्रो显示成हाम् रो、प्रकार显示成प् रकार的问题,本质是jsPDF原生文本渲染不支持天城文的连字(Ligatures)和复杂字形组合。天城文很多字符是通过多个Unicode码点组合成单个视觉字形的(比如म्र是म+्+र的组合),但jsPDF会把每个码点单独渲染,导致连字被拆分开。
下面是我亲测有效的解决方案:
1. 先确认字体的连字支持
首先检查你用的akchyar-unicode.ttf是否包含完整的天城文连字字形。有些所谓的“Unicode字体”可能只包含基础字符,没有实现连字、元音附标等复杂字形的组合。
推荐替换成Noto Sans Devanagari——这是谷歌专门为天城文开发的字体,对复杂字形组合支持非常完善。你可以把字体文件转成Base64后添加到jsPDF的VFS中:
const doc = new jsPDF(); // 假设notoDevanagari是NotoSansDevanagari-Regular.ttf的Base64字符串 doc.addFileToVFS('NotoSansDevanagari-Regular.ttf', notoDevanagari); doc.addFont('NotoSansDevanagari-Regular.ttf', 'NotoDevanagari', 'normal'); doc.setFont('NotoDevanagari');
2. 用HTML转Canvas的方式渲染文本(推荐方案)
jsPDF的原生text方法对OpenType的复杂字形布局(GSUB/GPOS表)支持不足,而浏览器的HTML渲染引擎能完美处理天城文的连字规则。我们可以先把文本渲染成HTML元素,再转成Canvas,最后导入到PDF中:
// 1. 创建临时隐藏的HTML元素来承载天城文 const textContainer = document.createElement('div'); textContainer.style.cssText = ` font-family: 'Noto Sans Devanagari'; font-size: 18px; visibility: hidden; padding: 10px; `; textContainer.textContent = 'हाम्रो प्रकार'; document.body.appendChild(textContainer); // 2. 使用html2canvas将HTML转成Canvas html2canvas(textContainer).then(canvas => { const doc = new jsPDF(); // 将Canvas添加到PDF中,调整坐标和缩放比例 doc.addImage(canvas, 'PNG', 60, 20, canvas.width * 0.25, canvas.height * 0.25); doc.save('nepali-document.pdf'); // 清理临时元素 document.body.removeChild(textContainer); });
注意:需要先引入html2canvas库(可以通过npm安装或CDN引入)。
3. 为什么原生jsPDF方法不行?
天城文属于复杂书写系统,需要依赖OpenType字体中的GSUB(字形替换)和GPOS(字形定位)表来实现连字、元音附标等组合效果。但jsPDF的核心文本渲染引擎并没有处理这些复杂规则,只会按单个Unicode码点依次绘制字符,所以才会出现拆分的情况。
内容的提问来源于stack exchange,提问作者joseph nakarmi
相关产品推荐
相关产品推荐

