【问题标题】:django current page to pdfdjango 当前页面到 pdf
【发布时间】:2018-06-12 20:16:57
【问题描述】:

我正在尝试为当前页面(服务详细信息,这是一个动态页面)创建一个“转换为 pdf”按钮我尝试使用 ReportLab(正如 Django 文档所建议的那样,但我无法让它工作,并且 ReportLab 文档没有提及这种可能性)

现在我可以从这个视图中创建一个 pdf 文件:(编辑,为了清楚起见,回到 django 文档中的代码) 视图.py

        @login_required
    def service_detail(request, pk):
        service = get_object_or_404(Service, pk=pk)
        return render(request, 'detail.html', {'service':service, 'pk':pk})

    @login_required
    def render_to_pdf(request):
        # Create the HttpResponse object with the appropriate PDF headers.
        response = HttpResponse(content_type='application/pdf')
        response['Content-Disposition'] = 'attachment; filename="service.pdf"''

        # Create the PDF object, using the response object as its "file."
        p = canvas.Canvas(response)

        # Draw things on the PDF. Here's where the PDF generation happens.
        p.drawString("Hello world.")

        # Close the PDF object cleanly, and we're done.
        p.showPage()
        p.save()
        return response

urls.py

url(r'^service/(?P<pk>\d+)/$', views.service_detail, name='service_detail'), #Services details
url(r'^render_to_pdf/', views.render_to_pdf, name='render_to_pdf'),

服务详情的模板包括动态元素,例如:

Your location: {{ service.user_location }} <br><br>

任何人都知道我可以做什么,或者我可以使用什么其他技术来创建这样的 PDF?

我主要使用 Python、Django、HTML 和 CSS

【问题讨论】:

  • “我只是无法让它工作”是对您问题的完全无用的描述。请解释如何它“不起作用”。

标签: python django pdf


【解决方案1】:

content_type 必须是application/pdf 而不是service/pdf,也可以尝试给出不带空格的pdf文件名,例如service.pdf,来自docs,你也忘了把attachment放在Content-Disposition

尝试像这样将pdf写入response并使用BytesIO

from io import BytesIO 

@login_required
def render_to_pdf(request):
    response = HttpResponse(content_type='application/pdf')
    response['Content-Disposition'] = 'inline; filename="service.pdf'
    buffer = BytesIO()
    p = canvas.Canvas(buffer)

    # Start writing the PDF here
    p.drawString(100, 100, 'Hello world.')
    # End writing

    p.showPage()
    p.save()

    pdf = buffer.getvalue()
    buffer.close()
    response.write(pdf)

    return response

【讨论】:

  • 感谢您的意见! attachment 只是为了弹出一个窗口,我不一定需要。尤其是我无法比创建一个“hello world”pdf文件更进一步:(不幸的是,问题不在于那里。
  • @Mai 更新我的答案,尝试使用response.write(p),与BytesIO
  • 我仍然无法从当前页面创建 pdf。我的问题是我无法摆脱创造一个“你好世界”。当用户使用动态数据创建自己的服务时,手动创建每个 pdf 不是一种选择。该代码可以工作并创建一个 pdf,但我只能制作一个随机文本,我可以在“hello world”中写入一个随机文本。通过 ReportLab 文档并摆脱这些想法。也许是另一种技术(不是报告实验室,而是仅适用于当前动态页面视图的技术)
【解决方案2】:

您可能需要考虑使用包 django-wkhtmltopdf 在 Django 中生成 PDF。

使用它,您可以将 PDF 布局为 HTML 页面(带有 CSS 标记),就像任何其他视图一样,但它会将其呈现为 PDF 文件。请注意,您必须安装 wkhtmltopdf binary 才能使其正常工作。

通过在url中添加?as=html前缀,你可以在开发的同时在浏览器中查看你的页面。

django-wkhtmltopdf 包使用基于类的视图。举个例子:

views.py

from django.utils.text import slugify
from wkhtmltopdf.views import PDFTemplateView

class Portfolio(PDFTemplateView):
    template_name = 'frontend/portfolio.html'

    def get_filename(self):
        return slugify('portfolio ' + self.request.user.first_name + ' ' + self.request.user.last_name) + '.pdf'

    @method_decorator(login_required)
    def dispatch(self, *args, **kwargs):
        return super().dispatch(*args, **kwargs)

urls.py

from django.urls import path
from . import views

app_name = 'frontend'

urlpatterns = [
    path(
        '<slug:group_slug>/<int:school_year_pk>/portfolio/',
        views.Portfolio.as_view(),
        name='portfolio'
    ),
    ...

【讨论】:

  • 谢谢,如果有问题我会查看并回来的:)
猜你喜欢
  • 1970-01-01
  • 2010-10-19
  • 2015-09-05
  • 2020-09-11
  • 1970-01-01
  • 2019-08-04
  • 1970-01-01
  • 2015-10-07
  • 2012-10-25
相关资源
最近更新 更多