我正在尝试使用Weasyprint python包从HTML模板生成pdf文件,我需要通过电子邮件发送它。
这是我尝试过的:
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')
但它返回错误
TypeError: expected bytes-like object, not HttpResponse
如何从HTML模板生成PDF文件并将其发送到电子邮件?
更新:现在使用此更新代码生成pdf并发送电子邮件,但当我从收到的电子邮件中打开附加的pdf文件时,它会显示
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')
请帮帮我!
提前致谢!
答案 0 :(得分:3)
正如您在Weasysprint文档中看到的那样,调用方法write_pdf()
会将文档呈现为单个File
。
http://weasyprint.readthedocs.io/en/stable/tutorial.html
获得HTML对象后,调用其write_pdf()或write_png() 在单个PDF或PNG文件中获取渲染文档的方法。
另外,他们提到了
没有参数,这些方法在内存中返回一个字节字符串。
因此,您可以获取其PDF字节字符串并将其用于附件或传递文件名以将PDF写入。
您还可以向write_pdf()
发送可写文件对象。
如果您传递文件名或可写文件对象,他们会 直接写在那里。
您可以生成并附加PDF文件:
pdf = weasyprint.HTML(string=html).write_pdf()
...
email.attach("certificate.pdf", pdf, "application/pdf")
如果成功,您也可以发送200响应,如果失败则发送500响应。
关于SMTP服务器的说明
通常,您需要一个SMTP邮件服务器才能将邮件转发到目的地。
正如您可以从Django document send_mail
阅读,需要一些configuration:
使用EMAIL_HOST和EMAIL_PORT设置中指定的SMTP主机和端口发送邮件。 EMAIL_HOST_USER和EMAIL_HOST_PASSWORD设置(如果已设置)用于向SMTP服务器进行身份验证,EMAIL_USE_TLS和EMAIL_USE_SSL设置控制是否使用安全连接。
然后,您可以使用send_mail()
以及以下参数将邮件中继到本地SMTP服务器。
send_mail(subject,message,from_email,recipient_list,fail_silently = False,auth_user = None,auth_password = None,connection = None,html_message = None)
注意:不要错过身份验证参数。
答案 1 :(得分:1)
以上是上述代码的完整工作版本:
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()
答案 2 :(得分:0)
此代码适用于我
template = get_template('admin/invoice.html')
context = {
"billno": bill_num,
"billdate": bill_date,
"patientname": patient_name,
"totalbill": total_bill,
"billprocedure": invoice_cal,
}
html = template.render(context)
result = BytesIO()
pdf = pisa.pisaDocument(BytesIO(html.encode("ISO-8859-1")), result)#, link_callback=fetch_resources)
pdf = result.getvalue()
filename = 'Invoice.pdf'
to_emails = ['receiver@gmail.com']
subject = "From CliMan"
email = EmailMessage(subject, "helloji", from_email=settings.EMAIL_HOST_USER, to=to_emails)
email.attach(filename, pdf, "application/pdf")
email.send(fail_silently=False)