Python 3.x 如何使用python中的reportlab、rtl和bidi创建包含波斯语(波斯语)文本的PDF

Python 3.x 如何使用python中的reportlab、rtl和bidi创建包含波斯语(波斯语)文本的PDF,python-3.x,pdf,reportlab,persian,farsi,Python 3.x,Pdf,Reportlab,Persian,Farsi,我一直在尝试创建一个PDF文件,内容可以是英语、波斯语、数字或它们的组合 波斯语文本有一些问题,如:“اییکمتفاتت” ۱-文本必须从右向左书写 2-单词中不同位置的字符之间存在差异(意味着字符根据其周围的字符改变其形状) 3-因为句子是从右向左读的,所以正常的文本包装无法正常工作。我使用reportlab创建PDf,但不幸的是reportlab不支持阿拉伯语和波斯语字母,所以我使用Vahid Mardani的“rtl”库和Meir Kriheli的“pybidi”库使文本在PDf结果中看

我一直在尝试创建一个PDF文件,内容可以是英语、波斯语、数字或它们的组合

波斯语文本有一些问题,如:“اییکمتفاتت”

۱-文本必须从右向左书写

2-单词中不同位置的字符之间存在差异(意味着字符根据其周围的字符改变其形状)


3-因为句子是从右向左读的,所以正常的文本包装无法正常工作。

我使用reportlab创建PDf,但不幸的是reportlab不支持阿拉伯语和波斯语字母,所以我使用Vahid Mardani的“rtl”库和Meir Kriheli的“pybidi”库使文本在PDf结果中看起来正确

首先,我们需要向reportlab添加一种支持波斯语的字体:

from reportlab.lib.enums import TA_RIGHT
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
pdfmetrics.registerFont(TTFont('Persian', 'Bahij-Nazanin-Regular.ttf'))
styles = getSampleStyleSheet()
styles.add(ParagraphStyle(name='Right', alignment=TA_RIGHT, fontName='Persian', fontSize=10))
  • 在ubuntu 14.04中:

    copy Bahij-Nazanin-Regular.ttf into
    /usr/local/lib/python3.4/dist-packages/reportlab/fonts folder
    
  • 向reportlab添加字体和样式:

    from reportlab.lib.enums import TA_RIGHT
    from reportlab.pdfbase import pdfmetrics
    from reportlab.pdfbase.ttfonts import TTFont
    pdfmetrics.registerFont(TTFont('Persian', 'Bahij-Nazanin-Regular.ttf'))
    styles = getSampleStyleSheet()
    styles.add(ParagraphStyle(name='Right', alignment=TA_RIGHT, fontName='Persian', fontSize=10))
    
  • 在下一步中,我们需要将波斯语文本字母重塑为右侧形状,并使每个单词的方向从右向左:

        from bidi.algorithm import get_display
        from rtl import reshaper
        import textwrap
    
        def get_farsi_text(text):
            if reshaper.has_arabic_letters(text):
              words = text.split()
              reshaped_words = []
              for word in words:
                if reshaper.has_arabic_letters(word):
                  # for reshaping and concating words
                  reshaped_text = reshaper.reshape(word)
                  # for right to left    
                  bidi_text = get_display(reshaped_text)
                  reshaped_words.append(bidi_text)
                else:
                  reshaped_words.append(word)
              reshaped_words.reverse()
             return ' '.join(reshaped_words)
            return text
    
    对于添加项目符号或包装文本,我们可以使用以下功能:

        def get_farsi_bulleted_text(text, wrap_length=None):
           farsi_text = get_farsi_text(text)
           if wrap_length:
               line_list = textwrap.wrap(farsi_text, wrap_length)
               line_list.reverse()
               line_list[0] = '{} •'.format(line_list[0])
               farsi_text = '<br/>'.join(line_list)
               return '<font>%s</font>' % farsi_text
           return '<font>%s &#x02022;</font>' % farsi_text
    

    在使用Reportlab一段时间后,我们在组织和格式化它方面遇到了一些问题。这花了很多时间,而且有点复杂。 所以我们决定与pdfkit和jinja2合作。通过这种方式,我们可以用html和CSS进行格式化和组织,而不需要重新格式化波斯语文本

    首先,我们可以设计一个html模板文件,如下所示:

    <!DOCTYPE html> <html> <head lang="fa-IR"> <meta charset="UTF-8"> <title></title> </head> <body > <p dir="rtl">سوابق کاری</p> <ul dir="rtl"> {% for experience in experiences %} <li><a href="{{ experience.url }}">{{ experience.title }}</a></li> {% endfor %} </ul> </body> </html>
    如果有人想使用
    Django
    从html模板生成PDF,可以这样做:

    template = get_template("app_name/template.html")
    context = Context({'something':some_variable})
    html = template.render(context)
    pdf = pdfkit.from_string(html, False)
    response = HttpResponse(pdf, content_type='application/pdf')
    response['Content-Disposition'] = 'attachment; filename=output.pdf'
    return response
    

    如果您的应用程序是在线应用程序,请尝试使用在php上实现这一点的库,因为从python或任何其他语言构建pdf都无关紧要。如果它是正确的,知道我张贴是作为一个答复谢谢你的答复。我可以用python创建PDF,到目前为止它看起来不错,但我还没有用所有不同的文本样式对它进行测试。如果您检查了我的代码并发现任何问题,我将非常感谢您通知我。在混合文本说明时,这是否也有效,无论是LTR单词(“英语”)还是混合句子(既有波斯语又有英语)从右到左显示。@r.aj,感谢您添加了完整的详细示例。当我尝试上述示例时,以LTR方向显示的阿拉伯语单词“157aتتتت㶩㶩㶩㶩㶩㶩㶩”显示为“15785;”.有什么建议吗?嗨,我用这个脚本尝试了你的文本,它工作正常。你确定你使用了get_farsi_text或get_farsi_Bulletted_text函数。因为你的文本似乎没有经过以下步骤:#对于重塑和浓缩单词:#重塑的_text=重塑er.reformate(word)#对于从右到左:#bidi_text=get_display(reformed_text)reformed_words.append(bidi_text)我在这里遇到了同样的问题,pdfkit工作正常,但当尝试添加样式时,例如
    dir='rtl'
    text align=right
    带有En和Fa组合词的文本会奇怪地改变它们的位置并相互覆盖,页边距和填充也不起作用。您有过这样的问题吗?如果有,您可以指导我解决方案吗?
    template = get_template("app_name/template.html")
    context = Context({'something':some_variable})
    html = template.render(context)
    pdf = pdfkit.from_string(html, False)
    response = HttpResponse(pdf, content_type='application/pdf')
    response['Content-Disposition'] = 'attachment; filename=output.pdf'
    return response