Descargar Excel

publicado por: Anonymous

Tengo una función que crea un archivo excel, sin embargo la función que genera el excel guarda en disco. Lo que quiero saber es como lograr que el excel que genero se pueda descargar al presionar un boton desde un formulario de primefaces.

xhtml:

<h:form>
    <p:commandButton action="#{controller.descargar}" value="descargar"/>
</h:form>

Bean:

@Named(value = "controller")
@SessionScoped 
public class ClientsCtrl {
    public void descargar(){
        GeneraExcel gExcel = new GeneraExcel();
        gExcel.crearExcel();

    }
}

GeneraExcel:

public class GeneraExcel {

public void crearExcel() {
    try {
        String filename = "C:/NewExcelFile.xls";
        HSSFWorkbook workbook = new HSSFWorkbook();
        HSSFSheet sheet = workbook.createSheet("FirstSheet");

        HSSFRow rowhead = sheet.createRow((short) 0);
        rowhead.createCell(0).setCellValue("No.");
        rowhead.createCell(1).setCellValue("Name");
        rowhead.createCell(2).setCellValue("Address");
        rowhead.createCell(3).setCellValue("Email");

        HSSFRow row = sheet.createRow((short) 1);
        row.createCell(0).setCellValue("1");
        row.createCell(1).setCellValue("Sankumarsingh");
        row.createCell(2).setCellValue("India");
        row.createCell(3).setCellValue("lalalla.com");

        FileOutputStream fileOut = new FileOutputStream(filename);
        workbook.write(fileOut);
        fileOut.close();
        System.out.println("Your excel file has been generated!");

    } catch (Exception ex) {
        System.out.println(ex);
    }
}

}

solución

La forma en la que lo resolvì fue la siguiente :

Poner false a la propiedad ajax del xhtml :

<h:form>
    <p:commandButton action="#{controller.descargar}"
        value="descargar" ajax ="false"/>
</h:form>

Bean :

@Named(value = "controller")
@SessionScoped 
public class ClientsCtrl {
    public void descargar(){
    //Obtenemos el contexto de jsf
    FacesContext fc = FacesContext.getCurrentInstance();
    ExternalContext ec = fc.getExternalContext();
    //Le asignamos un nombre
    String name = "Mi excel.xls");
    ec.responseReset();
    //Esto es importante y tiene que ver con el tipo de archivo, esté 
        //caso es para un excel
    ec.setResponseHeader("Content-Type", application/vnd.ms-excel));
    ec.setResponseHeader("Content-Disposition", "attachment; filename="" + name + """);
    //Trataremos de obtener un outputStream
    try (OutputStream output = ec.getResponseOutputStream()) {
    //Invocamos el objeto que devuelve el excel y le pasamos el outputStream
        GeneraExcel gExcel = new GeneraExcel();
    gExcel.crearExcel(output;

        //Con esto obtenemos el tamaño del archivo
        try (CountingOutputStream co = new CountingOutputStream(output)) {
            ec.setResponseContentLength((int) co.getByteCount());
            co.close();
        } catch (IOException ex) {
            System.out.println("Error al obtener el tamaño del stream " + ex.getMessage());
        }
    } catch (Exception e) {
        System.out.println("Error al intentar crear el excel " + e.getMessage());
    }

    fc.responseComplete();
    }
}

GeneraExcel:

public class GeneraExcel {
//Cambie mucho la implementación de esta parte, pero el resultado es el mismo.
//Entre los cambios importantes es que ahora solicito un OutputStream

    public void crearExcel(OutputStream outputStream) {
          try {
        Workbook wb = new HSSFWorkbook();
        Sheet sheet = wb.createSheet("MySheet");
        CreationHelper createHelper = wb.getCreationHelper();

        // Create a row and put some cells in it. Rows are 0 based.
        Row row = sheet.createRow((short) 0);
        Cell cell = row.createCell(0);
        cell.setCellValue(1);
        row.createCell(1).setCellValue(1.2);
        row.createCell(2).setCellValue(createHelper.createRichTextString("This is a string"));
        row.createCell(3).setCellValue(true);
        row.createCell(5).setCellValue("soy el 5");



        row = sheet.createRow(3);
        cell.setCellValue("hola");   
     row.createCell(6).setCellValue("soy el 6");

     //Escribimos sobre el outputStrream y luego le hacemos flush y lo cerramos para sincronizarlo
        wb.write(outputStream);
        outputStream.flush();
        outputStream.close();

    } catch (IOException ex) {
        System.out.println(ex);
    }
    }

}
Respondido por: Anonymous

Leave a Reply

Your email address will not be published.