使用ReportLab从数据库导入阿拉伯语数据到PDF表格时字符颠倒分离
ReportLab生成PDF表格时阿拉伯语字符分离颠倒的解决方法
问题原因
直接将阿拉伯语字符串放入ReportLab的Table单元格时,ReportLab不会自动处理阿拉伯语的双向文本布局和字符连写(ligature),导致字符分离、顺序颠倒。你之前仅在canvas.drawString中处理了文本,但表格内的文本未做对应处理。
解决方案
对每个阿拉伯语字段做两步处理,再用Paragraph包裹后放入表格:
- 用
arabic_reshaper.reshape()修复阿拉伯语字符的连写问题 - 用
get_display()调整双向文本的显示顺序 - 将处理后的文本封装为
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
相关产品推荐
相关产品推荐

