Quem sou eu

Minha foto

Formado em Computação, desenvolvedor web, interessado em tecnologia, metaleiro e um gamer inveterado.

Pesquisar

sexta-feira, 19 de abril de 2013

Gerando um PDF para download ou arquivo a partir de um Template em Django

Você vai precisar dos seguintes aplicativos instalados no ENV:

  • html5lib==0.95
  • pisa==3.0.33
  • reportlab==2.7

Crie um arquivo chamado report.py na raiz do seu projeto com o conteúdo abaixo:
# -*- coding: utf-8 -*-
from django import http
from django.conf import settings
from django.http import HttpResponse
from django.template import Context
from django.template import RequestContext
from django.template.loader import get_template
from django.template.loader import render_to_string
import cgi, os
import cStringIO as StringIO
import ho.pisa as pisa

def fetch_resources(uri, rel):
    path = os.path.join(settings.STATIC_PATH, uri.replace(settings.MEDIA_URL, ""))
    return path

def write_to_pdf(template_src, context_dict, filename):
    template = get_template(template_src)
    context = Context(context_dict)
    html  = template.render(context)
    result = StringIO.StringIO()
    pdf = pisa.pisaDocument(StringIO.StringIO(html.encode("UTF-8")), result, link_callback=fetch_resources)
    if not pdf.err:
        response = http.HttpResponse(mimetype='application/pdf')
        response['Content-Disposition'] = 'attachment; filename=%s.pdf' % filename
        response.write(result.getvalue())

        # OPCIONAL, CASO QUEIRA GERAR O ARQUIVO EM DISCO
        f = open('%s/uploads/projetos/%s.pdf' % (settings.MEDIA_ROOT, filename), 'w+')
        f.write(result.getvalue())
        f.close()


        return response

    return http.HttpResponse('Problema ao gerar PDF: %s' % cgi.escape(html))

Crie a view que será responsável pela chamada da geração do PDF:
from app.report import write_to_pdf

def projeto2pdf(request, slug=None):
    projeto = get_object_or_404(Projeto, slug=slug)
    response = write_to_pdf('template_pdf.html', {'projeto': projeto}, projeto.slug)
    return response

Caso seu template possua alguma imagem, lembre-se de colocar nos src das tags img apenas o caminho a partir do caminho definido na def fetch_resorces do arquivo report.py

...
<img src="site/img/sua_imagem.png" alt="imagem" width="176" height="103">
...

Agora basta criar a url para a chamada da view:
...
url(r'^projeto2pdf/(?P<slug>[-\w]+)/$', 'projeto2pdf', name='projeto2pdf'),
...

hasta!