[Métodos] Generar codigos de barras y codigos QR - Codigo de barras en una imagen con Barcode4j


La idea es simple, hacer una secuencia de carácteres un código de barras con una de las tantas librerías en java para ello, como barcode4j


Hacernos con la dependencia:

  • Desde su pagina de sourceforge podemos descargarnos el jar por versiones, link
  • Desde el repositorio de maven Maven repository, podemos descargar el jar como incluirlo en una dependencia en nuestro pom

Empezar a codear:

  • Creando un objeto de barcode4j que generará el codigo de barras:
    • Code39Bean codebean = new Code39Bean();
  • Al momento de crearlo, tomará por defecto estos valores:
    • De aquí nos importará setear: doQuietzone, moduleWidth, wideZone
  • Setear el codebean:
    • moduleWidth define el ancho del módulo
      • recibe un 'double', que podemos obtener a través de funcion de la clase de barcode4j UnitConv:
        • esta funcion es in2mm convierte pulgadas en milimetros (inches to milimetres) y le pasamos por cada pulgada la profundidad que definamos(dpi)
          • final int dpi = 150;
          • double ancho = UnitConv.in2mm(1.0f / dpi);
          • codebean.setModuleWidth(ancho);
          Este double ancho va a tomar un valor de 0.16933333743363618, reemplazando el valor por defecto de 0.1899999976158142
    • wideZone Define el factor por el cual las barras anchas son más anchas que las barras estrechas
      • codebean.setWideFactor(3)
      este valor por defecto era de 2.5
    • doQuietzone Establece si una zona tranquila debe ser incluida o no
      • codebean.doQuietZone(false);
      no se bien que es este factor pero por defecto era true
  • Y este objeto codebean generá con el método generateBarcode el código de barras como una imagen, recibiendo como parametros:
    • un objeto BitmapCanvasProvider a tráves de su constructor con muchos parámetros:
      1. un OutputStream que contenga la ruta donde se va a crear la imagen.
      2. el tipo MIME del formato de salida deseado, le pasamos el string "image/x-png"
      3. la resolucion, puediendo reutilizar el int que se determina al principio
      4. el tipo de imagen deseada, una constante de la clase BufferedImage.TYPE_BYTE_BINARY
      5. un boolean para determinar si habilitar el anti-aliasing
      6. un entero fijar la orientación( solo puede ser en grados 0, 90, 180, 270, -90, -180 o -270 )
      1
      2
      BitmapCanvasProvider canvas = new BitmapCanvasProvider(out, "image/x-png", dpi, 
                          BufferedImage.TYPE_BYTE_BINARY, false, 0);
      
    • la secuencia de caracteres a convertir en codigo de barras en forma de String

Todo el código completito para poner en main y salir andando:


 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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
    System.out.println("Creando su código de barras");
    // Creando el bean de barcode
    Code39Bean codebean = new Code39Bean();
    // Se declara los pixels por pulgada  = dpi (Dots Per Inch)
    final int dpi = 150;

    // Configurando el generador de barcode
    /** hace la distancia entre las barras, del ancho exacto a 1 pixel **/
    double ancho = UnitConv.in2mm(1.0f / dpi);
    /** Establece el ancho del módulo estrecho **/
    codebean.setModuleWidth(ancho);
    /** Define el factor por el cual las barras anchas son más anchas que las barras estrechas **/
    codebean.setWideFactor(3);
    /** Establece si una zona tranquila debe ser incluida o no **/
    codebean.doQuietZone(false);

    // Abriendo el archivo de salida
    String directorio = "resources/images/";
    File carpeta = new File(directorio);
    if(!carpeta.exists()){
        carpeta.mkdirs();
    }
    String nombreArchivo = "codigoBarras.png";
    File miFile = new File(directorio + nombreArchivo);
    OutputStream out = null;

    BitmapCanvasProvider canvas;
    try {
        out = new FileOutputStream(miFile);
        // Configurando el 'canvas provider' para un PNG monocromatico
        canvas = new BitmapCanvasProvider(out, //el outputstream para escribir
                                          "image/x-png", //el tipo MIME del formato de salida deseado
                                          dpi, //la resolución de imagen deseada
                                          BufferedImage.TYPE_BYTE_BINARY, //el tipo de imagen deseado
                                          false, //true si se debe habilitar el anti-aliasing
                                          0); // Orientation debe ser 0, 90, 180, 270, -90, -180 or -270

        // Generando el codigo de barras
        codebean.generateBarcode(canvas, "LegenDar10");

        // Cerrando el fin de la generacion
        canvas.finish();
    } catch(IOException ioe){
        System.err.println("Ha ocurrido un error: " + ioe.getMessage());
    } finally {
        try {
            out.close();
        } catch (IOException e) {
            System.err.println("No se ha podido cerrar el outputstream " + e.getMessage());
        }
    }
    System.out.println("Imagen creada exitosamente en " + miFile.getAbsoluteFile());
    System.out.println("fin del programa =)");
    System.exit(0);


El resultado:

[MySQL] Consultadas agrupadas: GROUP BY (Vs) DISTINCT


La clasula GROUP BY nos permite 'agrupar' los resultados de una columna que sean iguales usando las funciones de agregación (COUNT, MAX, MIN, SUM, AVG)
La clausula 'DISTINCT' nos permite 'agrupar' los resultados de una columna que sean iguales


Por ejemplo, tomando una tabla 'inventario' que contiene una columna llamada 'idEstadoInventario'
La cual en varios registros lleva valores como 1, 2 ó 3, étc:

  • GROUP BY necesariamente funciona como un complemento de sumar, contar, obtener máximo ó mínimo, promediar, étc
    • Puedo sumar los valores que agrupo por el valor inicial
    • Puedo contar la cantidad de registros 1, 2 y 3
    • Puedo promediar, obtener el maximo y minimo aunque carece de sentido porque el promedio y el maximo o minimo son los mismo valores de 1, 2 y 3
  • DISTINCT buscará entre todos los registros y seleccioná la primera ocurrencia pero obviará las que sean iguales.


Por otra parte el uso de GROUP BY en si mismo:
  • Al usar una funcion de agregacion, se hará por el total de los resultados
  • Al 'agrupar' se realiza la misma implementación aunque diferenciando entre los registros de diferentes valores

[Métodos] Verificar que un archivo sea PDF


Verificar que un archivo sea PDF


Para lograr esa verificacion podemos valernos de algo simple pero efectivo. Al abrir un archivo PDF con un editor de texto, todos los archivos PDF comienzan con el prefijo que señala su version del estilo %PDF-1.3 o similiar pero conteniendo el porcentaje y las siglas PDF:


Con este principio entonces, podemos:
  • Crear un objeto de la clase java.io.File
  • Crear un objeto java.io.FileReader
  • Y tambien un objeto de java.util.Scanner

La idea entonces, es abrir un objeto File, preparalo con un FileReader para que el Scanner pueda leer linea a linea(Aunque solo nos interesa la prinmera) y asi poder hallar si contiene el prefijo %PDF-1.3

File archivo = new File(ruta al archivo);
Scanner input;
try{
    FileReader fReader = new FileReader(file);
    input = new Scanner(fReader);
    String checkline = new = input.nextLine();
    if (checkline.contains("%PDF-")) {
        //Aqui encontramos el prefijo esperado, es PDF!!!
    }else{
        //Lo sentimos, NO es PDF =(
    }
} catch(FileNotFoundException e) {
    e.printStackTrace();
}

[Métodos] Generar archivos PDF con imagenes desde Java (c/ iTextPDF) - Parte III


Parte III - Agregar una imagen al PDF


Para agregar una imagen a nuestros PDFs, simplemente hay que agregar a nuestro documento (Clase documento propia de itextpdf) a través de su método 'add' un objeto de la clase com.itextpdf.text.Image


Image imagen= Image.getInstance(aqui la ruta de la imagen);
documento.add(imagen);

Y con eso estariamos para agregar imagenes a nuestros documentos PDFs.
Desde luego, antes de agregar con el metodo 'add', podemos setearle algunas propiedades a nuestro objeto Image para editarlo, como redimencionarlo o centrarlo.

  • imagen.scaleToFit(436, 267);
  • imagen.setAlignment(Chunk.ALIGN_MIDDLE);

Un ejemplo del código sería algo mas o menos de esta forma:

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

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

    documento.open();
    imagen = Image.getInstance("src/com/dar10comyr/blogspot/img/imagen.png");
    documento.add(imagen);

    documento.close();
} catch (IOException | DocumentException e) {
    e.printStackTrace();
}


Para poder obtener algo de la forma:

[Métodos] Generar archivos PDF con estilo desde Java (c/ iTextPDF) - Parte II


Parte II - Agregar Contenido al PDF


Texto

  • Tamaño
  • Fuente
  • Color
  • Alineacion
  • Decoracion
Empezando por el texto, para definirle algun estilo, el codigo anterior nos basta, solo que esta vez elegiremos algun otro constructor que no este vacio y setee los valores por defecto

public void exportarPDF() {
    Document documento = new Document();

    Calendar cal = Calendar.getInstance();
    Long milis = cal.getTimeInMillis();
    String nombreUnicoArchivo = "/Desktop/miPDF-" + milis + ".pdf";
    String rutaFinalArchivo = System.getProperty("user.home") + nombreUnicoArchivo;
    FileOutputStream fos;
    try {
        fos = new FileOutputStream(rutaFinalArchivo);

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

        documento.open();

        Paragraph paragraph = new Paragraph(/*PASAR PAREMETROS PARA EL ESTILO DESEADO*/);

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



Para poder poner un poco de estilo, uso el ultimo constructor String string, Font font, con la diferencia que en lugar de poner un objeto 'font' uso un método de clase(estático) de FontFactory que devuelve ese objeto:

  • public static Font getFont(String fontname, float size, int style, BaseColor color)
  • String fontname: es la tipografia que usará el texto:

  • float size: es el tamaño, obviamente como un número con coma flotante
  • int style: es el estilo, y también son constantes que podemos usar de la clase Font
  • color: y para el color, podemos usar las constantes o llamar al constructor con los valores RBG




public void exportarPDF() {
    Document documento = new Document();

    Calendar cal = Calendar.getInstance();
    Long milis = cal.getTimeInMillis();
    String nombreUnicoArchivo = "/Desktop/miPDF-" + milis + ".pdf";
    String rutaFinalArchivo = System.getProperty("user.home") + nombreUnicoArchivo;

    FileOutputStream fos;
    try {
        fos = new FileOutputStream(rutaFinalArchivo);

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

        documento.open();

        Paragraph paragraph = new Paragraph("dar10comyr\n.blogspot\n.com",
                FontFactory.getFont(FontFactory.COURIER, 72, Font.UNDERLINE, BaseColor.ORANGE));

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


el final ha sido, mejorando considerablemente a la vez pesada. Pero aun se puede hacer mucho y a ello vamos!

[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:



Java 25 de 2025