how to show a Reportlab report in the browser?

1

I am new with reportlab, the problem I have is that despite being able to create reports with reportlab, I have only been able to save them in the root folder of my project, but when I upload it to a test server I get this error:

Error and Traceback

IOError at /PHVA/pdfJornadas
[Errno 13] Permission denied: u'Reporte Jornadas de Trabajo Cliente 1 S.A.S.pdf'
Request Method: GET
Request URL:    http://cliente1.mydomain.com/PHVA/pdfJornadas
Django Version: 1.6.5
Exception Type: IOError
Exception Value:    
[Errno 13] Permission denied: u'Reporte Jornadas de Trabajo Cliente 1 S.A.S.pdf'
Exception Location: /usr/local/lib/python2.7/dist-packages/reportlab/pdfbase/pdfdoc.py in SaveToFile, line 218
Python Executable:  /usr/bin/python
Python Version: 2.7.6
Python Path:    
['/usr/lib/python2.7',
 '/usr/lib/python2.7/plat-x86_64-linux-gnu',
 '/usr/lib/python2.7/lib-tk',
 '/usr/lib/python2.7/lib-old',
 '/usr/lib/python2.7/lib-dynload',
 '/usr/local/lib/python2.7/dist-packages',
 '/usr/lib/python2.7/dist-packages',
 '/var/www/html/cliente1/my_project']
Server time:    Jue, 10 Mar 2016 09:46:10 -0500  


Traceback Switch to copy-and-paste view

/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py in get_response
                    response = wrapped_callback(request, *callback_args, **callback_kwargs) ...
/var/www/html/cliente1/my_project/phva/views/reportes.py in exportarJornadasTrabajo
    doc.build(Story) ...
/usr/local/lib/python2.7/dist-packages/reportlab/platypus/doctemplate.py in build
        BaseDocTemplate.build(self,flowables, canvasmaker=canvasmaker) ...
/usr/local/lib/python2.7/dist-packages/reportlab/platypus/doctemplate.py in build
        self._endBuild() ...
/usr/local/lib/python2.7/dist-packages/reportlab/platypus/doctemplate.py in _endBuild
        if getattr(self,'_doSave',1): self.canv.save() ...
/usr/local/lib/python2.7/dist-packages/reportlab/pdfgen/canvas.py in save
        self._doc.SaveToFile(self._filename, self) ...
/usr/local/lib/python2.7/dist-packages/reportlab/pdfbase/pdfdoc.py in SaveToFile
            f = open(filename, "wb") ...

part of my views (Updated)

# -*- encoding: utf-8 -*-
from datetime import timedelta, date, datetime

from django.contrib.auth.decorators import login_required
from django.http import HttpResponse

#from reportlab.pdfgen import canvas
from reportlab.lib import colors
from reportlab.lib.units import cm
from reportlab.lib.enums import TA_JUSTIFY, TA_CENTER
from reportlab.lib.pagesizes import letter, landscape
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, Image

from phva.forms import *
from matriz_legal.models import *
from gestion_riesgos.models import *
from capacitaciones.models import MatrizFormacion
from ripso.utilities import *

def exportarJornadasTrabajo(request):
    empresa=PlanearEmpresa.objects.all()[0]
    title = "Reporte Jornadas de Trabajo "+empresa.razon_social
    filename = title+".pdf"
    # Creamos el response
    response = HttpResponse(content_type='application/pdf')
    response['Content-Disposition'] = 'attachment; filename="%s"' % filename
    # Usando el response en lugar del filename
    doc = SimpleDocTemplate(response,pagesize=letter, rightMargin=72,leftMargin=72, topMargin=72,bottomMargin=18)
    Story=[]

    #...

    #Jornadas
    jornadas=PlanearJornadaTrabajo.objects.all().order_by('grupo')

    if jornadas:
        datos_jorn=[]
        datos_jorn.append(['Grupo', 'Nombre', 'Horario'])
        for i in jornadas:
            datos_jorn.append([i.get_grupo_display(), Paragraph(i.nombre, styles['Justify']), Paragraph(i.horario, styles['Justify'])])
        t=Table(datos_jorn, colWidths=(4*cm, 4*cm, 8*cm))
        t.setStyle(TableStyle([('BACKGROUND',(0,0),(-1,0),colors.gray),
                               ('GRID', (0,1), (-1,-1), 0.25, colors.gray)]))
        Story.append(t)
        Story.append(Spacer(1, 12))
    else:
        p=ParagraphStyle('test')
        ptext = '<font size=12>No se encuentran datos disponibles registrados.</font>'
        Story.append(Paragraph(ptext, p))
        Story.append(Spacer(1, 12))

    #...

    doc.build(Story)
    return response

Updated

The views method is executing me 2 times when I change it to return response

    
asked by Diana Carolina Hernandez 10.03.2016 в 15:03
source

2 answers

2

If what you want is to send the information flow of the PDF to the client for download, what you have to do is return a HttpResponse .

Example:

from django.http import HttpResponse

def exportarJornadasTrabajo(request):
    empresa = PlanearEmpresa.objects.all()[0]
    filename = "Reporte Jornadas de Trabajo %s.pdf" % empresa.razon_social
    # Creamos el response
    response = HttpResponse(content_type='application/pdf')
    response['Content-Disposition'] = 'attachment; filename="%s"' % filename
    # Observa que ahora en vez de usar el nombre del archivo usamos el response
    doc = SimpleDocTemplate(
        response,
        pagesize=letter, 
        rightMargin=72,
        leftMargin=72, 
        topMargin=72,
        bottomMargin=18
    )
    Story=[]
    # ...
    doc.build(Story) 
    # En vez de retornar un redirect retornamos el response
    return response
    
answered by 10.03.2016 / 16:13
source
0

I have something similar to what you ask,

This is my HTML code in a Django Template and I do a POST to a URL that receives the parameter that I sent here

<div class="cuerpo"> 
    <div class="container">
        <div class="panel panel-default" style="width: auto;">
            <div class="panel-heading">Reporte Stock Productos por Almacen</div>
            <div class="panel-body">
                <form class="form form-horizontal" id='contra' name='contra' method='post' action='http://localhost:8000/reportestockalmacen/'>
                    <div class="row">
                        <div class="form-group">
                            <label for="cmbalmacen" class="col-sm-2 col-md-2 col-lg-2 control-label">Almacen</label>
                            <div class="col-sm-8 col-md-8 col-lg-6">
                                 <select class="form-control" name="cmbalmacen" id="cmbalmacen" required style="width:50%">
                                </select>
                            </div>
                            <div class="col-sm-2 col-md-2 col-lg-4">

                            </div>
                        </div>
                    </div>

                     <div class="row">
                        <div class="form-group">
                            <div class="col-sm-offset-2 col-sm-10">
                                <button type="reset" class="btn btn-default">Cancelar</button>                                
                                <input type="submit" id="button" name="button" class="btn btn-primary"  value="Aceptar"/>
                            </div>
                        </div>
                    </div>                        

                </form>

            </div>
        </div>
    </div>

  </div>

and this would be my Python code, which also has to be added to the URL.

def ReporteStockAlmacen(request):

if request.method == 'POST':        

    try:

        response = HttpResponse(content_type='ReporteProductosAlamcen/pdf')
        response['Content-Disposition'] = 'attachment; filename="Reporte_Productos_Almacen.pdf"'

        almacen=request.POST['cmbalmacen']                      
        jsonfinal = Get_ProductosPorAlmacen(almacen)

        data2 = jsonfinal["almacen"]

        temp = StringIO()
        width, height = A4
        p = canvas.Canvas(temp,pagesize = A4)   
        xPos = 50
        yPos = 685
        aum = 15
        pie = 60
        fecha = timezone.now().strftime('%Y-%m-%d %H:%M:%S')

        p.setFont("Helvetica",8)
        p.drawString(230, 730, "STOCK DE PRODUCTOS")
        p.drawString(215, 715, "Reporte generado el  "+str(fecha))
        p.line(700, 700, 0, 700)#(HORIZONTAL,,HORIZONTAL,)
        p.drawString(xPos, yPos, "CODIGO")
        p.drawString(xPos+120, yPos, "PRODUCTO")
        p.drawString(xPos+360, yPos, "SERIE")

        p.line(700, yPos-5, 0, yPos-5)                          

        for almacen in data2:

            p.drawString(500, 715, almacen['nombrealmacen'])

            if(yPos <= pie):
                p.showPage()
                p.save()
                xPos = 50
                yPos = 780
                aum = 15    
            x=0

            for productos in almacen["productos"]:
                p.setFont("Helvetica",8)

                if x == 0:
                    p.drawString(xPos, yPos-aum,productos['codigoproducto'])
                    p.drawString(xPos+120, yPos-aum,productos['nombreproducto'])
                    p.drawString(xPos+360, yPos-aum,productos['serieproducto_almacens'])
                    yPos-=aum


                    p.setFont("Helvetica",8)
                    if(yPos <= pie):

                        p.showPage()
                        p.save()

                        xPos = 50                       
                        yPos = 780
                        aum = 15                

        p.showPage()
        p.save()
        response.write(temp.getvalue())


        return response
    except:
        HttpResponse({'exito':0})
    
answered by 15.03.2016 в 04:22