Skip to main content
 首页 » 编程设计

python之从 html 模板生成 PDF 并在 Django 中通过电子邮件发送

2025年05月04日25lvdongjie

我正在尝试使用 Weasyprint 从 HTML 模板生成 pdf 文件python 包,我需要通过电子邮件发送它。

这是我尝试过的:

def send_pdf(request): 
minutes = int(request.user.tagging.count()) * 5 
testhours = minutes / 60 
hours = str(round(testhours, 3)) 
user_info = { 
    "name": str(request.user.first_name + ' ' + request.user.last_name), 
    "hours": str(hours), 
    "taggedArticles": str(request.user.tagging.count()) 
} 
html = render_to_string('users/certificate_template.html', 
                        {'user': user_info}) 
response = HttpResponse(content_type='application/pdf') 
response['Content-Disposition'] = 'filename=certificate_{}'.format(user_info['name'] + '.pdf') 
pdf = weasyprint.HTML(string=html).write_pdf(response, ) 
from_email = 'our_business_email_address' 
to_emails = ['Reciever1', 'Reciever2'] 
subject = "Certificate from INC." 
message = 'Enjoy your certificate.' 
email = EmailMessage(subject, message, from_email, to_emails) 
email.attach("certificate.pdf", pdf, "application/pdf") 
email.send() 
return HttpResponse(response, content_type='application/pdf') 

But it returns an error as TypeError: expected bytes-like object, not HttpResponse

如何从 HTML 模板生成 pdf 文件并将其发送到电子邮件?

Update: With this updated code now it's generating pdf and sending an email but when I open attached pdf file from recieved email it says unsupported file formate data.

这是更新后的代码:

def send_pdf(request): 
minutes = int(request.user.tagging.count()) * 5 
testhours = minutes / 60 
hours = str(round(testhours, 3)) 
user_info = { 
    "name": str(request.user.first_name + ' ' + request.user.last_name), 
    "hours": str(hours), 
    "taggedArticles": str(request.user.tagging.count()) 
} 
html = render_to_string('users/certificate_template.html', 
                        {'user': user_info}) 
response = HttpResponse(content_type='application/pdf') 
response['Content-Disposition'] = 'filename=certificate_{}'.format(user_info['name']) + '.pdf' 
pdf = weasyprint.HTML(string=html).write_pdf() 
from_email = 'arycloud7@icloud.com' 
to_emails = ['abdul12391@gmail.com', 'arycloud7@gmail.com'] 
subject = "Certificate from Nami Montana" 
message = 'Enjoy your certificate.' 
email = EmailMessage(subject, body=pdf, from_email=settings.EMAIL_HOST_USER, to=to_emails) 
# email.attach("certificate.pdf", pdf, "application/pdf") 
email.content_subtype = "pdf"  # Main content is now text/html 
email.encoding = 'ISO-8859-1' 
email.send() 
return HttpResponse(pdf, content_type='application/pdf') 

请帮帮我!

提前致谢!

请您参考如下方法:

这是上面代码的完整工作版本:

    user_infor = ast.literal_eval(ipn_obj.custom) 
    if int(user_infor['taggedArticles']) > 11: 
        # generate and send an email with pdf certificate file to the user's email 
        user_info = { 
            "name": user_infor['name'], 
            "hours": user_infor['hours'], 
            "taggedArticles": user_infor['taggedArticles'], 
            "email": user_infor['email'], 
        } 
        html = render_to_string('users/certificate_template.html', 
                                {'user': user_info}) 
        response = HttpResponse(content_type='application/pdf') 
        response['Content-Disposition'] = 'filename=certificate_{}'.format(user_info['name']) + '.pdf' 
        pdf = weasyprint.HTML(string=html, base_url='http://8d8093d5.ngrok.io/users/process/').write_pdf( 
            stylesheets=[weasyprint.CSS(string='body { font-family: serif}')]) 
        to_emails = [str(user_infor['email'])] 
        subject = "Certificate from Nami Montana" 
        email = EmailMessage(subject, body=pdf, from_email=settings.EMAIL_HOST_USER, to=to_emails) 
        email.attach("certificate_{}".format(user_infor['name']) + '.pdf', pdf, "application/pdf") 
        email.content_subtype = "pdf"  # Main content is now text/html 
        email.encoding = 'us-ascii' 
        email.send()