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

Django中xhtml2pdf生成阿拉伯语PDF发票失败求助

解决xhtml2pdf生成阿拉伯语PDF显示异常问题

生成的PDF中阿拉伯语文字出现显示混乱(字符颠倒、无法正确连写),针对你的代码,可通过以下关键修正解决:

1. 修复字体加载与RTL文本配置

xhtml2pdf对RTL语言的字体支持需要明确配置,同时要确保字体路径正确:

  • 用Django静态文件标签引用字体,避免路径问题
  • 添加unicode-bidi: embed强制RTL文本方向,保证阿拉伯语排版正确

修改HTML中的样式部分:

{% load static %}
<style>
  @font-face{
    font-family: 'samim';
    src: url('{% static "fonts/Shabnam-FD.ttf" %}') format('truetype');
    font-weight: normal;
    font-style: normal;
  }
  body{
    background: #fff;
    font-family: 'samim', sans-serif !important;
    direction: rtl !important;
    unicode-bidi: embed !important;
  }
</style>

2. 完善xhtml2pdf渲染参数

在pisaDocument中添加阿拉伯语支持的配置项,指定默认字体与编码:

def render_to_pdf(template_src, context_dict={}):
    template = get_template(template_src)
    html = template.render(context_dict)
    result = BytesIO()
    # 配置RTL与字体参数
    pdf_config = {
        'encoding': 'UTF-8',
        'default_font': 'samim',
        'font_path': '/your/project/static/fonts/',  # 替换为你的字体目录绝对路径
    }
    pdf = pisa.pisaDocument(
        BytesIO(html.encode("UTF-8")),
        dest=result,
        encoding='UTF-8',
        **pdf_config
    )
    if not pdf.err:
        return HttpResponse(result.getvalue(), content_type='application/pdf')

3. 修正视图代码语法错误

你的视图代码存在语法错误,多余的括号会导致调用失败,修正后:

pdf = render_to_pdf('pdf/invoice.html', context)
if pdf:
    response = HttpResponse(pdf, content_type='application/pdf')
    filename = f"invoice-{invoice_number}.pdf"
    content = f"inline; filename={filename}"
    response['Content-Disposition'] = content
    return response

4. 移除无效标签

xhtml2pdf不支持<pdf:language name="arabic"/>这个自定义标签,直接删除即可。

额外提示

  • 确保字体文件确实支持阿拉伯语连写(Shabnam-FD符合要求,若仍有问题可尝试Noto Naskh Arabic等字体)
  • 测试时先简化HTML结构,只保留阿拉伯语段落,确认字体加载正常后再添加复杂布局
  • 保证所有阿拉伯语文本为原始UTF-8编码,不要做HTML转义

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 05:12:04