Python 3 中 PDF 响应损坏,但在 Python 2 中正常工作

4

我使用Python2.7和Flask编写了一个可以正常运行的应用程序。其中一个功能是下载PDF发票。它目前工作良好。

现在我正在开发一个新应用程序,该应用程序也允许下载PDF发票,但这次我使用的是Python3。我可以将文件保存到服务器并获得一个完美工作的PDF,但如果我尝试将其发送到浏览器,则生成的文件会损坏。

以下是下载函数:

@mod.route('/get_invoice/<invoice_id>')
def get_invoice(invoice_id):
    invoice = Invoices.query.filter_by(id=invoice_id).all()

    pdf_generator = PDFInvoice(invoice)
    pdf = pdf_generator.new()

    response = make_response(pdf.output(dest='S'))
    response.headers['Content-Disposition'] = 'attachment; filename="invoice.pdf"'
    response.headers['Content-Type'] = 'application/pdf'

    return response

这几乎与旧版Python2.7应用程序中的工作函数相同。
具体来说,它将这个(可以正常工作的PDF)转换为:
x�3R��2�35W(�r
Q�w3T��30P^HISp^M^A�^X^[�^YZ*�^[^Z�^Y�*��(h�e^Vg�(�^V+$�(����e����奖h*�d��^@^@�v^T�

将其转换成这样(损坏的PDF):
x^Ü3Rðâ2Ð35W(çr
QÐw3T°Ô30P^HISp^M^A^É^X^[è^YZ*^Ø^[^Zê^Y^Û*^Ĥ(h^Äe^Vg^Ö(^Ô^V+$^Ö(^Ô^×^×ëe§æ^Õèå¥^Öh*^Äd^Áô^@^@øv^TÂ

PDF文件中剩余的数据都是文本字符串,并且它们似乎没有改变。因此,这似乎是某处的编码问题。


一个猜测:这是否是响应编码的原因。您需要在内容类型中指定吗?我查阅了Flask文档,它说默认使用UTF-8... - mechanical_meat
我已经更新了我的问题,并提供了更多信息。看起来它走在正确的轨道上。 - Mike
知道 pdf.output(dest='S') 会产生什么内容会很有用。可能它应该是 bytes,但如果它是 str,那么这就可以解释编码问题了。 - mata
type() 函数显示 <class 'str'>。 - Mike
1个回答

5
FPDF输出一个str,在Python 2中基本上等同于bytes,但在Python 3中是unicode而不是bytes。直接从文档中获取: 如果您使用的是Python 3.x,则必须使用pdf.output(dest='S').encode('latin-1')才能获得输出,如果不这样做,则生成的PDF将无效。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接