【问题标题】:Creating PDFs with django (wkhtmltopdf)使用 django 创建 PDF (wkhtmltopdf)
【发布时间】:2013-08-14 13:11:18
【问题描述】:

有人可以为我提供一个全面的示例,说明如何使用wkhtmltopdfdjango 中获取view 以返回PDFdjango-wkhtmltopdf 附带的示例数量有限,并且他们假定我没有的知识水平。我已经查看了源代码,但我不知道如何使用它(例如 PDFTemplateViewPDFTemplateResponse 之间有什么区别?!?)

如果有任何帮助,我将不胜感激。

顺便说一句(我也在为页眉和页脚使用模板)

编辑

def some_view(request,sID):
    something = get_object_or_404(Something,id=sID)
    return render_to_response('something.html', {'something':something}, context_instance=RequestContext(request))

如何获得以下简单视图来为我提供pdf 而不是html 文件?

编辑 2

我目前正在玩:

def pdf_view(request,sID):
    template = 'pdf.html'
    something = get_object_or_404(Something,id=sID)
    context = {
        'something' : Something,
        'object_for_header_and_footer': something.object_for_header_and_footer,
    }
    cmd_options = settings.WKHTMLTOPDF_CMD_OPTIONS

    return PDFTemplateResponse(request=request,
        context=context,
        template=template,
        filename='something',
        header_template='header.html',
        footer_template='footer.html',
        cmd_options=cmd_options)

但我在/usr/local/lib/python2.7/dist-packages/wkhtmltopdf/utils.py in wkhtmltopdf, line 74 中得到'str' object has no attribute 'update'。不知道要不要开始hack wkhtmltopdf?!?!

【问题讨论】:

  • 普通视图和 PDFTemplateResponse 对我有用。我没有指定 WKHTMLTOPDF_CMD_OPTIONS。

标签: django wkhtmltopdf


【解决方案1】:

PDFTemplateView 和 PDFTemplateResponse 的区别在于视图是基于类的视图。而 PDFTemplateResponse 渲染 pdf 数据并设置正确的response headers。添加页眉和页脚:

# urls.py

from django.conf.urls.defaults import *
from wkhtmltopdf.views import PDFTemplateView


    urlpatterns = patterns('',
        ...
        url(r'^pdf/$', PDFTemplateView.as_view(template_name='my_template.html',
                filename='my_pdf.pdf', 
                header_template='my_header_template.html', 
                footer_template='my_footer_template.html', 
                ...
                ), name='pdf'),
    )

在浏览器中打开 pdf/ 将开始下载基于 my_template.html、my_header_template.html 和 my_footer_template.html 的 my_pdf.pdf。

advanced example 展示了如何继承 PDFTemplateView 扩展和更改 PDFTemplateView 的逻辑。要了解会发生什么,请阅读Using class based views

header_templatefooter_template 一样,您可以定义response_class。因为 PDFTemplateResponse 是默认的,所以您不必定义它。

编辑

以下简单视图为您提供 pdf 而不是 html。这不是使用 django-wkhtmltopdf。您可以在 html2pdf 函数中使用 wkhtmltopdf。

def some_view(request):
    t = loader.get_template('myapp/template.html')
    c = RequestContext(request, {'foo': 'bar'})
    html = t.render(c)
    pdf_data = html2pdf(html) # Your favorite html2pdf generator
    response = HttpResponse(pdf_data, content_type='application/pdf')
    response['Content-Disposition'] = 'attachment; filename="some_filename.pdf"'
    return response

编辑 2

带有上下文的简单视图:

模板.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Untitled</title>
</head>
<body>
    <h1>{{ title }}</h1>
</body>
</html>

urls.py

from views import MyPDFView

urlpatterns = patterns('',
    (r'^pdf/', MyPDFView.as_view()),
)

views.py

from django.views.generic.base import View
from wkhtmltopdf.views import PDFTemplateResponse

class MyPDFView(View):
    template='template.html'
    context= {'title': 'Hello World!'}

    def get(self, request):
        response = PDFTemplateResponse(request=request,
                                       template=self.template,
                                       filename="hello.pdf",
                                       context= self.context,
                                       show_content_in_browser=False,
                                       cmd_options={'margin-top': 50,},
                                       )
        return response

编辑 3

如果使用 DetailView,可以将对象添加到上下文中:

url(r'^books/(?P<pk>\d+)/$', MyPDFView.as_view(), name='book-detail'),


class MyPDFView(DetailView):
    template='pdftestapp/template.html'    
    context= {'title': 'Hello World!'}
    model = Book

    def get(self, request, *args, **kwargs):        
        self.context['book'] = self.get_object()

        response=PDFTemplateResponse(request=request,
                                     template=self.template,
                                     filename ="hello.pdf",
                                     context=self.context,
                                     show_content_in_browser=False,
                                     cmd_options={'margin-top': 50,}
                                     )
        return response

【讨论】:

  • 渲染静态.html(我猜)没问题,但是如果您希望def something.views.something_view(request,someID) 渲染pdf 而不是html,会发生什么?
  • (& 在旁注中,为什么静态 *.html 文件被传递给其中包含 template 的属性。这没有意义?!?当然,如果属性中有 template它要求view。不是吗?!?)
  • 感觉有点像User.objects.filter(clue__lt=0)
  • 我同意,通过视图来呈现 pdf 会很好。你可以在他们的 GitHub 页面上打开一个问题。
  • 添加了一个返回 pdf 的简单视图。
【解决方案2】:

嗯,该错误表明您将字符串传递到您不应该传递的地方。

在检查了它的source code 之后,我猜在settings.py 你有WKHTMLTOPDF_CMD_OPTIONS 作为一个字符串,类似于

WKHTMLTOPDF_CMD_OPTIONS = 'some_option_here'

但你应该在那里分配一个字典:

WKHTMLTOPDF_CMD_OPTIONS = {
    'quiet': True,
}

否则您的代码应该可以正常工作。

【讨论】:

    猜你喜欢
    • 2014-01-06
    • 2013-12-25
    • 2014-07-27
    • 1970-01-01
    • 1970-01-01
    • 2011-10-20
    • 1970-01-01
    • 2019-07-10
    • 1970-01-01
    相关资源
    最近更新 更多