Python实现阿拉伯语DataFrame转PDF:解决导出单元格为空问题
解决阿拉伯语DataFrame转PDF时单元格为空的问题
问题根源
matplotlib默认字体不支持阿拉伯语字符,且未处理从右到左(RTL)的文本排版逻辑,导致阿拉伯语内容无法正常渲染,表现为单元格为空。
解决方案一:修复matplotlib的字体与RTL设置
通过指定支持阿拉伯语的字体、调整文本对齐方式,让matplotlib正确渲染阿拉伯语内容。
代码示例
import matplotlib import matplotlib.pyplot as plt from pandas.plotting import table from matplotlib.backends.backend_pdf import PdfPages import pandas as pd from matplotlib.font_manager import FontProperties # 示例阿拉伯语DataFrame report = pd.DataFrame({ "اسم المستخدم": ["حسام", "محمد", "فاطمة"], "العمر": [30, 25, 28], "المدينة": ["جدة", "الرياض", "مكة"] }) # 手动指定阿拉伯语字体文件路径(替换为你本地的实际路径) font_path = "NotoNaskhArabic-Regular.ttf" arabic_font = FontProperties(fname=font_path) fig, ax = plt.subplots(figsize=(12, 4)) ax.axis('tight') ax.axis('off') # 创建表格并设置右对齐(符合阿拉伯语阅读习惯) the_table = ax.table( cellText=report.values, colLabels=report.columns, loc='center', cellLoc='right', colLoc='right' ) # 为所有单元格应用阿拉伯语字体 for cell in the_table.get_celld().values(): cell.set_fontproperties(arabic_font) # 调整字体大小与表格缩放,避免文本截断 the_table.auto_set_font_size(False) the_table.set_fontsize(10) the_table.scale(1.2, 1.2) # 保存PDF pp = PdfPages("arabic_report_matplotlib.pdf") pp.savefig(fig, bbox_inches='tight') pp.close() plt.close()
解决方案二:使用fpdf2库(更适配RTL文本)
matplotlib对RTL语言的排版支持有限,fpdf2专门优化了多语言尤其是RTL文本的渲染,更适合处理阿拉伯语内容。
步骤
- 安装依赖:
pip install fpdf2 - 下载支持阿拉伯语的字体(如Noto Naskh Arabic)
代码示例
from fpdf import FPDF import pandas as pd # 示例阿拉伯语DataFrame report = pd.DataFrame({ "اسم المستخدم": ["حسام", "محمد", "فاطمة"], "العمر": [30, 25, 28], "المدينة": ["جدة", "الرياض", "مكة"] }) class ArabicPDF(FPDF): def footer(self): # 添加页码(阿拉伯语格式) self.set_y(-15) self.set_font('NotoNaskhArabic', '', 10) self.cell(0, 10, f'الصفحة {self.page_no()}', 0, 0, 'C') # 创建PDF并启用RTL模式 pdf = ArabicPDF(orientation='P', unit='mm', format='A4') pdf.set_rtl(True) pdf.add_page() # 添加阿拉伯语字体 pdf.add_font('NotoNaskhArabic', '', 'NotoNaskhArabic-Regular.ttf', uni=True) pdf.set_font('NotoNaskhArabic', '', 12) # 设置列宽与行高 col_count = len(report.columns) col_width = pdf.w / (col_count + 1) row_height = pdf.font_size * 1.5 # 写入列标题 for col in report.columns: pdf.cell(col_width, row_height, col, border=1, align='R') pdf.ln(row_height) # 写入数据行 for _, row in report.iterrows(): for val in row.values: pdf.cell(col_width, row_height, str(val), border=1, align='R') pdf.ln(row_height) # 保存PDF pdf.output("arabic_report_fpdf.pdf")
注意事项
- 字体文件路径需替换为你本地的实际路径,Noto Naskh Arabic可免费下载
- 若DataFrame包含数值类型,转换为字符串时可根据需求格式化(如保留小数位)
- fpdf2的RTL模式会自动调整文本流向,更贴合阿拉伯语的阅读习惯
内容的提问来源于stack exchange,提问作者Hesham Ibrahim
相关产品推荐
相关产品推荐

