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

5 comentarios:

  1. Muchas gracias por el aporte, me genera el excel pero me da pete el Microsoft Excel al intentar abrir el archivo que he generado y descargado. Y dandole a abrir directamente tampoco me abre, lo unico bueno que despues de tres intentos al tercero si me abre pero no sé porque me pasa esto. Es como si el Excel que me generara no estuviera bien del todo. Haber si puedes ayudarme. Muchas gracias.

    ResponderEliminar
    Respuestas
    1. Hola, lo que puede ser es que cuando lo intentes abrir no este terminada la descarga completamente. EL archivo te abre con algún error en el office ?

      Eliminar
  2. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  3. Podrías compartirnos los archivos?

    ResponderEliminar
  4. Buenas tambien tengo el mismo problemas el archivo sale con error no lo puedo visualizar en el excel.

    ResponderEliminar

Alguna duda?