miércoles, 5 de diciembre de 2018

Generar PDF con DJango 2.1 (Vertical y Horizontal - Portrait y Landscape)

#django #pdf #generate #reportlab #Portrait #letter #landscape #articulo #free #class

Para generar pdf con Django, debemos instalar el paquete ReportLab 


 pip install reportlab  

ReportLab sólo tiene una dependencia llamada Pillow.  Si tienes problemas con la instalación de ReportLab, trata primero de instalar el Pillow.

En la siguiente imange puedes ver cómo instalo reportlab y pillow de manera offline.

Una vez instalado, ya podemos trabajar en nuestro proyecto, para esto crearemos una vista de tipo función de la siguiente forma:

 def categoria_print(self, pk=None):  
   import io  
   from reportlab.platypus import SimpleDocTemplate, Paragraph, TableStyle  
   from reportlab.lib.styles import getSampleStyleSheet  
   from reportlab.lib import colors  
   from reportlab.lib.pagesizes import letter  
   from reportlab.platypus import Table  
   
   response = HttpResponse(content_type='application/pdf')  
   buff = io.BytesIO()  
   doc = SimpleDocTemplate(buff,  
               pagesize=letter,  
               rightMargin=40,  
               leftMargin=40,  
               topMargin=60,  
               bottomMargin=18,  
               )  
   categorias = []  
   styles = getSampleStyleSheet()  
   header = Paragraph("Listado de Categorías", styles['Heading1'])  
   categorias.append(header)  
   headings = ('Id', 'Descrición', 'Activo', 'Creación')  
   if not pk:  
     todascategorias = [(p.id, p.descripcion, p.activo, p.creado)  
               for p in Categoria.objects.all().order_by('pk')]  
   else:  
     todascategorias = [(p.id, p.descripcion, p.activo, p.creado)  
               for p in Categoria.objects.filter(id=pk)]   
   t = Table([headings] + todascategorias)  
   t.setStyle(TableStyle(  
     [  
       ('GRID', (0, 0), (3, -1), 1, colors.dodgerblue),  
       ('LINEBELOW', (0, 0), (-1, 0), 2, colors.darkblue),  
       ('BACKGROUND', (0, 0), (-1, 0), colors.dodgerblue)  
     ]  
   ))  
   
   categorias.append(t)  
   doc.build(categorias)  
   response.write(buff.getvalue())  
   buff.close()  
   return response  


En este caso, las importaciones de las dependencias las hice dentro de la función ya que no requeriré en otro lado de dichas importaciones, pero en tu caso, puedes hacerlo de manera global para todas las funciones.

Esta vista imprime las categorías de un determinado producto (parte de lo que imparte en el curso de Desarrollo Web con Python usando Django 2.1) puede recibir el id de la categoría o no.  Si lo recibe imprime ese único registro, sino lo recibe imprime todos los registros.

En este caso:
  • Se genera documento de tamaño carta (verticual o portrait)
  • Se crea variable vacía
  • Se agrega título "Listado de Categorías"
  • Se agrega el título
  • Se agregan encabezado para la tabla a mostrar (Id, Descripción, Activo y Creación).
  • Si a la vista no se le pasa el Id,  filtra de las categorías todos los registros, si se pasa el Id, únicamente filtra el registro que cumpla con el Id dado.
  • Se genera una tabla con encabezado y el resultado del filtro anterior.
  • Se le d formato a la tabla
  • Se agrega tabla
  • Se construye el documento
  • Impresión a la salida
  • Cerrar buffer
  • Devolver response
Luego se debe agregar la ruta que responda a la vista. Una vez importada la vista anterior, se procede a agregar una ruta para que imprima todos los registros (no se le envía id) y la otra que imprima un único registro (se envía Id):

 path('categorias/print', categoria_print, name='categoria_print'),  
 path('categorias/print/<int:pk>', categoria_print, name='categoria_print_one'),  

Ya sólo falta poner la url en un botón para que se imprima, en este caso (basándonos en el curso), el botón imprimir (todos los registros), se puso en la parte superior y el botón imprimr un registro, se agregó en una columna donde están los botones, según se muestra en la siguiente imagen.


El código para cada uno es:
Imprimir todo:

 <a href="{% url 'catalogos:categoria_print' %}" class="btn btn-warning" target="print"><span class="fa fa-print"></span> Imprimir</a>  

Imprimir un único registro, se toma en cuenta que se está recorriendo por medio de la variable item.

 <a href="{% url 'catalogos:categoria_print_one' item.id %}" target="print" class="btn btn-default btn-circle">  
    <span class="fa fa-print"></span>  
 </a>  

Generando la salida, respectivamente imprimir todo y un registro:


Para imprimir en forma horizontal (LandScape), sólo se debe hacer los siguientes cambios.


Básicamente es importar el tamaño landscape y luego al armar el documento, indicarle que el tamaño es carta pero con orientación horizontal (landscape)


Espero que te sea de utilidad este artículo.  Si deseas estar pendiente de las demás actualizaciones, ya sea de artículos y/o descuento de los cursos, puedes registrarte en el siguiente formulario:





2 comentarios:

  1. Viejo,..por favor, cambia el fondo del area donde esta escrito el codigo. negro sobre gris..uuuufff!! como se te ocurrio semejante fondo,...es del terror

    ResponderBorrar
  2. Amigo como estas Dios te Bendiga, amigo necesito hacer una constancia de estudio y la quiero hacer en reportlab ayudame hacerla necesito entregarla urgentemente

    ResponderBorrar

¿Tienes algún comentario? ¿Qué te ha parecido este artículo? Cuéntalo.

 
>