PDF-Erzeugung

Für die Erzeugung von PDF-Dokumenten gibt es verschiedene Möglichkeiten. Wir wollen die Bibliothek pisa nutzen, die ein html2pdf Konverter ist.

Installation der nötigen Pakete

Zuerst müssen alle nötigen Pakete installiert werden:

$ pip install pisa PIL html5lib httplib2 pyPdf reportlab

Zur Installation von PIL müssen unter Linux die folgenden Pakete installiert sein:

  • libjpeg62
  • liblcms1
  • python-dev

Für OS X muss man zum Beispiel mit Homebrew die Unterstützung für das JPG Format installieren:

$ brew install jpeg

Ein generischer View für PDFs

Dann schreibst du in cookbook/views.py: einen generischen View zum Erzeugen von PDF Dateien:

import cStringIO as StringIO

from django.http import HttpResponse
from django.views.generic import DetailView
import ho.pisa as pisa


class PDFView(DetailView):
    def render_to_pdf(self, html):
        pdf = StringIO.StringIO()
        pisa.CreatePDF(html, pdf, encoding='utf-8')
        pdf.seek(0)
        return pdf

    @property
    def filename(self):
        return getattr(self.get_object(), self.slug_field)

    def render_to_response(self, context, **response_kwargs):
        tpl = super(PDFView, self).render_to_response(context, **response_kwargs)
        tpl.render()
        pdf = self.render_to_pdf(tpl.rendered_content)
        response = HttpResponse(pdf, mimetype='application/pdf')
        response['Content-Disposition'] = 'attachment; filename=%s.pdf' % self.filename
        return response

Das PDF erzeugen

Jetzt fügst du den URL recipes_recipe_detail_pdf zu recipes/urls.py hinzu:

from .views import RecipeDetailView, RecipePDFView

urlpatterns += patterns('',
    url(r'^rezept/(?P<slug>[-\w]+)/$', RecipeDetailView.as_view(),
        name='recipes_recipe_detail'),
    url(r'^rezept/(?P<slug>[-\w]+)/pdf/$', RecipePDFView.as_view(),
        name='recipes_recipe_detail_pdf'),
    url(r'^$', RecipeListView.as_view(), name='recipes_recipe_index'),
)

Und nun erstellst mit Hilfe des generischen PDF Views eine View für die PDFs der Rezepte in recipes/views.py:

from utils import PDFView


class RecipePDFView(PDFView):
    model = Recipe
    template_name = 'recipes/detail_pdf.html'

Jetzt fehlt noch das HTML Template, dass die Vorlage für das PDF ist. Erstelle er hier recipes/templates/recipes/detail_pdf.html:

{% extends "base.html" %}

{% block title %}{{ block.super }} - {{ object.title }}{% endblock %}

{% block toggle_login %}{% endblock %}

{% block content %}
{% load recipes %}
<h2>{{ object.title }}</h2>
<p>Schwierigkeitsgrad: {{ object.get_difficulty_display }}</p>
<p>Ergibt {{ object.number_of_portions }}
    Portion{{ object.number_of_portions|pluralize:"en" }}.</p>
<h3>Zutaten</h3>
{{ object.ingredients|linebreaks }}
<h3>Zubereitung</h3>
{{ object.preparation|linebreaks }}
<p>Zubereitungszeit: {{ object.time_for_preparation }} Minuten</p>
<p>Autor: {{ object.author }}</p>
<h4>Kategorie{{ object.category.count|pluralize:"n" }}</h4>
<ul>
    {% for category in object.category.all %}
        <li>{{ category.name }}</li>
    {% endfor %}
</ul>
{% get_related_recipes object 5 as related_recipes %}
{% if related_recipes %}
<h4>Verwandte Rezepte</h4>
<ul>
{% for recipe in related_recipes %}
    <li>{{ recipe.title }}</li>
{% endfor %}
</ul>
{% endif %}
{% endblock %}

Und füge als letzten Schritt eine Link zum PDF in das Template für ein Rezept ein recipes/templates/recipes/detail.html:

<a href="{% url recipes_recipe_detail_pdf object.slug %}">Rezept als PDF herunterladen</a>

Jetzt kannst du das Rezept auch als PDF ansehen.

Inhalt

Vorheriges Thema

Ein RSS Feed für die “News” App

Nächstes Thema

RESTful Webservice

Diese Seite