django 有没有方法用wkhtmltopdf创建PDF文件而不返回HttpResponse或使用URL?我只想将PDF文件附加到电子邮件中

nle07wnf  于 2022-12-24  发布在  Go
关注(0)|答案(6)|浏览(134)

我在Django 1.6中使用wkhtmltopdf Package 器将模板生成为PDF。当我想在之后显示PDF或使用HttpResponse发送PDF文件以供下载时,它工作正常,但我想做的是在我的tmp文件夹中创建文件并将其附加到电子邮件中。
我不知道如何做到这一点。

# views.py

context = {
    'products_dict': products_dict,
    'main_categories': main_categories,
    'user_category': user_category
}

response = PDFTemplateResponse(request=request,
                               context=context,
                               template="my_template.html",
                               filename="filename.pdf",
                               show_content_in_browser=True,
                               cmd_options={'encoding': 'utf8',
                                            'quiet': True,
                                            'orientation': 'landscape',
                                           }
                               )

return response

上面的代码生成的PDF正是我想要的。事情是我不想在浏览器中显示PDF或开始下载(我不想返回响应)。我只想创建它,然后将文件附加到电子邮件,像这样:

email = EmailMessage()
email.subject = "subject"
email.body = "Your PDF"
email.from_email = "sender@gmail.com"
email.to = [ "receiver@gmail.com", ]

# Attach PDF file to the email
email.attach_file(my_pdf_file_here)
# Send email
email.send()

我尝试使用子进程,但它似乎不像我可以发送上下文到我的模板来呈现它之前生成的PDF。

carvr3hs

carvr3hs1#

问题不在于wkhtmltopdf,而在于django-wkhtmltopdf提供了一些基于类的视图,如果你不需要这些视图,你就不需要使用它们:您可以自己呈现模板并将结果字符串传递给命令行wkhtmltopdf工具。
看起来django-wkhtmltopdf库确实提供了一些实用函数(在utils目录中),这可能会使最后一步变得更容易。

6mw9ycah

6mw9ycah2#

我的工作

这里的问题是,当发送带有pdf文件附件的邮件时,email.attach需要类似字节的对象,但是我们有pdftemplate响应对象。
我试着用几种方法把它转换成字节,但是都出错了。所以,我只是随机地进入了PDFTemplateResponse类的定义,然后我在里面找到了rendered_content方法,多亏了vs代码让它变得更容易。
然后我刚刚做的是写下面的一行,它的工作!
第一个月
这是我第一次发表关于堆栈溢出的文章。所以,请原谅我的错误。

mw3dktmi

mw3dktmi3#

感谢Daniel Roseman for the help to go towards what I wanted,我确实在这里使用了wkhtmltopdf的测试文件:http://pydoc.net/Python/django-wkhtmltopdf/1.1/wkhtmltopdf.tests.tests/
这是我在我的观点中所做的:

order = Order.objects.get(id=order_id)
return_file = "tmp/" + 'order' + str(order_id) + '.pdf'

context = {
    'order' : order,
    'items' : order.ordered_products.all()
}

response = PDFTemplateResponse(
    request=request, 
    context=context, 
    template="'products/order_pdf.html'",
    cmd_options={
        'encoding': 'utf8',
        'quiet': True
    }
)

temp_file = response.render_to_temporary_file("products/order_pdf.html")

wkhtmltopdf(pages=[temp_file.name], output=return_file)

然后可以像这样在email.attach()方法中使用return_file:

email.attach_file(return_file)

也可以在wkhtmltopdf方法中省略output参数,然后该方法将返回输出,并在attach_file()方法中使用该输出。
此答案以edit的形式发布到以下问题:有没有方法在不返回HttpResponse或使用URL的情况下使用wkhtmltopdf创建PDF文件?我只想通过CC BY-SA 3.0下的OP dguay将PDF文件附加到电子邮件中。

h79rfbju

h79rfbju4#

answer provided已经过时了,因为render_to_temporary_file不再是PDFTemplateResponse的方法。
我还没有尝试通过电子邮件发送PDF,但是要将生成的PDF保存到Django模型的文件域,您可以按照以下步骤操作:

from wkhtmltopdf.views import PDFTemplateResponse
from io import BytesIO
from django.core.files import File
from django.http import HttpRequest
    
request = HttpRequest()

context = {
   'order' : order,
   'items' : order.ordered_products.all()
}

response = PDFTemplateResponse(
    request=request, 
    context=context, 
    template="products/order_pdf.html",
    cmd_options={
        'encoding': 'utf8',
        'quiet': True
    }
)
    
my_model.pdf_field.save(
        response.filename, File(BytesIO(response.rendered_content)))

它应该很容易从那里电子邮件的PDF。

rpppsulh

rpppsulh5#

嘿,请检查您的wkhtmltopdf二进制文件是可执行的或没有。因为这个PDFTemplateResponse为我工作。

ljo96ir5

ljo96ir56#

response = PDFTemplateResponse(
    request,
    template='reports/report_email.html',
    filename='weekly_report.pdf',
    context=render_data,
    cmd_options={'load-error-handling': 'ignore'})


subject, from_email, to = 'reports', 'digu35@gmail.com', 'digu35@gmail.com'
html_content = render_to_string('reports/report_email.html',render_data)
text_content = strip_tags(html_content)
msg = EmailMultiAlternatives(subject, text_content, from_email, [to])
msg.attach_alternative(html_content, "text/html")
msg.attach('pdf_filename.pdf', response.rendered_content, 'application/pdf')
msg.send()

这个代码片段放在views.py中后可能会对您有所帮助。

相关问题