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

使用ReportLab从数据库导入阿拉伯语数据到PDF表格时字符颠倒分离

ReportLab生成PDF表格时阿拉伯语字符分离颠倒的解决方法

问题原因

直接将阿拉伯语字符串放入ReportLab的Table单元格时,ReportLab不会自动处理阿拉伯语的双向文本布局和字符连写(ligature),导致字符分离、顺序颠倒。你之前仅在canvas.drawString中处理了文本,但表格内的文本未做对应处理。

解决方案

对每个阿拉伯语字段做两步处理,再用Paragraph包裹后放入表格:

  1. 用arabic_reshaper.reshape()修复阿拉伯语字符的连写问题
  2. 用get_display()调整双向文本的显示顺序
  3. 将处理后的文本封装为Paragraph,并指定阿拉伯语字体与右对齐样式

修改后的完整代码

import arabic_reshaper
from bidi.algorithm import get_display
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
import sqlite3
from reportlab.lib import colors
from reportlab.lib.pagesizes import letter, inch
from reportlab.platypus import Paragraph, SimpleDocTemplate, Table, TableStyle
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.lib.enums import TA_RIGHT

# 注册阿拉伯语字体
pdfmetrics.registerFont(TTFont('Arabic-bold', 'tradbdo.ttf'))

def onFirstPage(canvas, document):
    arabic_text = arabic_reshaper.reshape(u'بيان')
    arabic_text = get_display(arabic_text)

    canvas.setFont('Arabic-bold', 14)
    canvas.drawString(50, 750, arabic_text)
    canvas.line(50, 740, 75, 740)

doc = SimpleDocTemplate("Report.pdf", pagesize=letter)
elements = []

# 创建阿拉伯语段落样式:右对齐+指定字体
arabic_style = getSampleStyleSheet()["BodyText"]
arabic_style.fontName = 'Arabic-bold'
arabic_style.alignment = TA_RIGHT

data = []
conn = sqlite3.connect("S:\\الموارد البشرية & الرعاية الطبية\\HR1.db")
c = conn.cursor()
c.execute('SELECT number, name, date1, date2 FROM agazat2')

# 处理每一行数据:阿拉伯语字段用Paragraph包裹
for row in c.fetchall():
    processed_row = []
    for item in row:
        # 判断是否为阿拉伯语字符(可根据实际字段调整判断逻辑)
        if isinstance(item, str) and '\u0600' <= item <= '\u06FF':
            reshaped_text = arabic_reshaper.reshape(item)
            display_text = get_display(reshaped_text)
            processed_row.append(Paragraph(display_text, arabic_style))
        else:
            processed_row.append(Paragraph(str(item), arabic_style))
    data.append(processed_row)
conn.close()

c_width = [0.5*inch, 3*inch, 1.5*inch, 1.5*inch]
t = Table(data, rowHeights=20, repeatRows=1, colWidths=c_width)
t.setStyle(TableStyle([
    ('GRID', (0,0), (-1,-1), 1, colors.black),
    ('FONTNAME', (0,0), (-1,-1), "Arabic-bold"),
    ('ALIGN', (0,0), (-1,-1), 'RIGHT'),  # 表格内容整体右对齐,符合阿拉伯语阅读习惯
]))

elements.append(t)
doc.build(elements, onFirstPage=onFirstPage)

关键修改点

  • 新增阿拉伯语专用Paragraph样式,设置右对齐和阿拉伯语字体
  • 遍历数据库返回的每一行,对阿拉伯语字段做reshaper和bidi处理后封装为Paragraph
  • 表格样式添加全局右对齐,匹配阿拉伯语阅读逻辑
  • 提前注册字体,避免重复注册操作

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 03:25:28