[Metodos] Generar archivos PDF en Java (c/ iTextPDF)


Parte I - Hola PDF!!!


Para poder crear un archivo pdf sencillo desde el codigo de JAVA vamos a usar la libreria iTextPDF, simplemente agregando el nuevo jar a nuestro proyecto o dejandoselo en manos de un gestor de dependencias como maven, que ademas te da la opcion de descargarlo manualmente para un proyecto pequeño.

Para hacer nuestro 'Hola mundo' solamente se requieren 6 pasos:

  1. Creamos virtualmente el documento que vamos a trabajar, a través de la clase Document propia de iTextPDF:
    • Document documento = new Document();

  2. Creamos un FileOutputStream pasando como parametro un String que será el path donde se va a generar el PDF. Esto puede traer aparejado algunos pequeños problemas, como que la ruta no exista, que no contemos con permisos para escribir, etc De encontrarse el archivo, se sobreescribe:
    • FileOutputStream fos = new FileOutputStream();

  3. Nuestro próximo paso es llamar al escritor de PDF de itextPDF(PdfWriter) a tráves de su método estático pasandole el documento y un OutputStream como parámetro y tmb indicandole el nivel de espacio entre líneas que va a acontener el documento como un Integer:
    • PdfWriter pdfW = PdfWriter.getInstance(documento, fos);
      pdfW.setInitialLeading(20);

  4. Ahora estamos listos para 'abrir' nuestro documento, que virtualmente ya tiene forma, y comenzar a introducir contenido en él:
    • documento.open();

  5. Para introducir texto como el 'hola mundo', vamos a de crear un objeto Paragraph, propio de iTextPDF, inicializandolo con el String que vayamos a introducir como parámetro del constructor:
    • Paragraph paragraph = new Paragraph("Hola PDF");
      documento.add(paragraph );

  6. Se cierra el documento:
    • documento.close();
Luego de todo esto, mi resultado fué:


Mi código completo es:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
public void exportarPDF() {
    Document documento = new Document();

    String escritorio = System.getProperty("user.home")+"/Desktop/miPDF.pdf";
    FileOutputStream fos;
    try {
        fos = new FileOutputStream(escritorio);

        PdfWriter pdfW = PdfWriter.getInstance(documento, fos);
        pdfW.setInitialLeading(20);

        documento.open();

        Paragraph paragraph = new Paragraph("Hola PDF");

        documento.add(paragraph);
    } catch (FileNotFoundException | DocumentException e) {
        e.printStackTrace();
    }
    documento.close();
}

Comparte esto:





[Métodos] Java Mail - Parte IV - Recibir un Mail




Para poder leer correos de nuestro mail como cualquier servicio de web mail pero en hecho en java vamos a necesitar importar la dependencia de Java Mail, crear un conjunto de propiedades, crear la sesion, y ahora contamos con los objetos Store y Folder, ademas de la clase Message para cada email.


  1. Crear un conjunto de propiedades, a las cuales hay que setearle las propiedades:
    Properties prop = new Properties();

    • Deshabilitar el TLS (Transport Layer Security)
      • prop.setProperty("mail.pop3.starttls.enable", "false");

    • Avtivar en su lugar SSL (Secure Sockets Layer)
      • prop.setProperty("mail.pop3.socketFactory.class","javax.net.ssl.SSLSocketFactory" );
        prop.setProperty("mail.pop3.socketFactory.fallback", "false");

    • Le indicamos el puerto de conexion (995)
      • prop.setProperty("mail.pop3.port","995");
        prop.setProperty("mail.pop3.socketFactory.port", "995");

  2. Creamos una sesion, con las properties recién definidas:
    • Session sesion = Session.getInstance(prop);

  3. Pasamos a crear los objetos, Store y Folder. Store vendria a ser como la cuenta de mail que guarda los diversos correos, Folder la carpeta donde se guardan estos(EJ: recibidos, enviados, spam, etc)
    • Store store;
      Folder folder;

  4. Inicializamos estos objetos dentro de un try-catch, pidiéndole a la Session que obtenga el 'almacen' y lo conecte, pasando el host, usuario y contraseña.
    Luego a este 'almacen' le pedimos que obtenga la carpeta y la abra con una propiedad de READ_ONLY para no marcar los correos como leido. Caso contrario usamos READ_WRITE:
    • store= sesion.getStore("pop3");
      store.connect("pop.gmail.com","nuestro_mail@gmail.com","nuestra_contraseña");
      folder= store.getFolder("[Gmail]/Send");
      folder.open(Folder.READ_ONLY);

  5. Creamos nnuestro objeto Message que representa el correo electronico en si mismo como un array de mensajes.
    • Message [] mensajes= folder.getMessages();

  6. Ya tendremos nuestro array de mensajes para mostrar, imprimiendo simplemente en pantalla, podemos utlizar un ciclo for para leer cada uno
    • for (int i = 0; i < mensajes.length; i++){     System.out.println("DE : " + mensajes[i].getFrom()[0].toString());
          System.out.println("ASUNTO: " + mensajes[i].getSubject());
      }


El resultado puede variar, dependiendo de los correos recibidos. Mi resultado fu este:



Mi método completo es el siguiente.
public void leerCorreo(){
    Properties prop = new Properties();

    // Deshabilitamos TLS
    prop.setProperty("mail.pop3.starttls.enable", "false");

    // Hay que usar SSL
    prop.setProperty("mail.pop3.socketFactory.class","javax.net.ssl.SSLSocketFactory" );
    prop.setProperty("mail.pop3.socketFactory.fallback", "false");

    // Puerto 995 para conectarse.
    prop.setProperty("mail.pop3.port","995");
    prop.setProperty("mail.pop3.socketFactory.port", "995");

    Session sesion = Session.getInstance(prop);
    sesion.setDebug(false);

    Store store;
    Folder folder;
    try {
        store = sesion.getStore("pop3");
        store.connect("pop.gmail.com","dar10comyr@gmail.com","blogspot2016");

        folder = store.getFolder("INBOX");
        folder.open(Folder.READ_ONLY);

        Message [] mensajes = folder.getMessages();

        for (int i = 0 ; i < mensajes.length; i++){
            System.out.println("DE    : " + mensajes[i].getFrom()[0].toString());
            System.out.println("ASUNTO: " + mensajes[i].getSubject());
        }
    } catch (NoSuchProviderException e){
        e.printStackTrace();
    } catch (MessagingException e) {
        e.printStackTrace();
    }
}




OBTENER TODAS LAS CARPETAS


Para obtener mas carpetas ademas de la de 'INBOX', deberemos cambiar el protocolo de conexion de POP a IMAP
  1. Creamos nuestras propiedades.
  2. Le seteamos un única propiedad:
    • prop.setProperty("mail.store.protocol", "imaps");
  3. Creamos una sesion con las properties creadas.

  4. Obtenemos un Store pidiendoselo a la sesion pero esta vez con el protocolo IMAP
    • Store store= sesion.getStore("imaps");

  5. Le pedimos al Store que se conecte pasandole el host pero como protocolo POP, el usuario y la contraseña (igual que antes).

  6. Ahora, vamos a obtener un array de del Folders para luego recorrerlo y obtener de si mismo el nombre de la carpeta (o todos)
    • Folder[] folders= store.getDefaultFolder().list("*")

  7. Realizamos una pequeña comprobación con un if, ya que vamos a pedirle al Folder que nos obtenga el 'tipo', que es un número y solo nos interesa que sea el '3' (Ya que tambien existe un tipo '2' que no contiene 'folders' válidos).
    • if (folder.getType() == 3) {     System.out.println(folder.getFullName() + ": " + folder.getMessageCount());

  8. Ahora obtenemos el folder, pidiendosele al Store pero esta vez le pasamos como parametro, el mismo 'folder' que obtiene su nombre.
    • folder = store.getFolder(folder.getFullName());

  9. Nuevamente le seteamos la opcion de 'READ ONLY' para que no los marque como leidos, si es que lo queremos asi:
    • folder.open(Folder.READ_ONLY);

  10. Volvemos a crear nuestro array de mensajes que luego iteraremos para leer cada mensaje de cada carpeta:
    • Message [] mensajes= folder.getMessages();

  11. Por ultimo el mismo for para ver aunque sea por pantalla los resultados:
    • for (int i = 0; i < mensajes.length; i++){     System.out.println("DE : " + mensajes[i].getFrom()[0].toString());
          System.out.println("ASUNTO: " + mensajes[i].getSubject());
      }

Mi resultado fue mas o menos asi:





El codigo completo de esta clase es:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public void LeerCorreos() {
    Properties props = System.getProperties();
    props.setProperty("mail.store.protocol", "imaps");
    try {
        Session session = Session.getDefaultInstance(props, null);
        Store store = session.getStore("imaps");
        store.connect("imap.gmail.com", "dar10comyr@gmail.com", "blogspot2016");
        Folder[] folders = store.getDefaultFolder().list("*");
        for (Folder folder : folders) {
            if (folder.getType() == 3) {
                System.out.println(folder.getFullName() + ": " + folder.getMessageCount());

                folder = store.getFolder(folder.getFullName());
                folder.open(Folder.READ_ONLY);

                Message [] mensajes = folder.getMessages();

                for (int i = 0 ; i < mensajes.length; i++){
                    System.out.println("DE    : " + mensajes[i].getFrom()[0].toString());
                    System.out.println("ASUNTO: " + mensajes[i].getSubject());
                }
            }
        }
    } catch (MessagingException e) {
        e.printStackTrace();
    }
}


Comparte esto: