我一直在尝试从内容中创建PDF文件,该内容可以是英文、波斯语、数字或它们的组合。
波斯语文本存在一些问题,例如:"این یک متن فارسی است"
1- 文字必须从右到左书写
2- 单词中不同位置的字符有所不同(即字符根据其周围字符而改变形状)
3- 由于句子是从右向左读取的,因此常规的文本换行不起作用。
我一直在尝试从内容中创建PDF文件,该内容可以是英文、波斯语、数字或它们的组合。
波斯语文本存在一些问题,例如:"این یک متن فارسی است"
1- 文字必须从右到左书写
2- 单词中不同位置的字符有所不同(即字符根据其周围字符而改变形状)
3- 由于句子是从右向左读取的,因此常规的文本换行不起作用。
我使用reportlab创建PDF,但不幸的是,reportlab不支持阿拉伯语和波斯语字母,所以我使用了Vahid Mardani的'rtl'库和Meir Kriheli的'pybidi'库来使文本在PDF结果中正确显示。
首先,我们需要添加一个支持波斯语的字体到reportlab:
in ubuntu 14.04:
copy Bahij-Nazanin-Regular.ttf into
/usr/local/lib/python3.4/dist-packages/reportlab/fonts folder
add font and styles to 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 •</font>' % farsi_text
为了测试代码,我们可以编写:
from reportlab.lib.pagesizes import letter
from reportlab.platypus import SimpleDocTemplate, Paragraph
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
doc = SimpleDocTemplate("farsi_wrap.pdf", pagesize=letter, rightMargin=72, leftMargin=72, topMargin=72,
bottomMargin=18)
Story = []
text = 'شاید هنوز اندروید نوقا برای تمام گوشیهای اندرویدی عرضه نشده باشد، ولی اگر صاحب یکی از گوشیهای نکسوس یا پیک' \
'سل باشید احتمالا تا الان زمان نسبتا زیادی را با آخرین نسخهی اندروید سپری کردهاید. اگر در کار با اندروید نوقا' \
' دچار مشکل شدهاید، با دیجیکالا مگ همراه باشید تا با هم برخی از رایجترین مشکلات گزارش شده و راه حل آنها را' \
' بررسی کنیم. البته از بسیاری از این روشها در سایر نسخههای اندروید هم میتوانید استفاده کنید. اندروید برخلاف iOS ' \
'روی گسترهی وسیعی از گوشیها با پوستهها و اپلیکیشنهای اضافی متنوع نصب میشود. بنابراین تجویز یک نسخهی مشترک برا' \
'ی حل مشکلات آن کار چندان سادهای نیست. با این حال برخی روشهای عمومی وجود دارد که بهتر است پیش از هر چیز آنها را' \
' بیازمایید.'
tw = get_farsi_bulleted_text(text, wrap_length=120)
p = Paragraph(tw, styles['Right'])
Story.append(p)
doc.build(Story)
在使用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>
然后,我们使用jinja2库将数据渲染到模板中,然后使用pdfkit从渲染结果创建pdf:
from jinja2 import Template
from pdfkit import pdfkit
sample_data = [{'url': 'http://www.google.com/', 'title': 'گوگل'},
{'url': 'http://www.yahoo.com/fa/', 'title': 'یاهو'},
{'url': 'http://www.amazon.com/', 'title': 'آمازون'}]
with open('template.html', 'r') as template_file:
template_str = template_file.read()
template = Template(template_str)
resume_str = template.render({'experiences': sample_data})
options = {'encoding': "UTF-8", 'quiet': ''}
bytes_array = pdfkit.PDFKit(resume_str, 'string', options=options).to_pdf()
with open('result.pdf', 'wb') as output:
output.write(bytes_array)
dir='rtl'
或者text-align=right
这样的样式时,同时包含英文和波斯语单词的文本会奇怪地改变位置并相互覆盖,边距和填充也无法正常工作。你是否也遇到了这样的问题?如果是,能否指导我解决方案? - aasmpro如果有人想使用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
将多字节(波斯语,阿拉伯语)字符串作为参数发送到以下 TypeScript 函数,并将返回的字符串放入 pdfMaker 或任何其他 PDF 生成器中。
farsiNew(farsistr){
// because pdfmake display it mirrored by default
var allText = '';
var point = 19;
var words = farsistr.split("\n");
var newword;
for(var i=0; i<=words.length-1; i++){
newword = words[i].split( ' ');
if (newword.length <point) {
allText = allText + newword.reverse().join(' ') + "\n";
}else{
for(var q =0; q<= Math.ceil (newword.length / point); q++) {
var s , t;
if (q === 0) {
s = 0; t = point;
}
else {
s = q * point + q;
t = s + point;
}
for (var v = t; v >= s; v--) {
if(!newword[v])
continue;
allText = allText + ' ' +newword[v]
}
allText = allText + '\n';
}
}
}
return allText;
}