从 html 模板生成 PDF 并在 Django 中通过电子邮件发送
Generate PDF from html template and send via Email in Django
我正在尝试使用 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')
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')
请帮帮我!
提前致谢!
正如您从 Weasysprint 文档中看到的,调用方法 write_pdf()
将在单个 File
.
中呈现文档
http://weasyprint.readthedocs.io/en/stable/tutorial.html
Once you have a HTML object, call its write_pdf() or write_png()
method to get the rendered document in a single PDF or PNG file.
此外,他们提到
Without arguments, these methods return a byte string in memory.
因此,您可以获得其 PDF 字节字符串并将其用于附件或传递文件名以写入 PDF。
有一点你也可以发送一个可写的file-like对象到write_pdf()
。
If you pass a file name or a writable file-like object, they will
write there directly instead.
您可以像这样生成并附加 PDF 文件:
pdf = weasyprint.HTML(string=html).write_pdf()
...
email.attach("certificate.pdf", pdf, "application/pdf")
如果成功,您也可以发送 200 个响应;如果失败,则发送 500 个响应。
关于 SMTP 服务器的注意事项
通常您需要一个 SMTP 邮件服务器来将邮件中继到目的地。
你可以从 Django 中读到 document send_mail
need some configuration:
Mail is sent using the SMTP host and port specified in the EMAIL_HOST and EMAIL_PORT settings. The EMAIL_HOST_USER and EMAIL_HOST_PASSWORD settings, if set, are used to authenticate to the SMTP server, and the EMAIL_USE_TLS and EMAIL_USE_SSL settings control whether a secure connection is used.
然后您可以使用 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)
注意:认证参数不要遗漏
这是上面代码的完整工作版本:
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()
这段代码对我有用
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)
基于@Rishabh gupta 的回答:
import io
from django.template.loader import render_to_string
from django.core.mail import EmailMultiAlternatives
from weasyprint import HTML
context = { "name": 'Hello', }
html_string = render_to_string('myapp/report.html', context)
html = HTML(string=html_string)
buffer = io.BytesIO()
html.write_pdf(target=buffer)
pdf = buffer.getvalue()
email_message = EmailMultiAlternatives(
to=("youremailadress@gmail.com",),
subject="subject test print",
body="heres is the body",
)
filename = 'test.pdf'
mimetype_pdf = 'application/pdf'
email_message.attach(filename, pdf, mimetype_pdf)
email_message.send(fail_silently=False) # TODO zzz mabye change this to True
我正在尝试使用 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')
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')
请帮帮我!
提前致谢!
正如您从 Weasysprint 文档中看到的,调用方法 write_pdf()
将在单个 File
.
http://weasyprint.readthedocs.io/en/stable/tutorial.html
Once you have a HTML object, call its write_pdf() or write_png() method to get the rendered document in a single PDF or PNG file.
此外,他们提到
Without arguments, these methods return a byte string in memory.
因此,您可以获得其 PDF 字节字符串并将其用于附件或传递文件名以写入 PDF。
有一点你也可以发送一个可写的file-like对象到write_pdf()
。
If you pass a file name or a writable file-like object, they will write there directly instead.
您可以像这样生成并附加 PDF 文件:
pdf = weasyprint.HTML(string=html).write_pdf()
...
email.attach("certificate.pdf", pdf, "application/pdf")
如果成功,您也可以发送 200 个响应;如果失败,则发送 500 个响应。
关于 SMTP 服务器的注意事项
通常您需要一个 SMTP 邮件服务器来将邮件中继到目的地。
你可以从 Django 中读到 document send_mail
need some configuration:
Mail is sent using the SMTP host and port specified in the EMAIL_HOST and EMAIL_PORT settings. The EMAIL_HOST_USER and EMAIL_HOST_PASSWORD settings, if set, are used to authenticate to the SMTP server, and the EMAIL_USE_TLS and EMAIL_USE_SSL settings control whether a secure connection is used.
然后您可以使用 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)
注意:认证参数不要遗漏
这是上面代码的完整工作版本:
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()
这段代码对我有用
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)
基于@Rishabh gupta 的回答:
import io
from django.template.loader import render_to_string
from django.core.mail import EmailMultiAlternatives
from weasyprint import HTML
context = { "name": 'Hello', }
html_string = render_to_string('myapp/report.html', context)
html = HTML(string=html_string)
buffer = io.BytesIO()
html.write_pdf(target=buffer)
pdf = buffer.getvalue()
email_message = EmailMultiAlternatives(
to=("youremailadress@gmail.com",),
subject="subject test print",
body="heres is the body",
)
filename = 'test.pdf'
mimetype_pdf = 'application/pdf'
email_message.attach(filename, pdf, mimetype_pdf)
email_message.send(fail_silently=False) # TODO zzz mabye change this to True