Generacion de Reportes Profesionales Con Python
Generacion de Reportes Profesionales Con Python
02.12.2005
11:12
Uhr
Pgina
57
REPORTLAB
Hoy en da se hace imprescindible disponer de herramientas que permitan generar informes en PDF de alta calidad rpida y dinmicamente. Existen diferentes herramientas para esta finalidad, entre ellas cabe destacar ReportLab, biblioteca gratuita que permite crear documentos PDF empleando como lenguaje de programacin Python. POR ANA M. FERREIRO Y JOSE A. GARCA
a biblioteca ReportLab crea direchay que seguir para instalar y configurar tamente documentos PDF basnReportLab. dose en comandos grficos y sin El paquete pdfgen es el nivel ms bajo pasos intermedios, generando informes para generar documentos PDF, que se en un tiempo extremadabasa esencialmente en mente rpido y siendo de una secuencia de instrucgran utilidad en los ciones para dibujar siguientes contextos: cada pgina del docugeneracin dinmica de mento. El objeto que proPDFs en aplicaciones web porciona las operaciones (empleado con Zope), de dibujo es el Canvas. El generacin de informes y Canvas mide igual que publicacin de datos una hoja de papel blanalmacenados en bases de co, con puntos sobre la datos, embebiendo el misma identificados motor de impresin en mediante coordenadas aplicaciones para consecartesianas (X,Y), que guir la generacin de Figura 1: Coordenadas cartepor defecto tienen el oriinformes a medida, etc. sianas de una hoja. gen (0,0) en la esquina inferior izquierda de la Primeros pasos pgina. La coordenada X va hacia la Lo primero es tener instalados Python y derecha y la coordenada Y avanza hacia ReportLab para realizar todas las pruearriba (ver Figura 1). bas que van surgiendo y las que se nos Para crear nuestro primer PDF basta ocurran. En [1] se detallan los pasos que escribir en un fichero, que podemos lla-
Probamos el programa y vemos que en el mismo directorio ya se ha creado un fichero llamado primer.pdf, anlogo al que se muestra en la Figura 2, sin necesidad de realizar ningn otro paso intermedio. Mediante la lnea from reportlab.pdfgen import canvas importamos Canvas, utilizado para dibujar en el PDF. El comando
WWW.LINUX- MAGAZINE.ES
Nmero 13
57
057-060_PDFRepL13
02.12.2005
11:12
Uhr
Pgina
58
canvas.Canvas(path__fichero) permite indicar el nombre con el que se guardar el PDF. El mtodo drawString(x,y,cadena_texto) empieza a escribir el texto en la coordenada (x,y) (se puede probar a cambiar las diferentes coordenadas). El mtodo showPage() crea la pgina actual del documento. Finalmente, save() guarda el fichero en el path indicado. En el ejemplo previo hemos creado un PDF sin especificar el tamao del documento, si queremos fijar el tamao de la hoja (A4, letter, A5, etc.) bastara indicarlo en el Canvas mediante:
from reportlab.lib.U pagesizes import letter,A4,A5,U A3 c=canvas.Canvas("primer.pdf",U pagesize=letter)
Listado 1: ejemplo2.py
01 from reportlab.pdfgen import canvas 02 c=canvas.Canvas("canvas_draw.p df") 03 c.setFont("Helvetica",24) 04 c.line(50,50,50,350) 05 c.line(50,50,350,50) 06 c.setStrokeColorRGB(1,1,0.0) 07 c.setFillColorRGB(0,0.0,0.5) 08 c.roundRect(75,75,275,275,20,s troke=0, fill=1) 09 c.setFillColorRGB(0.8,0.,0.2) 10 c.circle(205,205,100,stroke=1,fill=1) 11 c.setFillColorRGB(0.75,0.75,0. ) 12 c.drawString(125,80,"Cuadrado" ) 13 c.setFillColorRGB(0,1,0.2) 14 c.drawString(155,200,"Circulo" ) 15 c.setStrokeColorRGB(1,0,0.0) 16 c.ellipse(75,450,350,335,fill= 0) 17 c.setFillColorRGB(0,0,0.5) 18 c.drawString(150,375,"Elipse") 19 c.showPage() 20 c.save()
El tamao de las hojas se importa mediante from reportlab.lib.pagesizes import letter,A4,A5,A, y se especifica en el Canvas con la propiedad pagesize. Muchas veces querremos adaptar el dibujo a las dimensiones de la hoja, por lo que necesitamos conocer el ancho y el alto de la misma: ancho=tipo_hoja[0] y alto=tipo_hoja[1]; donde tipo_hoja puede ser letter, Figura 2: Primer documento generado. El resultado impreso A4, A5 , etc. refleja cmo controlar las coordenadas de una hoja. La clase Canvas dispone de diferentes herramientas para dibutipo de fuente se realiza usando jar lneas, circunferencias, rectngulos, canvas.SetFont(tipo_fuente,tamao). En arcos, etc. Adems permite modificar el la Figura 3 se muestra el PDF que creacolor de los objetos, rotar, trasladar, indimos con el simple cdigo del Listado 1. car tipo y tamao de fuente, etc. En el Podemos probar a cambiar propiedades cdigo del Listado 1 podemos ver cmo (en el manual de ReportLab encontrarese dibujan, por ejemplo lneas, mos muchas otras). mediante canvas.line(x1,y1,x2,y2); crAadiendo imgenes culos, empleando el mtodo canvas.cirEn este instante ya podemos demostrar cle(x_centro,y_centro,radio,stroke=1,fill nuestra creatividad en dibujo artstico, =1); y rectngulos con esquinas redonaunque de un modo bastante laborioso. deadas, Seguro que ms de uno preferimos canvas.roundRect(x,y,ancho,alto,anguincluir en nuestros ficheros imgenes ya lo,stroke=1,fill=0). Ntese que cada creadas. Pues esto es posible: en el rea vez que se quiera emplear un color de descarga de Linux Magazine tenemos nuevo hay que indicarlo mediante la imagen Tux2.png para las diferentes canvas.setFillColorRGB(r,g,b), para el color de relleno, o pruebas. canvas.setStrokeColorRGB(r,g,b), para A la hora de incluir imgenes podemos fijar el color de las lneas. La eleccin del optar por las siguientes opciones. La pri-
58
Nmero 13
WWW.LINUX- MAGAZINE.ES
057-060_PDFRepL13
02.12.2005
11:12
Uhr
Pgina
59
Figura 4: drawImage.
Colocando
imgenes
mera y ms sencilla, pero con la que no nos es posible rotar, trasladar, ni redimensionar es mediante el mtodo drawImage(image,x,y,width=None,heig ht=None) de la clase Canvas (si no se especifica el alto y el ancho, coloca la figura con sus dimensiones originales). Mediante las siguientes lneas podemos crear un fichero similar al de la Figura 4.
c.drawImage("Tux2.png",0,0)
c.drawImage("Tux2,png",200,300,U width=30,height=60)
Si lo que pretendemos es rotar imgenes o escalarlas, debemos emplear los objetos Image(x,y,ancho,alto,path_imagen) y Drawing(ancho,alto) que se importan mediante from reportlab.graphics.shapes import Image, Drawing. El objeto Drawing puede escalarse, rotarse y trasladarse; pero hay que tener en cuenta que todas estas operaciones son acumulativas (ver Figura 5). En el Listado 2 podemos ver cmo emplear correctamente estos objetos (Figura 6). Obsrvese que ahora el PDF no se genera a partir de un Canvas, sino que se genera mediante renderPDF.drawToFile(d,"canvas_image2.pdf"), donde d=Drawing(A4[0],A4[1]). Podemos probar a modificar los valores de los distintos mtodos scale, rotate, translate; observaremos que a veces la imagen puede desaparecer del folio, eso es debido a que los valores que se dan hacen que nos salgamos de las dimensiones de la pgina.
los espacios en blanco innecesarios; bulletText indica si el prrafo se escribe con un punto al inicio del mismo; la fuente y otras propiedades del prrafo y el punto se indican mediante el argumento style. Veamos cmo aadir un prrafo:
01 fr om repor tlab.lib.styles import getSampleStyleSheet 02 styleSheet=getSampleStyleShee t() 03 story=[] 04 h1=styleSheet['Heading1'] 05 h1.pageBreakBefore=0 06 h1.keepWithNext=1 07 h1.backColor=colors.red 08 P1=Paragraph("Estilo Cabecera - h1 ",h1) 09 story.append(P) 10 style=styleSheet['BodyText'] 11 P2=Paragraph("Estilo BodyText" ,style) 12 story.append(P2)
El paquete reportlab.lib.styles contiene estilos predefinidos. Con getSampleStyleSheet obtenemos un estilo ejemplo. Tenemos un estilo para la cabecera y otro para el texto normal. Mediante h1.pageBreakBefore=0 decimos que no queremos un salto de pgina cada vez que se escriba una cabecera h1, en caso contrario basta escribir 1. Los diferentes prrafos se van almacenando en la lista story porque posteriormente se aaden al pdf a travs el paquete SimpleDocTemplate de reportlab.platypus:
WWW.LINUX- MAGAZINE.ES
Nmero 13
59
057-060_PDFRepL13
02.12.2005
11:12
Uhr
Pgina
60
tener un texto muy largo. Si aadimos un prrafo cuyo texto sea "Hola"*300, seguro que se generan ms de una hoja. Si lo que queremos es aadir una tabla, es necesario importar from reportlab.platypus import Table,TablsStyle. Una tabla se crea aadiendo una lista de listas, donde cada componente de la lista guarda la informacin de cada fila. Si queremos construir una tabla de 5 filas y 3 columnas hacemos
t=Table([['','Ventas',U 'Compras'],U ['Enero',1000, 2000],U
En una tabla se puede fijar el estilo de cada miembro de la misma. Si por ejemplo, se quiere que el texto de la primera columna sea azul, y que los nmeros sean todos verdes, haremos
t.setStyle([U ('TEXTCOLOR',(0,1),(0,-1),U colors.blue), ('TEXTCOLOR',U (1,1), (2,-1),colors.green)])
En el cdigo del Listado 3 mostramos un ejemplo en l se ilustra cmo adaptar el estilo segn se quiera (Figura 7). Podemos ver que para incluir un nuevo elemento en el PDF es suficiente con ir aadiendo cada objeto a la lista story. Ahora ya sabemos todo lo necesario para crear nuestros propios carteles, inforI mes, catlogos, presentaciones, etc.
En este caso, se genera un PDF con tantas pginas como sea necesario. Comprobar esto es tan sencillo como
RECURSOS
[1] Reportlab: http://www.reportlab.org
60
Nmero 13
WWW.LINUX- MAGAZINE.ES