如何使用Flask send_file()处理pdfkit.from_string()创建的PDF文件

问题描述 投票:0回答:2

我有一个通过以下功能创建的,可以作为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"'}
flask file-transfer pdfkit
2个回答
0
投票

我找到了解决方案。它使用直接从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

我认为如果在新标签页中打开它,或者如果未在浏览器中打开就下载它,那将是更加理想的选择,但这对现在来说已经足够了。


0
投票

如果您的PDF为bytes_file

return bytes(byte_file), 200, {
    'Content-Type': 'application/pdf',
    'Content-Disposition': 'inline; filename="nameofyourchoice.pdf"'}

应该做到这一点。

© www.soinside.com 2019 - 2024. All rights reserved.