miércoles, 23 de abril de 2014

Crear Excel JSF / JAVA

Hola a todos,

Uno de estos días necesite crear un reporte de Excel con Java. Pero que el resultado de este, fuera un mensaje en el navegador indicándome si deseaba guardarlo o abrirlo, pero me tope con que casi todos los ejemplos que se encuentran en internet, solo muestran como crear un Excel en una ruta especifica ( como C://miCarpeta/ ), pero que hay  si lo que quiero es que se cree el Excel y el mismo navegador sea el que me de la opción de abrirlo o guardarlo?

Bueno en este pequeño tutorial describiré a continuación,  como realizar un evento en JSF para que como resultado el explorador nos permita abrir o guardar un Excel.

Para esto, ya debes tener claro como crear una pagina con J2EE (java web), también como desplegarla en un servidor de tu preferencia, y el mapeo de Beans.

Para este ejemplo utilizaremos la librería de Apache POI, el cual pueden descargar en la pagina oficial
http://poi.apache.org/download.html
o en otra de su preferencia
(http://www.java2s.com/Code/Jar/p/Downloadpoi39jar.htm).

Bueno, entonces manos  a la obra,

Primero: creamos una JSP que puede ser similar a esta, el tema del diseño queda en sus manos :)
<table width="100%" style="text-align:center; margin: 0 auto; border:0;" cellpadding="0" cellspacing="0">
   <tr>
       <td>
           <h2> Generar Excel</h2>
       </td>
   </tr>
   <tr>
       <td><h:form id="formConsultarUsuarios">

           <h:panelGroup style="text-align:center; margin: 0 auto; border:0;">
               <h:panelGrid columns="2" id="grillaFiltrosUser" border="0"
                    style="text-align:left; margin: 0 auto;">

                    <h:outputLabel id="lblNombres" style="text-align:right" value="Nombre Excel" />

                    <h:inputText id="nombrePerfil" maxlength="50"  value="#{TestBean.nombrePerfil}" />

               </h:panelGrid>

               <h:panelGrid columns="2" id="grillaBotones2" border="0"  style="text-align:left; margin: 0 auto;">

                  <h:commandButton value="Generar" id="btnGenerarExcel" action="#{TestBean.generarExcel}"
                                styleClass="linkbutton" />

                  <h:commandButton value="Limpiar" id="btnCancelar" action="#{TestBean.limpiar}"
                                styleClass="linkbutton" />

               </h:panelGrid>

           </h:panelGroup>

        </h:form></td> 
 
       </tr>

    </table>

Nota, no olvides registrar el Bean en el FecesConfig.xml



Segundo: Creamos el Bean llamado “TestBean”.

En este Bean, tendremos 3 arreglos que serán los que recorreremos para pintar la  información:

private String[] nombres ={"Nombre 1","Nombre 2","Nombre 3","Nombre 4","Nombre 5"};

private String[] telefonos ={"Telefono 1","Telefono 2","Telefono 3","Telefono 4","Telefono 5"};

private String[] direcciones ={"Direccion 1","Direccion 2","Direccion 3","Direccion 4","Direccion 5"};


después vendrá el llamado al método del Bean, y procederemos a crear el Excel.
Crearemos en el Bean un método llamado "Generar Excel" y en el agregaremos

//Libro Excel
 HSSFWorkbook libro = new HSSFWorkbook();

//Hoja Excel
HSSFSheet hoja = libro.createSheet();

// Se crea una fila dentro de la hoja
HSSFRow fila = null;

try 
{
   //cramos la celda
   HSSFCell celda = null;

   //Realizamos un ciclo para recorrer los arrelgos privados
   for(int i =0; i<this.nombres.length;i++)
   {
      fila = hoja.createRow(i); 
 
      //Nombre
      celda = fila.createCell(0);
      celda.setCellValue(nombres[i]);
 
     //Telefono
     celda = fila.createCell(1);
     celda.setCellValue(telefonos[i]);

     //dirección
     celda = fila.createCell(2);
     celda.setCellValue(direcciones[i]);
   }

  libro.setSheetName(0, getNombreExcel()); 

La parte de este tutorial mas importante sera que una vez tengamos el objeto del libro de excel, procederemos a obtener el arreglo de byte's que este creo, de la siguiente manera:

byte[] xls  = libro.getBytes();




Con este arreglo de byte's ya podemos  pasarlo al explorador y que este nos presente la opción solo debemos escribir:

String contentType = "application/vnd.ms-excel";

//Obtenemos el Contexto
FacesContext fc = FacesContext.getCurrentInstance();

       

  //Obtenemos el Response
  HttpServletResponse response = (HttpServletResponse)fc.getExternalContext().getResponse();

  response.setHeader("Content-disposition", "attachment; filename=" + getNombreExcel());

  //Se indicamos el tipo de contenido
  response.setContentType(contentType);

  //Escribimos en el Response los bytes
  response.getOutputStream().write(xls);
      

   //Forzamos a la finalización y cierre de los objetos necesarios
   response.getOutputStream().flush();
   response.flushBuffer();            
   fc.responseComplete();



Al finalizar esto, debería mostrarnos el resultado que queremos.




También, crearemos el método para limpiar el campo de texto llamado "Limpiar", que sera:


public String limpiar()
{
        nombreExcel ="";
        return null;
 }


Nota: queda a su consideración los estilos de las filas y un contenido verdadero, espero les sea de Ayuda. Cualquier cosa estoy para resolver sus preguntas ;)

Condigo completo del Bean:

public class TestBean {

    private String nombreExcel;

    private String[] nombres ={"Nombre 1","Nombre 2","Nombre 3","Nombre 4","Nombre 5"};
    private String[] telefonos ={"Telefono 1","Telefono 2","Telefono 3","Telefono 4","Telefono 5"};
    private String[] direcciones ={"Direccion 1","Direccion 2","Direccion 3","Direccion 4","Direccion 5"};

    

    public TestBean()

    {
        nombreExcel="";
    }
   

    public String generarExcel()
    {
        byte[] xls = new byte[0];

        //Libro Excel
        HSSFWorkbook libro = new HSSFWorkbook();

        //Hoja Excel
        HSSFSheet hoja = libro.createSheet();

        // Se crea una fila dentro de la hoja
        HSSFRow fila = null;        

        try 
        {
            //cramos la celda
            HSSFCell celda = null;

            //Realizamos un ciclo para recorrer los arrelgos privados
            for(int i =0; i<this.nombres.length;i++)
            {
                fila = hoja.createRow(i);                

                //Nombre
                celda = fila.createCell(0);
                celda.setCellValue(nombres[i]);

                //Telefono
                celda = fila.createCell(1);
                celda.setCellValue(telefonos[i]);

                //dirección
                celda = fila.createCell(2);
                celda.setCellValue(direcciones[i]);
            }

            libro.setSheetName(0, getNombreExcel());

            //Obtenemos los bytes del Excel
            xls  = libro.getBytes();            

            //Generamos el Excel
            String contentType = "application/vnd.ms-excel";

            //Obtenemos el Contexto
            FacesContext fc = FacesContext.getCurrentInstance();
             

            //Obtenemos el Response
            HttpServletResponse response = (HttpServletResponse)fc.getExternalContext().getResponse();

            response.setHeader("Content-disposition", "attachment; filename=" + getNombreExcel());

            //Se indicamos el tipo de contenido
            response.setContentType(contentType);

            //Escribimos en el Response los bytes
            response.getOutputStream().write(xls)
            

            //Forzamos a la finalización y cierre de los objetos necesarios
            response.getOutputStream().flush();
            response.flushBuffer();            
            fc.responseComplete();            

        } catch (Exception e) 
        {
            System.out.println("Error generando Excel.");
        }        

        return null;
    }
    
    public String limpiar()
    {
        nombreExcel ="";
        return null;
    }

    public String getNombreExcel() {
        return nombreExcel;
    }


    public void setNombreExcel(String nombreExcel) {
        this.nombreExcel = nombreExcel;
    }    

}
 
Quedo atento a sus comentarios y Opiniones, Muchas Gracias :)

domingo, 11 de noviembre de 2012

Numeros Binarios JAVA

Hola a todos,

En esta nueva entrada veremos cómo sacar el número binario dado un número entero.

Básicamente un numero binario es una combinación de ceros ( 0 ) y unos ( 1 ), que representan mediante manera exponencial números enteros. Estos números binarios salen de una operación básica como lo es la división  e invirtiendo en resultado final, por lo cual dado un número entero cualquiera dividimos sucesivamente hasta llegar a u número final 0 o 1. Todos estos necesitamos usar obtener dos resultados:

  1. El numero entero siguiente, que se da por medio de divisiones sucesivas.
  2. El residuo de la división por dos del número entero.
Podemos ver mas del concepto en WIki
// 

public class Binario {

 //para esta clase tenemos que importar la libreria para listas
 //que es import java.util.ArrayList; 
 
 public static void main(String[] args) {

  //Numero Entero que convertimos en binario
  int numero=128;
  
  //String en el cual almacenamos el valor binario resultante
  String binario="";
  
  //llamamos al metodo que convirte el numero en binario
  binario=convertirABinario(numero);
  
  //mostramos por consola el numero Binario resultante
  System.out.println("El numero Binario es " + binario);
 }
 
 /**
  * Metodo que convierte  un numero entero en binario
  * @param numero Numero entero correspondiente
  * @return cadena de texto con el numero binario resultante
  */ 
 public static String convertirABinario(int numero)
 {
  //lista donde almacenamos los valores individuales
  ArrayList binarios = new ArrayList();
  
  //variable donde almacenamos el resultado de la division 
  int aux=numero;
  
  //hacemos un ciclo while para sacar todos los valores binarios
  while(true)
  {
   //almacenamos el resultado de la operacion sea 1 o 0
   binarios.add(aux%2);
   
   //pasamos el sigiente numero
   aux/=2;
   
   if(aux<2)
    {
    //una vez obtenido todos los valores salimos del ciclo
     binarios.add(aux); 
     break;
    }
   
  }
    
  //llamamos al metodo que nos invierta la lista y obtenmos el resultado final
  return invertirLista(binarios);
 }

 
 /**
  * Metodo que invierte la lista para obtener el binario final
  * @param lista donde se encuentra los resultados binarios
  * @return con el numero binario final
  */
 public static String invertirLista(ArrayList lista)
 {
  String invertido="";
  
  for(int i=lista.size()-1;i>=0;i--)
  {
   invertido+=lista.get(i);
  }
  
  return invertido;
 }
}