Como generar un PDF con datos de una tabla MySQL con ayuda de iText
10 abril 2011 133 comentarios
Ejemplo muy sencillo donde se ilustra como generar un documento PDF con datos provenientes de una tabla creada en MySQL con la libreria iText. Bueno creo que el titulo de la entrada lo dice todo asi que no quiero ser redundante en el objetivo de esta practica de programacion.
El ejemplo consta de 3 archivos: CrearConexion.java, GenerarPDFEmpleados.java JfrPrincipal.java (a decir verdad tambien se usa una imagen (logo de mysql), pero puedes cambiarla por otra que quieras). Como en casi todos mis ejemplos, no voi a dar mucha explicacion debido a que mi objetivo es tener disponible el ejemplo de codigo. Primero que nada te muestro un diagrama para que veas en forma grafica y rapida la estructura del ejemplo:
A continuacion se explican brevemente los tres archivos de codigo a grandes rasgos:
JfrPrincipal
Clase que crea una interfaz grafica de usuario muy sencilla; la cual es una ventana con 2 JLabels, un JTextField y un JButton. Desde esta clase se hace una instancia de la clase GenerarPDFEmpleados.java, la cual es la que realmente genera el PDF con ayuda de la libreria iText. En el codigo se muestran los comentarios correspondiente explicando casi todo…
/* Instituto Tecnologico de Zacatepec, Mor. Descripcion: Clase que crea una ventana con un boton que al darle clic genera el PDF de una tabla de MySQL. Autor: Gonzalo Silverio gonzasilve@gmail.com Archivo: JfrPrincipal.java */ import javax.swing.*; import java.awt.FlowLayout; import java.awt.event.*; public class JfrPrincipal extends JFrame { String strTituloPDF = "INSTItuTO TEcnologico de zacatepec"; String strNombrePDF = "pdf_tabla_Empleados.pdf"; JTextField jtfNombrePDF; //Constructor JfrPrincipal(String titulo, int ancho, int alto) { //Establecer titulo, tamanio y posicion en la pantalla super(titulo); setSize(ancho,alto); setLocationRelativeTo(null); //centrado //Rotulo principal de la ventana JLabel lblTitulo = new JLabel("Generar un PDF desde Java"); JPanel panTitulo = new JPanel(new FlowLayout(FlowLayout.CENTER)); panTitulo.add(lblTitulo); //Crea campo de texto para especificar el nombre del PDF JLabel lblNombrePDF = new JLabel("Nombre del documento PDF"); jtfNombrePDF = new JTextField(30); jtfNombrePDF.setText(strNombrePDF); jtfNombrePDF.setHorizontalAlignment (JTextField.CENTER); JPanel panNombrePDF = new JPanel(new FlowLayout(FlowLayout.CENTER)); panNombrePDF.add(Box.createHorizontalStrut(15)); panNombrePDF.add(lblNombrePDF); panNombrePDF.add(jtfNombrePDF); //Crear el boton nuevo JButton btnGenerarPDF = new JButton("Generar PDF"); JPanel panGenerarPDF = new JPanel(new FlowLayout(FlowLayout.CENTER)); panGenerarPDF.add(btnGenerarPDF); //Todos los componentes estan en un Box Vertical //la clase Box se usa para alinear los controles Box boxVertical = Box.createVerticalBox(); boxVertical.add(Box.createVerticalStrut(50)); boxVertical.add(panTitulo); boxVertical.add(panNombrePDF); boxVertical.add(Box.createVerticalStrut(10)); boxVertical.add(panGenerarPDF); //Agregar el Box a la ventana add(boxVertical); setResizable(false); //No maximizar ni cambiar tamanio //Al dar en la X terminar todo el programa setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // ########### ESCUCHADOR BOTON NUEVO ########## ActionListener escuchadorGenerarPDF = new ActionListener() { public void actionPerformed(ActionEvent evt) { strNombrePDF = jtfNombrePDF.getText(); GenerarPDFEmpleados ejemplo = new GenerarPDFEmpleados(strTituloPDF,strNombrePDF); //Preguntar al usuario si desea abrir el documento PDF int respuesta = JOptionPane.showConfirmDialog(null,"Se ha generado el documento "+strNombrePDF+", ¿Desea abrirlo?","Pregunta",JOptionPane.YES_NO_OPTION,JOptionPane.QUESTION_MESSAGE); //Si la respuesta es SI, abrirlo if(respuesta == JOptionPane.YES_OPTION) ejemplo.abrirPDF (); } }; btnGenerarPDF.addActionListener(escuchadorGenerarPDF); } //Fin del constructor //hace visible la ventana public void mostrar() { setVisible(true); } public static void main(String[] args) { JfrPrincipal ejemplo = new JfrPrincipal("Ventana principal de Usuario",400,400); ejemplo.mostrar(); } }
Y a continuacion una imagen de la GUI que se genera:
El primer Jlabel es un rotulo para la ventana, el segundo Jlabel es una etiqueta para el JTextField con la cual se le indica al usuario que debe escribir el nombre del documento PDF (con extension), el JTextField es el campo donde el uuario debe escribir el nombre del PDF. El JButton al darle click; el usuario generara el documento PDF de una tabla llamada Empleados e inmediatamente se le preguntara si desea abrirlo, aca una imagen:
Si el usuario da click en el boton Si del mensaje llama al metodo abrirPDF() de un objeto de la clase GenerarPDFEmpleados.java el cual abrira en una nueva ventana el documento PDF dentro del cual se muestra el contenido de la tabla empleados, aca una imagen del PDF:
GenerarPDFEmpleados.java
En esta clase es donde se hace uso de la libreria iText para generar un documento PDF. El codigo de esta clase es el siguiente:
// Instituto Tecnologico de Zacatepec // Descripcion: Programa que genera un archivo PDF con datos de una base de datos // en mySQL y con ayuda de la libreria iText // Author: Gonzalo Silverio gonzasilve@hotmail.com // Archivo: GenerarPDFEmpleados.java import java.awt.Color; import java.io.FileOutputStream; import java.io.IOException; import java.util.Date; import com.lowagie.text.Anchor; import com.lowagie.text.BadElementException; import com.lowagie.text.Cell; import com.lowagie.text.Chapter; import com.lowagie.text.Document; import com.lowagie.text.DocumentException; import com.lowagie.text.Font; import com.lowagie.text.List; import com.lowagie.text.ListItem; import com.lowagie.text.Paragraph; import com.lowagie.text.Section; import com.lowagie.text.Table; import com.lowagie.text.Element; import com.lowagie.text.PageSize; import com.lowagie.text.pdf.PdfPCell; import com.lowagie.text.pdf.PdfWriter; import com.lowagie.text.pdf.PdfContentByte; import com.lowagie.text.pdf.PdfPTable; import com.lowagie.text.Image; import java.sql.*; public class GenerarPDFEmpleados { private String strNombreDelPDF; private Font fuenteNegra10 = new Font(Font.TIMES_ROMAN, 10, Font.BOLD, Color.BLACK); private Font fuente8 = new Font(Font.TIMES_ROMAN, 8, Font.NORMAL, Color.BLACK); private Font fuenteAzul25 = new Font(Font.TIMES_ROMAN, 25, Font.BOLD, Color.BLUE); Color grisClaro = new Color( 230,230,230); Color azulClaro = new Color( 124,195,255 ); //############# VARIABLES PARA MANEJO DE BASE DE DATOS ######################## //Guarda la consulta operacion a realizar String strConsultaSQL; //Apuntador a la conexion Connection conn = null; //Para ejecutar operaciones SQL Statement estSQL1; //Para guardar los resultados de una operacion SELECT ResultSet rs; Document document; PdfWriter writer; String strRotuloPDF; //Metodo principal del ejemplo public GenerarPDFEmpleados(String titulo, String nomPDF) { strRotuloPDF = titulo; strNombreDelPDF = nomPDF; try { //Hoja tamanio carta, rotarla (cambiar a horizontal) document = new Document( PageSize.LETTER.rotate() ); writer = PdfWriter.getInstance( // that listens to the document document, // direccionar el PDF-stream a un archivo new FileOutputStream(strNombreDelPDF)); document.open(); agregarMetaDatos(document); agregarContenido(document); document.close(); System.out.println("Se ha generado el PDF: "+ strNombreDelPDF); } catch (Exception e) { e.printStackTrace(); } } //agrega el contenido del documento; para este ejemplo agrega una tabla con datos y una imagen //Espera como entrada el documento donde agregara el contenido private void agregarContenido(Document document) throws DocumentException { Paragraph ParrafoHoja = new Paragraph(); // Agregamos una linea en blanco al principio del documento agregarLineasEnBlanco(ParrafoHoja, 1); // Colocar un encabezado (en mayusculas) ParrafoHoja.add(new Paragraph(strRotuloPDF.toUpperCase (), fuenteAzul25) ); agregarLineasEnBlanco(ParrafoHoja, 1); // 1.- AGREGAMOS LA TABLA agregarTabla(ParrafoHoja); //Agregar 2 lineas en blanco agregarLineasEnBlanco(ParrafoHoja, 2); // 2.- AGREGAMOS LA IMAGEN try { Image im = Image.getInstance("logo_mysql.gif"); im.setAlignment(Image.ALIGN_CENTER | Image.TEXTWRAP ); im.setWidthPercentage (50); ParrafoHoja.add(im); } catch(Exception e) { e.printStackTrace (); } document.add(ParrafoHoja); } //Se conecta al DBMS MySQL , obtiene los datos de la tabla (SELECT) y los acomoda en una tabla JTable de iText. // Espera como entrada el parrafo donde agregara la tabla private void agregarTabla(Paragraph parrafo) throws BadElementException { //Anchos de las columnas float anchosFilas[] = { 0.2f,1f,1f,0.5f,0.5f,0.3f,1f,1.5f,0.7f }; PdfPTable tabla = new PdfPTable(anchosFilas); String rotulosColumnas[] = {"id","Nombre","Apellidos","Sexo","Telefono","Edad","Correo","Direccion","Fecha\nContratacion"}; // Porcentaje que ocupa a lo ancho de la pagina del PDF tabla.setWidthPercentage(100); //Alineacion horizontal centrada tabla.setHorizontalAlignment(Element.ALIGN_CENTER); //agregar celda que ocupa las 9 columnas de los rotulos PdfPCell cell = new PdfPCell(new Paragraph("Tabla: Empleados")); cell.setColspan(9); //Centrar contenido de celda cell.setHorizontalAlignment(Element.ALIGN_CENTER); //Color de fondo de la celda cell.setBackgroundColor (azulClaro); tabla.addCell(cell); try { if ( ConectarBD() ) { // Mostrar los rotulos de las columnas for(int i=0; i<rotulosColumnas.length; i++) { cell = new PdfPCell(new Paragraph(rotulosColumnas[i],fuenteNegra10)); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); cell.setHorizontalAlignment(Element.ALIGN_CENTER); cell.setBackgroundColor (grisClaro); tabla.addCell(cell); } //Consultar la tabla empleados strConsultaSQL = "SELECT * FROM empleados"; //ejecutar consulta rs = estSQL1.executeQuery(strConsultaSQL); //Iterar Mientras haya una fila siguiente while (rs.next()) { //Agregar 9 celdas cell = new PdfPCell(new Paragraph(String.valueOf(rs.getInt ("idEmpleado")),fuente8 )); tabla.addCell(cell); cell = new PdfPCell(new Paragraph(rs.getString("nombre"),fuente8)); tabla.addCell(cell); cell = new PdfPCell(new Paragraph(rs.getString("apellidos"),fuente8)); tabla.addCell(cell); cell = new PdfPCell(new Paragraph(rs.getString("sexo"),fuente8)); tabla.addCell(cell); cell = new PdfPCell(new Paragraph(rs.getString("telefono"),fuente8)); tabla.addCell(cell); cell = new PdfPCell(new Paragraph(String.valueOf(rs.getInt("edad")),fuente8) ); tabla.addCell(cell); cell = new PdfPCell(new Paragraph(rs.getString("correo"),fuente8)); tabla.addCell(cell); cell = new PdfPCell(new Paragraph(rs.getString("direccion"),fuente8)); tabla.addCell(cell); cell = new PdfPCell(new Paragraph(rs.getDate("fechaContratacion").toString (),fuente8 ) ); tabla.addCell(cell); } //Cerrar los objetos de manejo de BD CrearConexion.cerrar(rs); //ResultSet CrearConexion.cerrar(estSQL1); //Statement CrearConexion.cerrar(conn); //Connection } //Fin de if que comprueba si se pudo conectar } catch(Exception e) { System.out.println("Excepcion al ejecutar CONSULTA!!!"); //Mostrar la traza de la pila e.printStackTrace(); } //Agregar la tabla con los datos al parrafo que nos llego como entrada parrafo.add(tabla); } //Fin del metodo que crea la tabla //Agrega las lineas en blanco especificadas a un parrafo especificado private static void agregarLineasEnBlanco(Paragraph parrafo, int nLineas) { for (int i = 0; i < nLineas; i++) parrafo.add(new Paragraph(" ")); } //Agrega los metadatos del documento, los metadatos a asignar son //Titulo, Asunto, Palabras clave, Autor y el sw o org con el cual fue generado private static void agregarMetaDatos(Document document) { document.addTitle("Documento con datos de tabla MySQL"); document.addSubject("Usando iText y MySQL"); document.addKeywords("Java, PDF, iText"); document.addAuthor("Gonzalo Silverio"); document.addCreator("https://gonzasilve.wordpress.com"); } //devuelve true en caso de que si se pudo conectar //devuelve false sino se logro conectar public boolean ConectarBD() throws Exception { try { //Aqui se instancia a la otra clase --> CrearConexion.java //y se le mandan en el constructor los datos de conexion CrearConexion con = new CrearConexion("root","root","prueba"); //Obtiene una referencia a la conexion abierta conn = con.getConnection(); //Comprobar si hay una refencia valida if(conn!=null) { //Mostrar MSG al usuario de la conexion se ha establecido System.out.println("Conexion establecida"); //Se prepara para ejecutar sentencias en la conexion recien abierta estSQL1 = conn.createStatement(); return true; } else return false; } catch (SQLException e) { // the above drop statements will throw exceptions // if the types and tables did not exist before. Just ingore it. System.out.println("Error en la conexion!!!"); e.printStackTrace(); return false; } } //Abre el documento PDF public void abrirPDF() { /* Abrir el archivo PDF */ try { Runtime.getRuntime().exec("rundll32 url.dll,FileProtocolHandler " + strNombreDelPDF); } catch (IOException e) { e.printStackTrace(); } } }
Como se observa en el metodo conectarBD() se hace una instancia de la clase CrearConexion.java y se le mandan en el constructor los datos con los que se conectara a MySQL.
Los datos que se usan para conectarse al DBMS son:
Usuario: root
Password: root
Base de datos: prueba
Tabla: empleados
Host: localhost
Y la estructura de la tabla empleados es:
CrearConexion.java
Este archivo tiene como funcion la apertura de una conexion al DBMS MySQL y devuelve la referencia a traves de su metodo getConnection(). En el constructor recibe los datos que seran usados por el JConnector, el codigo de este archivo es:
// Instituto Tecnologico de Zacatepec // Descripcion: Clase para manejo de base de datos de MySQL // Author Gonzalo Silverio gonzasilve@hotmail.com // Archivo: CrearConexion.java import java.sql.*; public class CrearConexion { //Datos por default de la conexion static String strUsuario = "usr"; static String strPassword = "pw"; static String strBaseDatos ="bd"; static String strHost = "localhost"; //Constructor, le llegan los datos con los que se conectara al DBMS public CrearConexion(String usr,String pw, String bd) { strUsuario = usr; strPassword = pw; strBaseDatos =bd; try { Class.forName("com.mysql.jdbc.Driver"); } catch ( ClassNotFoundException e ) { System.out.println("ERROR: Error al cargar la clase del Driver"); } } //Constructor, le llegan los datos con los que se conectara al DBMS // a dif. del otro constructor le llega tbn el host (servidor) public CrearConexion(String usr,String pw, String bd,String srvr) { strUsuario = usr; strPassword = pw; strBaseDatos =bd; strHost = srvr; try { //Cargar el driver Class.forName("com.mysql.jdbc.Driver"); } catch ( ClassNotFoundException e ) { System.out.println("ERROR: Error al cargar la clase del Driver\n"); e.printStackTrace(); } } public static Connection getConnection() throws SQLException { //a continuacion vamos a formar la cadena de conexion, pero... //OJO aca debes poner el nombre de la instancia de SQL Server que vas a usar String url = "jdbc:mysql://"+strHost+"/"+strBaseDatos; return DriverManager.getConnection(url,strUsuario,strPassword); } //Cierra objeto Resultset public static void cerrar(ResultSet rs) { try { rs.close(); } catch(Exception ex) {} } //Cierra objeto Statement public static void cerrar(Statement st) { try { st.close(); } catch(Exception ex) {} } //Cierra objeto Connection public static void cerrar(Connection con) { try { con.close(); } catch(Exception ex) {} } } //Fin de la clase
Como se puede ver esta clase es la misma que use en el ejemplo Acceso a Base de datos de SQL Server desde java (Jconnector).
Eso es todo, hasta pronto y espero comentarios al respecto. ya sabes si quieres los fuentes, basta con pedirlos dejando tu mail. Suerte, bye.
Hola, me ayudó en mucho tu proyecto 🙂
… podrás ayudarme con una pregunta:
me marca error mi clase de GenerarPDF en la línea en la que declaro mi metodo principal.
–Por favor, necesito que me ayudes
espero respuesta :3
Hola amigo me podrias mandar el ejemplo para ver su funcionamiento ??
muchas gracias!!
Buenas que tal amigo, como seria para imprimir directamente con la impresora predeterminada, osea en vez de abrir el pdf que me lo imprima ya.
Hola! me pueden ayudar con el proyecto?, quisiera saber si es posible mandarlo a mi correo: Mazinkaiser_SRW@hotmail.com. Gracias!!!!
Hola, el codigo se me hace muy bueno, sin embargo, me podrias ayudar? tienes idea de como se podria generar a partir de una conexion mysql pero via jpa?
Me gustaría el fuente ya que es muy bueno
Buenas amigo, serías tan amable de enviarme la libreria que utilizaste a razaisger@hotmail.com
definitivamente la gente es cómoda, lee y entiende el código!!
Hola, este metodo se ve interesante; me gustaria tener las fuentes para verificar si sirve a mis propositos. Saludos
Que tal amigo buen ejemplo, de casualidad podrias enviarme para poder ver bien su funcionamiento. jonystanlita5@gmail.com
que paso con tu imagenes amigo! x si tambien me lo puedes enviar te lo agradecere mucho.
me podrías regalar el proyecto a este correo: harbyjohaan@hotmail.com gracias
pasame el programa porfa germanmelchorv@gmail.com
https://mega.co.nz/#!OVJEQTCZ!Frgpp2sGHesKpUKhgCdvOJMNs4UF9v-nOeTFSJWUI30
Perdon me equivoque, puedes compartir el codigo del proyecto, segui cada linea y no pude conseguir hacerlo funcionar.
Te pido un favor si me puedes pasar tu código y las librerías que utilizaste mi correo es ani.963@hotmail.com
Amigo Tengo una duda con tu codigo.. Podrias Respondermela Porfavor.. Te lo agradecera Mucho
k tal sera que me puedes propprcionar el programa porfaz te
dejo mi correo: drinkit_18@hotmail.com
y si quiero solo enviar los datos sin la tabla?
Me puedes enviar el proyecto esta muy bueno quiero ver como funciona
mi correo j.carocaanticoy@gmail.com
me pasarias el codigo fuente usando la libreria este es mi correo cobra_1884@hotmail.com
pasame tambien el codigo fuente de la aplicacion
mi correo es cardenas_clk@hotmail.com
Excelente aporte, me podrias enviar el codigo por favor. nastick.nes@gmail.com
Gracias.
Saludos.
Hola muchas gracias por el aporte, es justo lo que estaba buscando. Te molestaria si te pido que me lo puedas compartir?
Muchas gracias de antemano!!
Mi correo es transparente_29@hotmail.com
Solo tengo una duda mas, se puede ajustar el tamaño a la hoja, lo que pasa que necesito imprirlo en forma de tiket.
Muchísimas gracias gonzasilve es lo que estaba buscando. Empecé a ver hoy cómo hacer reportes desde Java y estaba entre las herramientas IText y el jasperReports, pero con este tutorial me voy a inclinar por IText, todavía no sé bien por qué, creo que es porque me gusta complicarme siempre la vida, pero creo que al ser todo por código es más «configurable». Me interesaría mucho conocer tu opinión al respecto que sos el que sabe.
Abrazo!
Muy bueno!!
me lo puedes enviar?
muchas gracias y saludos!
Muy bueno!! me lo puedes enviar?
muchas gracias y saludos!
Hola muy bueno el tutorial podrias mandarme el ejemplo?, me gustaria verlo para poder ver como funciona.. gracias..
sandy_diazv@hotmail.com
hola amigo me podrias envia el proyecto, la verdad muy interesante creo ke e leido todos los codigos que has publicado =)
pankexiito@gmail.com
amigo muy buen post me pudes pasar tu proyecto para ver como funciona y asi practicar
muy interesante… me puedes enviar el proyecto porfavor… cristianmejiasuarez@gmail.com Gracias por compartir!
Porfas el codigo me seria muy util! Y sigue adelante!
cierto, mi correo xD bpg_92@hotmail.com
buen post amigo, pero me podrias mandar el proyecto porfa, es que estoy hace tiempo tratando de hacer estoy y no me resulta, porfa me harias un gran favor, mi correo es shamxel_988@hotmail.com
Excelente!!
Me podrias enviar el proyecto a mi tambien?
Por favor!!
hola buenas tardes necesito mucho de favor si me podrías pasar el proyecto completo mi correo es normix.osunadelreal5@gmail.com
graciiias! *:)
Excelente aporte gonzasilve gracias por compartir me pordrias enviar el ejemplo para analizarlo y sigue asi, saludos desde Perú.
PD: masterofmusic@live.com.mx
este es mi correo… gracias!
Hola que tal estoy viendo el tutorial y me parece perfecto… podrian enviarme por favor el ejemplo para correrlo en mi equipo?.
Buena , me solucionaste una duda
Por nada
Saludos.
Me sumo a Martin, excelente ejemplo, me puedes enviar el proyecto, saludos
Camilo ya te lo envie,
Saludos amigo.
Como siempre los mejores Tutoriales…
Podrias mandarme este ejemplo para poder ver como funciona?
tubidj@hotmail.com
muchas gracias
saludos
Ok, te lo acabo de adjuntar y enviar,
Saludos!