我有一个通过以下功能创建的,可以作为Sendgrid附件正常工作的pdfkit PDF:
def wish_lists_pdf(user=current_user):
pdf_heading = "Thank you!"
pdf_subheading = "Please find the Wish Lists you signed up to sponsor listed below."
pdf_context = {
'heading': pdf_heading,
'subheading': pdf_subheading,
'user': user,
}
css = os.path.join(basedir, 'static/main.css')
pdf_content = render_template(
'partials/email_lists_pdf.html', **pdf_context)
path_wkhtmltopdf = app.config['WKHTMLTOPDF_EXE']
config = pdfkit.configuration(wkhtmltopdf=path_wkhtmltopdf)
pdf_file = pdfkit.from_string(
pdf_content, False, configuration=config, css=css)
bytes_file = BytesIO(pdf_file)
return bytes_file
实际上,sendgrid需要此行而不是字节编码:
encoded_file = base64.b64encode(pdf_attachment).decode()
我尝试过使用这种编码和b64编码,如其他教程所建议。我不太了解编码的目的,因此可能是造成我的错误的部分原因。无论如何,这是我要提供PDF文件的路线:
@bp.route('download_lists_pdf/<int:user_id>', methods=['GET'])
def download_lists_pdf(user_id):
user = User.query.filter_by(id=user_id).first()
pdf_file = wish_lists_pdf(user=user)
return send_file(
pdf_file,
as_attachment=True,
attachment_filename="Wish List Reminder Page.pdf",
mimetype='application/pdf',
)
这将下载一个完全空白的0kb PDF文件。有人可以帮助我理解如何使用send_file()来让我从pdfkit提供此PDF吗?同样,作为Sendgrid附件,文件可以正常工作。
这是sendgrid附件配置,如果有帮助...
context = {
'heading': heading,
'subheading': subheading,
'user': user,
}
message = Mail(
from_email=app.config['ADMIN_EMAIL'],
to_emails=app.config['EMAIL_RECIPIENTS'],
subject=email_subject,
html_content=render_template('partials/email_lists.html', **context),
)
encoded_file = base64.b64encode(pdf_attachment).decode()
attached_file = Attachment(
FileContent(encoded_file),
FileName('Wish List Reminder Page.pdf'),
FileType('application/pdf'),
Disposition('attachment')
)
message.attachment = attached_file
sg = SendGridAPIClient(app.config['SENDGRID_API_KEY'])
response = sg.send(message)
谢谢您的帮助。
编辑:在下面尝试过,但是没有用
bytes_file = BytesIO(pdf_file)
return bytes(bytes_file), 200, {
'Content-Type': 'application/pdf',
'Content-Disposition': 'inline; filename="Wish List reminder sheet.pdf"'}
我找到了解决方案。它使用直接从pdfkit返回的PDF文件,然后使用Flask Response来提供文件。
这里是返回PDF文件的功能:
def wish_lists_pdf(user=current_user):
pdf_heading = "Thank you!"
pdf_subheading = "Please find the Wish Lists you signed up to sponsor listed below."
pdf_context = {
'heading': pdf_heading,
'subheading': pdf_subheading,
'user': user,
}
css = os.path.join(basedir, 'static/main.css')
pdf_content = render_template(
'partials/email_lists_pdf.html', **pdf_context)
path_wkhtmltopdf = app.config['WKHTMLTOPDF_EXE']
config = pdfkit.configuration(wkhtmltopdf=path_wkhtmltopdf)
pdf_file = pdfkit.from_string(
pdf_content, False, configuration=config, css=css)
return pdf_file
这是视图:
@bp.route('download_lists_pdf/<int:user_id>', methods=['GET'])
def download_lists_pdf(user_id):
user = User.query.filter_by(id=user_id).first()
pdf_file = wish_lists_pdf(user=user)
response = Response(pdf_file)
response.headers['Content-Disposition'] = "inline; 'Wish List reminder page'"
response.mimetype = 'application/pdf'
return response
我认为如果在新标签页中打开它,或者如果未在浏览器中打开就下载它,那将是更加理想的选择,但这对现在来说已经足够了。
如果您的PDF为bytes_file
,
return bytes(byte_file), 200, {
'Content-Type': 'application/pdf',
'Content-Disposition': 'inline; filename="nameofyourchoice.pdf"'}
应该做到这一点。