Generar un PDF a partir de un sencillo formulario en PyQt
Generar PDF en Python |
La idea de esta entrada, como su titulo ya describe, es crear en QtDesigner(PyQt) un
sencillo formulario gráfico que generará un PDF con los datos ingresados por el usuario.
Algunos ejemplos de uso: Ingreso de un alumno a un curso, ingreso de un nuevo funcionario a una empresa, etc.
La idea es llenar el formulario, y una ves que se presione el botón PDF, se abra automáticamente el archivo Formulario.pdf con los datos que acabamos de llenar.
Si se analiza con profundidad el código, se podrían mejorar muchas cosas, como por ejemplo añadir excepciones de error y alguna cosa mas. Pero la idea principal de la entrada es ver de forma sencilla como crear un Formulario en python y generar un PDF para imprimir o guardar.
Estas pruebas fueron
realizadas en un sistema Linux (Ubuntu)
Fecha: 14/04/2015
algunas entradas sobre PyQt por si no estas familiarizado con el
tema:
- Como instalar PyQt4 en Windows, Linux y Mac OS
- Primera aplicación gráfica con QtDesigner y Python
- Aplicación gráfica con PyQt4 y Sqlite3
- Ejercicios gráficos de programación
- Combinar 2 combobox en PyQt-Python
- Diálogos en PyQt con qmessagebox-Python
Diseño en QtDesigner
Nombre que utilicé para los objetos en QtDesigener
- Para el Nombre = textNombre
- Para el Apellido = textApellido
- Para el Correo = textCorreo
- Para el Curso = textCurso
- Para el País = textPais
- Para las Observaciones = textObs
Código del Programa
#!/usr/bin/python # -*- coding: utf-8 -*- # Formulario que Genera PDF # www.pythondiario.com import sys import os from reportlab.pdfgen import canvas from PyQt4 import QtCore, QtGui, uic # Cargar nuestro archivo .ui form_class = uic.loadUiType("formularioPDF.ui")[0] class MyWindowClass(QtGui.QMainWindow, form_class): def __init__(self, parent=None): QtGui.QMainWindow.__init__(self, parent) self.setupUi(self) self.btn_pdf.clicked.connect(self.generarPDF) # Evento del boton btn_pdf def generarPDF(self): # Guardo en las variables los datos de los textEdit Ingresados por el Usuario self.nombre = str(self.textNombre.toPlainText()) self.apellido = str(self.textApellido.toPlainText()) self.correo = str(self.textCorreo.toPlainText()) self.curso = str(self.textCurso.toPlainText()) self.pais = str(self.textPais.toPlainText()) self.obs = str(self.textObs.toPlainText()) # Ruta donde quiero crear el PDF c = canvas.Canvas("/home/diego123/Escritorio/Formulario.pdf") c.drawString(100,750,"Este formulario fue creado en www.pythondiario.com") c.drawString(100,700,("Nombre: "+ self.nombre)) c.drawString(100,680,("Apellido: "+ self.apellido)) c.drawString(100,660,("Correo: "+ self.correo)) c.drawString(100,640,("Curso: "+ self.curso)) c.drawString(100,620,("Pais: "+ self.pais)) c.drawString(100,600,("Observaciones: "+ self.obs)) c.save() # PARA WINDOWS: os.system("start AcroRD32 ruta_y_archivo.pdf &") os.system("evince /home/diego123/Escritorio/Formulario.pdf &") if __name__ == "__main__": app = QtGui.QApplication(sys.argv) MyWindow = MyWindowClass(None) MyWindow.show() app.exec_()
Análisis del código
Importamos los módulos necesarios para trabajar:
import sys import os from reportlab.pdfgen import canvas from PyQt4 import QtCore, QtGui, uic
El módulo os será necesario para abrir el archivo.pdf una ves sea creado. También importamos el módulo reportlab para crear el archivo.pdf. Los otros módulos son necesarios para la aplicación gráfica.
Cargamos el archivo.ui de QtDesigner:
# Cargar nuestro archivo .ui form_class = uic.loadUiType("formularioPDF.ui")[0]
Creamos la clase MyWindowClass con su inicializador
class MyWindowClass(QtGui.QMainWindow, form_class): def __init__(self, parent=None): QtGui.QMainWindow.__init__(self, parent) self.setupUi(self) self.btn_pdf.clicked.connect(self.generarPDF)
Como podemos ver, creamos un evento (btn_pdf.clicked.connect) que funcionara cada ves que presionemos el botón PDF (hace lo que está en la función generarPDF())
Función generarPDF()
# Evento del boton btn_pdf def generarPDF(self): # Guardo en las variables los datos de los textEdit Ingresados por el Usuario self.nombre = str(self.textNombre.toPlainText()) self.apellido = str(self.textApellido.toPlainText()) self.correo = str(self.textCorreo.toPlainText()) self.curso = str(self.textCurso.toPlainText()) self.pais = str(self.textPais.toPlainText()) self.obs = str(self.textObs.toPlainText()) # Ruta donde quiero crear el PDF c = canvas.Canvas("/home/diego123/Escritorio/Formulario.pdf") c.drawString(100,750,"Este formulario fue creado en www.pythondiario.com") c.drawString(100,700,("Nombre: "+ self.nombre)) c.drawString(100,680,("Apellido: "+ self.apellido)) c.drawString(100,660,("Correo: "+ self.correo)) c.drawString(100,640,("Curso: "+ self.curso)) c.drawString(100,620,("Pais: "+ self.pais)) c.drawString(100,600,("Observaciones: "+ self.obs)) c.save() # PARA WINDOWS: os.system("start AcroRD32 ruta_y_archivo.pdf &") os.system("evince /home/diego123/Escritorio/Formulario.pdf &")
Esta función se encarga de obtener los datos ingresados por el usuario y generar el PDF a partir de estos datos.
En las variables: self.nombre, self.apellido .... se guarda cada dato ingresado, para eso utilizamos el método toPlainText().
Luego creamos el archivo.pdf con la instrucción:
c = canvas.Canvas("/home/diego123/Escritorio/Formulario.pdf")
y más abajo agregamos los datos con la función drawString(coordenadas + texto).
c.save() se encarga de guardar el archivo, y la última linea:
# PARA WINDOWS: os.system("start AcroRD32 ruta_y_archivo.pdf &") os.system("evince /home/diego123/Escritorio/Formulario.pdf &")
se encarga de abrir atuomáticamente el archvo.pdf . En el comentario dejo también la instrucción para abrirlo en Windows.
Finalizamos el programa con el bloque de código ya conocido:
if __name__ == "__main__": app = QtGui.QApplication(sys.argv) MyWindow = MyWindowClass(None) MyWindow.show() app.exec_()
Espero que esta entrada sea de guia para sus futuras aplicaciones. Dejar sus comentarios ante cualquier duda o sugerencia.
Saludos, Diego.
-
-
Me alegro te sea de ayuda 😉
Saludos
-
-
Muchas gracias por la información, funciona de maravilla.
¿Podrías hacer alguna guía de como crear un ejecutable .exe para esta aplicación si no es mucha molestia?-
Hola Salvador, me has dado la idea para una nueva entrada. Por el momento no estoy con mucho tiempo, pero ni bien pueda publicaré algo al respecto. Saludos
-
Despues de investigar un poco ya pude generar un ejecutable de este ejercicio con cx_Freeze, gracias
-
Estaría bueno poder crear alguna entrada con esa información. Saludos
-
-
Excelentes tutoriales.
Recien empiezo con esto y se entiende todo perfectamente.
Gracias x compartirlos.-
Excelente Leonardo, me alegro te sean de ayuda los tutoriales. Gracias por visitar el blog 😉
-
-
Hola, muchas gracias por tus aportes, la verdad que gracias a ellos aprendo mucho.
Necesito ayuda con este error:File "formularioPDF.py", line 27, in generarPDF
self.nombre = str(self.textNombre.toPlainText())
AttributeError: 'QLineEdit' object has no attribute 'toPlainText'estuve buscando y no encuentro una solucion. Muchas gracias, saludos.
-
Es muy Facil Esa pregunta utilizaste un QLineEdit y debe ser un TextEdit, se parecen pero en el QtDisegner no son lo mismo por que tienen metodos diferentes. por eso no reconoce el metodo ToplainText, cambialo y listo
-
-
Hola Nico el error es que tenes que usar en el Diseño TextEdit y no LineEdit
-
Excelente aporte, yo quiero crear un pdf mostrando los datos de una tabla de una consulta en postgresql, me funcionaria tu ejemplo? o este es muy básico? por casualidad tienes algún material? Gracias 🙂
-
Hola. Gracias por visitar el blog. Necesitas utilizar entorno gráfico o sólo generar el pdf? No tengo material al respecto pero pienso que no debe ser complicado cargar los datos de esa consulta y generar el pdf. Saludos
-
Gracias por responder 😀 Tengo un formulario y me muestra la tabla con los datos de la consulta cargados y un botón pdf al darle click quiero que me muestre los datos tal cual como en la tabla. que podría hacer??
-
Podrías hacer lo mismo que hice yo: cada campo del formulario pasarlo con la función drawString, puedes guardarlo en una variable para que te quede más cómodo. Saludos
-
Buenas Maritrini, ya es un poco antigua su pregunta, pero me la he encontrado en internet y tengo la misma duda. Yo soy principiante en Python.
Quisiera saber si siempre pudo realizar la consulta de hace, de accesar una base de datos y mostrar los campos por medio del reportlab.Me interesa mucho saber sobre este tema ya que debo hacer una gran cantidad de reportes financieros, con cortes control inclusive.
Mucho agradecería la ayuda.
Roberto
Costa Rica
rmatarria@gmail.com
-
-
Que excelente sitio, ojala tuviera mas tiempo para seguirla.
-
Hola, muchas gracias por tu visita y comentarios ;). Saludos
-
-
Hola, seguí los pasos y se crea todo lo que debe generarse, pero al ejecutar la aplicación con el ejecutable generado me salta el siguiente error: 'ImportError: No module named PyQt4'. ¿Existe algún problema con pyqt4 a la hora de generar ejecutable? Muchas gracias de antemano.
-
Hola Salva, gracias por visitar el blog. Fijate en el ejemplo dos de esta entrada: Generar un archivo exe con python. Saludos
-
leí todas las entradas, el único problema es que yo no utilice QtDesigner para mi interfaz, la hice a mano con QWidget en vez de MainWindow, ¿puede ser que ese sea el probema? He estado intentando acoplar mi interfaz a una clase QtGui.QMainWindow, pero me salen todos mis widget en el mismo punto de la ventana principal, ya que estaba utilizando un grid.
-
Puede venir por ese lado si. Yo hace un tiempito estoy por fuera de PyQt y no se si pueda ayudarte. Vas a tener que seguir metiendo mano, quizá alguien más pueda responderte. Saludos
-
Muchas gracias de todas formas, he ido descubriendo que podía ser. Y me he dado cuenta que podría ser un problema de faltas de librerias en windows a la hora de hacer el ejecutable. He instalado el paquete de pandas, numpy, pyqt, fpdf y al menos he conseguido que ejecutara en windows el .py. Aún así cuando se ejecuta la app sigue dando fallos el pandas. Saludos
-
-
Hola diego una pregunta estoy generando un pdf dinamicamente nada mas que tengo un problema ya que al momento de que es dinamico en ocasiones hay datos que sobrepasan los que caben en 1 hoja tendras alguna opcion para que cuando se llene la primera escriba en una segunda hoja
-
Hola, gracias por visitar el blog. Te dejo el enlace de la documentación oficial: https://www.reportlab.com/docs/reportlab-userguide.pdf . Saludos
-
-
Hola, muy interesante este ejemplo. Tengo una pregunta que no tiene nada que ver con esto de pdf sino con otro programa de Python/Tkinter y como no encuentro una sección "general" para hacer preguntas, pues la hago aquí. De antemano perdón si no debí hacerlo aquí.
Llevo unos meses traveseando con Python y Tkinter. Quiero hacer una aplicación para realizar mapas de direcciones muy básico, que arrastrando formas en un canvas el usuario vaya construyendo el mapa. El problema es que no encuentro la manera de hacer drag&drop sobre una imagen .gif en el canvas pero que NO sea precargada al inicio, sino que el usuario pueda escoger cualquier imagen de un menú y esa imagen la pueda arrastrar con el mouse y ubicarla donde desee en el canvas. Ya tengo hecha toda la GUI, puedo cargar las imágenes .gif que desee en el canvas, las veces que desee y puedo moverlas a diferentes intervalos con el teclado, pero sería más lógico, fácil y rápido hacerlo con el mouse. He buscado por todas partes y sólo encuentro ejemplos que funcionan con una única image cargada desde el inicio junto con la aplicación, pero no que se puedan cargar varias luego ¿Es posible lograr lo que quiero hacer en Python o estoy perdiendo mi tiempo? Todavía no hago el paso a wxPython ni PyQt ni nada de eso, pero ya sólo me falta esto en Tkinter para tener lista mi aplicación y no me quiero dar por vencido. Tal vez mi email: hackerdeus@terra.com Saludos.-
Hola Alex, gracias por visitar el blog. Hace tiempo no toco nada de Tkinter, quizá algún colega pueda responderte. Saludo!!!
-
-
HOLA ME PODRIAS AYUDAR ME SALE EL SIGUIENTE ERROR .
Traceback (most recent call last):
File "C:UsersMusashiDocumentsPDF.py", line 5, in
from PyQt4 import QtCore, QtGui, uic
ImportError: No module named 'PyQt4'DESDE YA MUCHAS GRACIAS..!! SALUDOS
-
Hola. Gracias por visitar el blog. Te falta instalar el módulo PyQt4
Saludos
-
-
Hola, esta grandioso este tutorial, me podrías ayudar ya que al intentar probarlo me arroja el siguiente error:
Traceback (most recent call last):
File "pruebform.py", line 44, in generarPDF
c.save()
File "C:WinPython-32bit-3.3.5.0python-3.3.5libsite-packagesreportlabpdfg
encanvas.py", line 1209, in save
self._doc.SaveToFile(self._filename, self)
File "C:WinPython-32bit-3.3.5.0python-3.3.5libsite-packagesreportlabpdfb
asepdfdoc.py", line 217, in SaveToFile
f = open(filename, "wb")
TypeError: embedded NUL characterMi sistema operativo es windows
-
hola me podria decir alguien como hecho andar el ejemplo soy muy nobato aun en esto de python
-
Hola neo, gracias por visitar el blog!!! Que parte no entiendes? has intentado seguir los pasos del tutorial?
Saludos -
pues en concreto esto es lo que me sale, agradecieria la ayuda por que aun estoy muy verde
Traceback (most recent call last):
File "pdf.py", line 13, in
form_class = uic.loadUiType("formularioPDF.ui")[0]
File "/usr/lib/python2.7/dist-packages/PyQt4/uic/__init__.py", line 208, in loadUiType
winfo = compiler.UICompiler().compileUi(uifile, code_string, from_imports, resource_suffix)
File "/usr/lib/python2.7/dist-packages/PyQt4/uic/Compiler/compiler.py", line 140, in compileUi
w = self.parse(input_stream, resource_suffix)
File "/usr/lib/python2.7/dist-packages/PyQt4/uic/uiparser.py", line 974, in parse
document = parse(filename)
File "/usr/lib/python2.7/xml/etree/ElementTree.py", line 1182, in parse
tree.parse(source, parser)
File "/usr/lib/python2.7/xml/etree/ElementTree.py", line 647, in parse
source = open(source, "rb")
IOError: [Errno 2] No such file or directory: 'formularioPDF.ui' -
Al final del error dice que no está econtrando el archivo "formularioPDF.ui". Te aconsejaría que comienzes con el primer tutorial que hice de PyQt para que entiendas mejor: Primera aplicacion con Qt Designer y Python
Saludos
-
-
Se pude crear una pagina html con python, es decir que llames al archivo.py desde un formulario html, com se hace en php...? Gracias, Saludos.
-
Buenas Diego, donde podría obtener un buen ejemplo de acceso a base de datos Postgresql y mostrar el resultado de la lectura de una tabla. Mediante reportlab
Gracias
Roberto
Costa Rica
rmatarria@gmail.com -
Muy útil el ejemplo!!!
Te consulto, si quiero elegir la ruta y el nombre donde crear el pdf, como lo hago?
Gracias!!
Cielo
Deja una respuesta
Muchas Gracias Amigos... Justo lo que buscaba