← dompdf.js Studio

RTL 与阿拉伯语文字支持:从右到左排版实战

全球化产品的 PDF 导出早晚要面对 RTL(从右到左)文字:阿拉伯语、希伯来语、波斯语、乌尔都语等语言的书写方向与中文英文相反,段落从右往左排,标点方向、数字方向、混排顺序都有独立规则。用不支持 RTL 的库生成 PDF,轻则文字顺序颠倒、重则整段无法阅读,交付给中东客户或阿拉伯语用户的产品会直接失去可用性。dompdf.js 基于真实排版引擎处理双向文本(bidi),支持 dir 属性、text-align 方向控制以及阿拉伯语连字与字形变换,网页上正确的 RTL 排版在 PDF 里同样正确。本文从 RTL 基础概念讲起,覆盖方向属性用法、双向混排算法、阿拉伯语连字、数字与标点方向以及常见陷阱,帮助开发者系统掌握 dompdf.js 的 RTL 排版能力,让多语言 PDF 一次做对,交付给阿拉伯语用户的产品质量有保障。

RTL 语言与排版方向基础

RTL 语言包括阿拉伯语、希伯来语、波斯语、乌尔都语等,覆盖中东、北非与南亚的广大用户群体。这些语言的文字从右向左书写,段落起始于右侧,换行向左推进;标点符号的方向、引号的形状也遵循镜像规则,比如左括号在 RTL 语境下显示为视觉右侧的括号,与 LTR 环境恰好相反,细节差异很多。

方向是文档级属性:HTML 的 dir 属性(ltr/rtl/auto)定义元素的书写方向,浏览器据此决定文本排列、对齐默认值与标点镜像。dompdf.js 渲染 DOM 时继承这套方向体系,模板里设置 dir="rtl",生成的 PDF 段落即从右往左排列,与网页完全一致,不需要任何坐标层面的额外处理,接入成本很低。

RTL 不仅影响文字方向,还影响布局:列表项符号在右侧、表格列从右往左排、text-align 的默认值变为右对齐、flex 主轴方向反转。设计 RTL 模板时要通盘考虑这些联动效应,只改文字方向不改布局,会出现内容顺序正确但视觉结构错乱的情况,测试时务必整页检查,不能只看段落文字。

双向文本与 bidi 算法

RTL 文档中经常混入 LTR 内容:阿拉伯语文章里的英文产品名、电话号码、网址、变量名。双向文本(bidi)算法负责决定这些混合内容的显示顺序,它的核心规则是:每个字符按自身方向排列,段落整体按基地方向(base direction)流动,相邻不同方向的字符段按嵌套层级自动调整顺序,最终呈现正确的阅读顺序。

bidi 算法是排版引擎的内置能力,dompdf.js 直接继承,开发者不需要自己实现字符重排。需要理解的是基地方向的确定规则:元素 dir 属性优先于父元素方向,父元素优先于文档默认方向;方向不明确时用 dir="auto" 让引擎根据首字符自动判断,处理用户输入的多语言文本时尤其好用,比如一条可能是英文也可能是阿拉伯语的备注。

实际开发中,bidi 相关 bug 多数出在数据层:把 RTL 文本与 LTR 文本用字符串拼接,方向混合后显示顺序可能错乱。规范做法是让每段文本保持独立元素,由引擎按各自方向渲染,或者用 Unicode 方向控制字符明确标记边界,避免在字符串层手工编排顺序,数据层干净了,渲染层自然正确。

代码示例:RTL 段落与混排文本

direction: rtl 或 dir="rtl" 声明基地方向后,段落自动从右往左排,text-align: right 与默认方向一致,是 RTL 段落的自然对齐方式。阿拉伯语文本需要对应的阿拉伯语字体才能正确显示,dompdf.js 通过 @font-face 加载 Noto Naskh Arabic 这类字体,字体加载的注意事项与自定义字体完全一致,先 await document.fonts.ready 再生成。

混排时用 span 包裹 LTR 片段并设置 direction: ltr 与 unicode-bidi: isolate,isolate 让内部方向不影响外部段落的方向判断,订单号、邮箱、网址这类内容在 RTL 段落里保持从左到右的阅读顺序,视觉与逻辑都正确;没有 isolate 时,相邻文本的方向判断可能互相干扰,出现顺序错乱的怪现象,排查起来很费劲。

数字方向也要单独考虑:阿拉伯语环境里,西方数字(0-9)通常保持 LTR 方向,但阿拉伯-印度数字(٠-٩)按 RTL 排列;font-variant-numeric: tabular-nums 让表格里的数字等宽对齐,适合金额与数量列。对金额、日期这类关键数据,建议在模板里显式包裹方向明确的元素,不要依赖隐式规则,确保 PDF 里数字顺序绝对正确。

<style>
  body { direction: rtl; font-family: 'Noto Naskh Arabic', 'Source Han Sans SC', serif; }
  .rtl-paragraph { text-align: right; }
  .ltr-inline { direction: ltr; unicode-bidi: isolate; }
</style>
<p class="rtl-paragraph">هذا نص عربي يوضح دعم اتجاه النص من اليمين إلى اليسار</p>
<p class="rtl-paragraph">
  رقم الطلب: <span class="ltr-inline">ORD-2026-0818</span> تم تأكيده بنجاح
</p>
<p class="rtl-paragraph">
  البريد الإلكتروني: <span dir="ltr">support@example.com</span>
</p>

阿拉伯语连字与字形变换

阿拉伯字母有孤立、词首、词中、词尾四种形态,字母在单词中的位置决定使用哪种形态,这一过程称为字形整形(shaping)。整形后的字母通过连字机制连接成流畅的书写效果,这是阿拉伯语排版观感的核心。dompdf.js 复用浏览器内核的整形能力,模板里的阿拉伯语文本会自动完成形态选择与连字,不需要开发者干预,与浏览器显示效果一致。

需要留意的坑是:字体必须真正包含阿拉伯语字形与整形表(GSUB/GPOS),否则即使字符码正确,渲染出来的也是互不相连的孤立字母,观感如同字母被拆散。排查时先确认字体是否支持 Arabic 语言标签,再用浏览器渲染同一文本对比,两者一致说明整形正常,差异明显则多半是字体或加载的问题,按字体链路排查。

标点与符号的镜像也要检查:括号、引号、尖括号在 RTL 语境下自动镜像显示,这是排版引擎的标准行为;但图片、图表中的文字方向不受影响,需要手动设计镜像版本。生成前用真实阿拉伯语文本做一轮视觉验收,比事后发现客户投诉要划算得多,验收清单里加上 RTL 页面整页截图对比,稳妥可靠。

数字、标点与混排方向细节

RTL 文档里的数字方向遵循 Unicode 的欧洲数字规则:西方数字在 RTL 段落中整体保持从左到右,但带千分位的数字串顺序不变;如果混用阿拉伯-印度数字,方向与字形都不同,模板里应避免两种数字体系混用,统一风格才能保证表格和金额列的整齐,混用是排版混乱的常见来源。

标点方向随上下文:逗号、句号在 RTL 段落里按 RTL 方向显示,但包裹在 LTR 片段内的标点保持 LTR 行为。unicode-bidi: isolate 再次成为关键工具,它把标点的方向判断限制在元素内部,避免标点跑到错误的位置,混排复杂的段落建议对每个语言片段显式设置方向属性,方向控制越明确,渲染越稳定。

另一个细节是 URL 与邮箱在 RTL 段落中的显示:它们内部是 LTR 序列,但作为整体出现在 RTL 段落里时,位置与环绕的阿拉伯语文本相对顺序要正确。用 span 包裹并 isolate 是最稳妥的写法,同时配合 overflow-wrap: break-word 处理长 URL 在窄容器中的换行,RTL 与换行策略结合使用,多语言文档的排版质量才有保障。

常见问题与最佳实践

Q: 阿拉伯语 PDF 显示顺序颠倒?A: 检查模板是否设置了 dir="rtl" 或 direction: rtl,未设置方向时引擎按 LTR 处理,阿拉伯语字符虽然自身方向正确,但段落流动与混排顺序会错;给容器设置正确方向后,绝大多数顺序问题即刻消失,这是第一排查项。

Q: 阿拉伯语字母显示为孤立形态、没有连写?A: 优先确认字体是否支持阿拉伯语整形;字体支持但仍有问题,检查 document.fonts.ready 是否等待完成,字体未就绪时可能使用回退字体渲染,回退字体若无阿拉伯语支持就会退化为孤立字母形态,两者都要验证。

最佳实践小结:文档根元素设置 dir 方向、阿拉伯语正文配专用字体、混排片段用 unicode-bidi: isolate 包裹、生成前等待字体就绪、交付前用真实文本视觉验收。五条做到位,RTL 与阿拉伯语 PDF 就能稳定交付,多语言产品的导出质量也会得到用户认可,海外市场拓展少一道障碍。

⚡ 现场演示(点击生成 PDF)

下面的按钮用 dompdf.js 在浏览器端实时生成 PDF,无需后端:

Hello from dompdf.js!

这是由 dompdf.js 渲染的示例 PDF 内容。