Mostrando postagens com marcador PDF. Mostrar todas as postagens
Mostrando postagens com marcador PDF. Mostrar todas as postagens

quinta-feira, 14 de agosto de 2014

Gerando um PDF em Django sem template e forçando seu donwload

Você vai precisar dos seguintes aplicativos instalados no ENV:
  • reportlab==2.7

Faça uma view conforme abaixo:

#############################################################
# PDF
#############################################################
class PDFView(View):

 def post(self, request, *args, **kwargs):
  # IMPORTS NECESSARIOS
  from reportlab.pdfgen import canvas
  from reportlab.lib.pagesizes import letter, landscape, A4
  from reportlab.lib.units import inch, cm
  from reportlab.lib.colors import HexColor
  from django.conf import settings
  import os

  # VALIDAÇÃO DO CSRF_TOKEN
  c = {}
  c.update(csrf(request))
  
  # NOME DO ARQUIVO
  nome_arquivo = "1.pdf"
  arquivo = '%s/uploads/%s' % (settings.MEDIA_ROOT, nome_arquivo)

  if os.path.isfile(arquivo):
   # REDIRECT CASO NÃO ENCONTRAR O ARQUIVO
   return redirect('/')

  imagem =  '%s/%s' % (settings.MEDIA_ROOT, "sua_imagem_aqui.jpg")

  # CRIAÇÃO DO PDF EM MODO PAISAGEM , TAMANHO A4
  c = canvas.Canvas(arquivo, pagesize=landscape(A4))
  c.drawImage(
   '%s' % imagem,
   0,
   0,
   29.7*cm,
   21*cm
  )

  # DEFINIÇÃO DE FONTE, FAMILIA, TAMANHO E COR
  c.setFont("Helvetica", 16)
  c.setFillColor(HexColor(0x094d8a))

  # ESCRITA DO TEXTO POR CIMA DA IMAGEM COM ALINHAMENTO
  c.drawString(18.4*cm, 14*cm, "%s" % participante.nome)

  # GERAÇÃO E CRIACAO DO PDF
  c.showPage()
  c.save()

  # REDIRECT PARA VIEW QUE FORCARÁ O DOWNLOAD
  return redirect('certificados:download',participante.id)

 def get(self, request, *args, **kwargs):
  return redirect('/')


#############################################################
# DOWNLOAD
#############################################################
class ForceDownload(View):
 def get(self, request, *args, **kwargs):
  from django.http import HttpResponse
  from os import path
  
  import mimetypes

  arquivo = '%s/uploads/%s.pdf' % (settings.MEDIA_ROOT, kwargs['pk'])

  if not (path.exists(arquivo)):
   raise Http404

  mimetype, encoding = mimetypes.guess_type(arquivo)

  if mimetype is None:
   mimetype = 'application/force-download'

  file = arquivo.split("/")[-1]

  response = HttpResponse(open(arquivo, 'r').read())
  response['Content-Type'] = mimetype
  response['Pragma'] = 'public'
  response['Expires'] = '0'
  response['Cache-Control'] = 'must-revalidate, post-check=0, pre-check=0'
  response['Content-Disposition'] = 'attachment; filename=%s' % file
  response['Content-Transfer-Encoding'] = 'binary'
  response['Content-Length'] = str(path.getsize(arquivo))
  return response # Create your views here.


E no urls deixe da seguinte forma:


# coding: utf-8
from django.conf.urls import patterns, include, url
from . import views

urlpatterns = patterns('',

 ############################################################################
 # DOWNLOADS
 ############################################################################
 url(r'^downloads/(?P<pk>\d+)/$', views.ForceDownload.as_view(), name='download'),

 ############################################################################
 # CERTIFICADO
 ############################################################################
 url(r'^(?P<slug>[-\w]+)/$', views.PDFView.as_view(), name='pdf_detail'),


)

hasta!

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!