ReportLab PDF Python 3 个字体问题
ReportLab PDF Python 3 problems with fonts
我想生成不同语言的 PDF 报告。
我遵循了使用 TTFont 的不同指南。
我试过不同的语言,但没有人工作。
例如,对于俄语,我使用:
self.buffer = BytesIO()
self.pdf_data = []
pdfmetrics.registerFont(TTFont('DejaVuSerif', self.font_dir + 'dejavuserif/DejaVuSerif.ttf'))
font_name = "DejaVuSerif"
self.styles = getSampleStyleSheet()
self.styles.add(ParagraphStyle(name = "HeaderTitle", parent = self.styles['Title'], alignment = TA_CENTER, fontName=font_name))
doc = SimpleDocTemplate(self.buffer)
self.pdf_data.append(Paragraph('Операции - Отчет Август 2020 г.', self.styles['HeaderTitle']))
doc.build(self.pdf_data)
pdf = self.buffer.getvalue()
self.buffer.close()
但输出是:
€•‚ƒ„…†† - €‡ˆ‚‡ „‰Š‹Œ‡ 2020 Š.
我做错了什么?
ReportLab 版本 = 3.5.50
更新
我想指出在语言环境中文件是正确的,但是当我在响应中附加时,问题仍然存在。
return flask.send_from_directory(file_path, filename, mimetype="application/pdf", as_attachment=True, attachment_filename=filename, cache_timeout=0)
您显示的部分代码看起来不错。在变量 'pdf' 中,您将返回 PDF 的字节数。
一个人可以 return 带有像这样的烧瓶响应的字节:
@app.route('/')
def gen_pdf():
pdf_util = PDFUtil()
pdf_bytes = pdf_util.generate()
response = make_response(pdf_bytes)
response.headers.set('Content-Type', 'application/pdf')
return response
请注意 Content-Type
header 需要设置为:application/pdf
。如果您希望浏览器下载 PDF 文件而不是直接显示它,您可以添加额外的 header,例如:
response.headers.set('Content-Disposition', 'attachment', filename='test.pdf')
因此,如果字体没问题,并且您将这些字节 return 编辑为 content-type application/pdf
,则正确的结果将显示在浏览器中。
我只稍微修改了您的代码,将其保存在名为 pdf_flask_demo.py
的 python 脚本中,以获取带有烧瓶响应部分的 self-contained 示例:
from io import BytesIO
from reportlab.lib.enums import TA_CENTER
from reportlab.lib.styles import ParagraphStyle, getSampleStyleSheet
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.platypus import SimpleDocTemplate, Paragraph
from flask import Flask, make_response
app = Flask(__name__)
@app.route('/')
def gen_pdf():
pdf_util = PDFUtil()
pdf_bytes = pdf_util.generate()
response = make_response(pdf_bytes)
response.headers.set('Content-Type', 'application/pdf')
return response
class PDFUtil:
def __init__(self):
self.font_dir = "./"
def generate(self):
self.buffer = BytesIO()
self.pdf_data = []
pdfmetrics.registerFont(TTFont('DejaVuSerif', self.font_dir + 'dejavuserif/DejaVuSerif.ttf'))
font_name = "DejaVuSerif"
self.styles = getSampleStyleSheet()
self.styles.add(
ParagraphStyle(name="HeaderTitle", parent=self.styles['Title'], alignment=TA_CENTER, fontName=font_name))
doc = SimpleDocTemplate(self.buffer)
self.pdf_data.append(Paragraph('Операции - Отчет Август 2020 г.', self.styles['HeaderTitle']))
doc.build(self.pdf_data)
pdf = self.buffer.getvalue()
self.buffer.close()
return pdf
备选
也可以将 PDF 文件保存在本地文件系统中,return flask.send_from_directory
。在用户浏览器中下载的 PDF 在 PDF 查看器中打开时也可以正确显示。
@app.route('/')
def gen_pdf():
pdf_util = PDFUtil()
pdf_bytes = pdf_util.generate()
f = open('/Users/stephan/tmp/mytest.pdf', 'wb')
f.write(pdf_bytes)
f.close()
return flask.send_from_directory('/Users/stephan/tmp/', 'mytest.pdf', mimetype="application/pdf", as_attachment=True,
attachment_filename='mytest.pdf', cache_timeout=0)
测试
在命令行我调用:
export FLASK_APP=pdf_flask_demo
export FLASK_ENV=development
flask run
在浏览器中使用 http://127.0.0.1:5000
时,我得到了想要的结果:
我想生成不同语言的 PDF 报告。 我遵循了使用 TTFont 的不同指南。 我试过不同的语言,但没有人工作。
例如,对于俄语,我使用:
self.buffer = BytesIO()
self.pdf_data = []
pdfmetrics.registerFont(TTFont('DejaVuSerif', self.font_dir + 'dejavuserif/DejaVuSerif.ttf'))
font_name = "DejaVuSerif"
self.styles = getSampleStyleSheet()
self.styles.add(ParagraphStyle(name = "HeaderTitle", parent = self.styles['Title'], alignment = TA_CENTER, fontName=font_name))
doc = SimpleDocTemplate(self.buffer)
self.pdf_data.append(Paragraph('Операции - Отчет Август 2020 г.', self.styles['HeaderTitle']))
doc.build(self.pdf_data)
pdf = self.buffer.getvalue()
self.buffer.close()
但输出是:
€•‚ƒ„…†† - €‡ˆ‚‡ „‰Š‹Œ‡ 2020 Š.
我做错了什么?
ReportLab 版本 = 3.5.50
更新
我想指出在语言环境中文件是正确的,但是当我在响应中附加时,问题仍然存在。
return flask.send_from_directory(file_path, filename, mimetype="application/pdf", as_attachment=True, attachment_filename=filename, cache_timeout=0)
您显示的部分代码看起来不错。在变量 'pdf' 中,您将返回 PDF 的字节数。
一个人可以 return 带有像这样的烧瓶响应的字节:
@app.route('/')
def gen_pdf():
pdf_util = PDFUtil()
pdf_bytes = pdf_util.generate()
response = make_response(pdf_bytes)
response.headers.set('Content-Type', 'application/pdf')
return response
请注意 Content-Type
header 需要设置为:application/pdf
。如果您希望浏览器下载 PDF 文件而不是直接显示它,您可以添加额外的 header,例如:
response.headers.set('Content-Disposition', 'attachment', filename='test.pdf')
因此,如果字体没问题,并且您将这些字节 return 编辑为 content-type application/pdf
,则正确的结果将显示在浏览器中。
我只稍微修改了您的代码,将其保存在名为 pdf_flask_demo.py
的 python 脚本中,以获取带有烧瓶响应部分的 self-contained 示例:
from io import BytesIO
from reportlab.lib.enums import TA_CENTER
from reportlab.lib.styles import ParagraphStyle, getSampleStyleSheet
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.platypus import SimpleDocTemplate, Paragraph
from flask import Flask, make_response
app = Flask(__name__)
@app.route('/')
def gen_pdf():
pdf_util = PDFUtil()
pdf_bytes = pdf_util.generate()
response = make_response(pdf_bytes)
response.headers.set('Content-Type', 'application/pdf')
return response
class PDFUtil:
def __init__(self):
self.font_dir = "./"
def generate(self):
self.buffer = BytesIO()
self.pdf_data = []
pdfmetrics.registerFont(TTFont('DejaVuSerif', self.font_dir + 'dejavuserif/DejaVuSerif.ttf'))
font_name = "DejaVuSerif"
self.styles = getSampleStyleSheet()
self.styles.add(
ParagraphStyle(name="HeaderTitle", parent=self.styles['Title'], alignment=TA_CENTER, fontName=font_name))
doc = SimpleDocTemplate(self.buffer)
self.pdf_data.append(Paragraph('Операции - Отчет Август 2020 г.', self.styles['HeaderTitle']))
doc.build(self.pdf_data)
pdf = self.buffer.getvalue()
self.buffer.close()
return pdf
备选
也可以将 PDF 文件保存在本地文件系统中,return flask.send_from_directory
。在用户浏览器中下载的 PDF 在 PDF 查看器中打开时也可以正确显示。
@app.route('/')
def gen_pdf():
pdf_util = PDFUtil()
pdf_bytes = pdf_util.generate()
f = open('/Users/stephan/tmp/mytest.pdf', 'wb')
f.write(pdf_bytes)
f.close()
return flask.send_from_directory('/Users/stephan/tmp/', 'mytest.pdf', mimetype="application/pdf", as_attachment=True,
attachment_filename='mytest.pdf', cache_timeout=0)
测试
在命令行我调用:
export FLASK_APP=pdf_flask_demo
export FLASK_ENV=development
flask run
在浏览器中使用 http://127.0.0.1:5000
时,我得到了想要的结果: