Exportar reportes de JasperReports a pdf,xls y html en aplicaciones web.

Hace poco estube trabajando (para fines academico) en una aplicación web , y como toda apliación con un minimo grado de respeto, se hizo necesario generar reportes.  Conocía JasperReports, una gran herramienta para generar reportes en Java; al igual que iReport, un editor que permite crear los reportes para JasperReports de manera grafica. En anteriores proyectos había trabajado con estas herramientas, pero sólo para aplicaciones de escritorio, nunca los habia utilizado en aplicacion web. Necesitaba que los reportes estubieran disponbles en tres formatos: pdf, xls y html; y como  no sabia qué hacer, tocó buscar. A continuación presento de forma detallada los métodos utilizados para exportar los reportes en los formatos anteriormente mencionados.

import net.sf.jasperreports.engine.JRExporter;
import net.sf.jasperreports.engine.JRExporterParameter;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.JasperManager;
import net.sf.jasperreports.engine.export.JRHtmlExporter;
import net.sf.jasperreports.engine.export.JRHtmlExporterParameter;
import net.sf.jasperreports.engine.export.JRPdfExporter;
import net.sf.jasperreports.engine.export.JRXlsExporter;
import net.sf.jasperreports.engine.export.JRXlsExporterParameter;
import net.sf.jasperreports.j2ee.servlets.ImageServlet;
import net.sf.jasperreports.engine.JRException;

public class Reportes extends HttpServlet {    //usamos un Servlet para generar los reportes
private String rutaRep;

public void init(ServeletConfig fgc)
{
   rutaRep = fgc.getServletContext().getRealPath("Directorio_de_los_Reportes");
}

//Método que exporta el reporte en pdf
private void exportPdf( HttpServletResponse response,String narchivo,HashMap param) throws IOException
{
response.setContentType("application/pdf");
JasperReport js;
JasperPrint jp;
JRExporter exporter=null;
OutputStream op=response.getOutputStream();
try{
 js = JasperManager.compileReport(rutaRep+"\\"+narchivo);
 jp = JasperManager.fillReport(js,param,Motor.getConexion());
 byte[] bites = JasperExportManager.exportReportToPdf(jp);
 response.setHeader("Content-disposition", "attachment; filename=Informe.pdf");
 response.setContentLength(bites.length);
 op.write(bites);
 op.close();
 }
 catch(Exception e)
 {
  JOptionPane.showMessageDialog(null,e);
 }
}

//exporta en html
private void exportHtml(HttpServletResponse response,String narchivo,HashMap param) throws IOException
{
 response.setContentType("text/html");
 JasperReport js;
 JasperPrint jp;
 JRExporter exporter=null;
 try{
 js = JasperManager.compileReport(rutaRep+"\\"+narchivo);
 jp = JasperManager.fillReport(js,param,Motor.getConexion());
 exporter = new JRHtmlExporter();
 exporter.setParameter(JRExporterParameter.JASPER_PRINT,jp);
 exporter.setParameter(JRExporterParameter.OUTPUT_WRITER,response.getWriter());
 exporter.setParameter(JRHtmlExporterParameter.IMAGES_URI, request.getContextPath() + "/image?image=");

 if(exporter!=null)
 exporter.exportReport();
 }
 catch(Exception e)
 {
 JOptionPane.showMessageDialog(null,e);
 }
}

//exporta a xls
private void exportXls(HttpServletResponse response,String narchivo,HashMap param) throws IOException
 {
 try{   

 JasperReport report = JasperCompileManager.compileReport(rutaRep+"\\"+narchivo);
 JasperPrint print = JasperFillManager.fillReport(report,param,Motor.getConexion());
 OutputStream out = response.getOutputStream();

 ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream();
 JRXlsExporter exporterXLS = new JRXlsExporter();                

 exporterXLS.setParameter(JRXlsExporterParameter.JASPER_PRINT, print);
 exporterXLS.setParameter(JRXlsExporterParameter.OUTPUT_STREAM, arrayOutputStream);
 exporterXLS.setParameter(JRXlsExporterParameter.IS_ONE_PAGE_PER_SHEET, Boolean.FALSE);
 exporterXLS.setParameter(JRXlsExporterParameter.IS_DETECT_CELL_TYPE, Boolean.TRUE);
 exporterXLS.setParameter(JRXlsExporterParameter.IS_WHITE_PAGE_BACKGROUND, Boolean.FALSE);
 exporterXLS.setParameter(JRXlsExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_ROWS, Boolean.TRUE);
 exporterXLS.exportReport();

 response.setHeader("Content-disposition", "attachment; filename=ListadoPDF");
 response.setContentType("application/vnd.ms-excel");
 response.setContentLength(arrayOutputStream.toByteArray().length);
 out.write(arrayOutputStream.toByteArray());
 out.flush();
 out.close();

 }catch(JRException e)
 {
 JOptionPane.showMessageDialog(null,e);;
 }

 }

}

En los 3 metodos mostrados anteriormente son comunes estas dos lineas de codigo:

1) js = JasperManager.compileReport(rutaRep+”\\”+narchivo);
2) jp = JasperManager.fillReport(js,param,Motor.getConexion());

La primera linea se encarga de compilar el reporte, invocando el metodo JasperManager.compileReport(), el cual recibe como parametro la direccion o ruta donde se encuentra el archivo fuente del reporte. En mi caso la variable rutaRep, que se inicializa en el metodo init del servlet, almacena la direccion de la carpeta donde se encuentran alojados los fuentes de los reportes y el parametro narchivo indica el nombre del archivo a seleccionar.

La segunda linea se encarga de llenar el reporte. El metodo invocado recibe tres parametros: el primero de ellos es una referencia al reporte a llenar; el segundo contiene los parametros necesario para llenar el reporte (si no son necesarios se pasa null); y el tercero es una referencia a la conexion con la base de datos, en mi caso utilizo una clase llamada Motor, encargada de gestionar la conexion e invoco su metodo getConexion(), que devuelve precisamente la referencia a la bd.

Ahora solo queda invocar al metodo del servlet correspondiente dependiendo del tipo de formato que selecciona el usuario en la interfaz grafica.  A continuacion muestro un pequeño ejemplo de como invocar los metodos.

protected void doGet(HttpServletRequest request, HttpServletResponse response)
 throws ServletException, IOException {

 String tipo = request.getParameter("tipo");
 if (tipo.equals("pdf")) {
     this.exportPdf(response, "ejemplo.jrxml",null);
  }else if (tipo.equals("xls")) {
    this.exportXls(response, "ejemplo.jrxml",null);
  }

}

Espero y sea de utilidad a alguien.

Hasta otra, Ralf.

2 comentarios en “Exportar reportes de JasperReports a pdf,xls y html en aplicaciones web.

  1. hey tengo una duda, ojalá me puedas ayudar, ya que es un poco urgente: estoy siguiendo todos los pasos, y cuando reviso los parámetros que le estoy enviando al server me doy cuenta de que están correctos y que no vienen vacíos, sin embargo a la hora que genera el reporte me lo muestra en una página nueva del browser, pero es un pdf de una sola página en blanco! probé generando el reporte en una dirección física y efectivamente es una página en blanco; y pues obviamente necesito generarlo correctamente.
    1. Si te tenés alguna idea para poder solucionarlo te agradezco
    2. podrías publicar como estás llamando al servlet (si es desde código o desde la página misma), como le estás pasando los parámetros y el servlet en si mismo??

    Gracias!! y muy buen material!!

  2. Hola!,

    Ojala me puedas ayudar con la siguiente situación:

    Estoy generando reportes usando JasperReport en una aplicacion Web. Los reportes se me generan correctamente. Pero en caso tal de que el reporte sea muy grande se me va a generar una excepcion por falta de memoria. Se que esto se soluciona virtualizando o paginando el reporte, he visto manuales pero todos para aplicaciones de escritorio. De casualidad sabes como implementar virtualizer en aplicaciones Web?

    Gracias!

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s