Exportación masiva de informes a archivos Excel

Descripción del Requerimiento

Los informes pueden exportarse a archivos Excel mediante un botón en la barra de herramientas después de su visualización. Sin embargo, en la práctica, a menudo se requiere exportar informes directamente sin mostrarlos previamente, y frecuentemente se necesita realizar exportaciones masivas a archivos Excel. A continuación se persentan varios ejemplos sobre cómo generar archivos Excel masivamente sin mostrar los informes.

Para implementar este tipo de requerimientos generalmente se utiliza el enfoque de API para generar archivos Excel masivamente. Según el método utilizado, se pueden clasificar aproximadamente en tres categorías:

Primero: Exportación de una sola tabla a múltiples hojas en un solo archivo Excel

Segundo: Exportación de múltiples tablas a múltiples hojas en un solo archivo Excel

Tercero: Exportación de múltiples tablas a múltiples archivos Excel

Una tabla con múltiples hojas

Este enfoque generalmente se utiliza cuando el formato del informe es fijo, y luego se filtran los datos según un parámetro específico. Al exportar a Excel, se requiere exportar datos de múltiples parámetros, colocando cada conjunto de datos en diferentes hojas del mismo archivo Excel. Por ejemplo, en este caso se realizan estadísticas de pedidos por región, y al exportar, cada conjunto de datos regional debe ir a una hoja separada, utilizando el nombre de la región como nombre de la hoja. Veamos cómo hacerlo:

La interfaz de diseño del informe no necesita mucha explicación, simplemente diseña según los requisitos, como se muestra en la siguiente imagen:

Se agrega un parámetro al informe: area, para recibir el parámetro regional, y luego se filtran los datos en el conjunto de datos a través de este parámetro.

El código JSP utilizado en la API es el siguiente:

<%@ page contentType="text/html;charset=UTF-8" %>
<%@ page import="com.raqsoft.report.model.*"%>
<%@ page import="com.raqsoft.report.usermodel.*"%>
<%@ page import="com.raqsoft.report.view.*"%>
<%@ page import="com.raqsoft.report.util.*"%>
<%@ page import="com.raqsoft.report.view.excel.ExcelReport"%>
<%
String archivoInforme = request.getParameter("informe");
if(archivoInforme==null) archivoInforme="pedidos.rpx";
String nombreArchivo=archivoInforme.substring(0,archivoInforme.length()-4);
String rutaInforme = request.getRealPath("WEB-INF\\informes\\"+archivoInforme);
String directorioExportacion=request.getRealPath("/salida");
DefinicionInforme dd = (DefinicionInforme)UtilidadesInforme.read(rutaInforme);
String regiones="norte,este,sur,oeste,noreste;suroeste";
String[] region=regiones.split(",");
ReporteExcel re=new ReporteExcel();
for(int idx=0;idx<region.length;idx++){
Contexto contexto = new Contexto();
contexto.setParamValue("area",region[idx]);
Motor motor = new Motor(dd, contexto);
IInforme informeResultante = motor.calcular();
re.exportar(region[idx],informeResultante);
}
re.guardarEn(directorioExportacion+"/"+nombreArchivo+".xls");
%>

De esta manera, se generará el archivo Excel correspondiente en el directorio de exportación ubicado en la raíz de la aplicación. El archivo Excel generado será similar al siguiente:

Múltiples tablas con múltiples hojas

Este caso se aplica cuando el archivo Excel a exportar está compuesto por múltiples informes, donde cada informe se exporta a diferentes hojas en el archivo Excel, y posiblemente cada informe tenga parámetros diferentes (si los parámetros son iguales, entonces sería similar al primer ejemplo, solo que se haría un bucle según los nombres de los informes). Veamos el proceso de implementación específico:

Dado que los parámetros de diferentes informes pueden ser distintos, la dificultad de analizar cada informe y sus parámetros corespondientes en la API puede ser bastante grande. En este ejemplo, se requiere acceder al informe a través de URL en un formato específico, por ejemplo:

http://localhost:6868/demo/informeJsp/exportarExcel1.jsp?informe={nombre-informe-sin-parametros1}{nombre-informe-sin-parametros2}{informe1(param1=valor1;param2=valor2;...)}{informe2(param1=valor1;param2=valor2;...)}, por ejemplo: http://localhost:6868/demo/informeJsp/exportarExcel1.jsp?informe={prueba1.rpx}{prueba2.rpx(arg1=11;arg2=22;arg3=33)}

En versiones más recientes de Tomcat, hay ciertas restricciones con símbolos especiales, por lo que puedes convertir los símbolos {} a sus equivalentes en codificación URL, { es %7B y } es %7D. Si hay otros valores, realiza las conversiones correspondientes. Después de configurar la URL, veamos cómo analizarla y generar archivos Excel masivamente:

<%@ page contentType="text/html;charset=UTF-8" %>
<%@ page import="com.raqsoft.report.model.*"%>
<%@ page import="com.raqsoft.report.usermodel.*"%>
<%@ page import="com.raqsoft.report.view.*"%>
<%@ page import="com.raqsoft.report.util.*"%>
<%@ page import="com.raqsoft.report.view.excel.ExcelReport"%>
<%
request.setCharacterEncoding("UTF-8");
String parametro = request.getParameter("informe");
if(parametro == null || parametro.trim().length() == 0) 
throw new Exception("Ingrese el nombre del archivo de informe y cadena de parámetros: informe={nombre-sin-parametros}{informe1(param1=valor1;param2=valor2;...)}{informe2(param1=valor1;param2=valor2;...)}...");
String rutaSalida=request.getRealPath("/salida");
String paramTemp1=parametro.replace("}","");
String paramTemp2=paramTemp1.substring(1,paramTemp1.length());
String[] arrayParametros=paramTemp2.split("\\{");
ReporteExcel re=new ReporteExcel();
for(int i=0;i<arrayParametros.length;i++){
if(arrayParametros[i].lastIndexOf("(")<=0){
String rutaInformes = request.getRealPath("WEB-INF\\informes\\"+arrayParametros[i]);
String nombreHoja=arrayParametros[i].substring(0,arrayParametros[i].length()-4);
DefinicionInforme dd = (DefinicionInforme)UtilidadesInforme.read(rutaInformes);
Contexto contexto = new Contexto();
Motor motor = new Motor(dd, contexto);
IInforme informeCalculado = motor.calcular();
re.exportar(nombreHoja,informeCalculado);
}else{
System.out.println("El informe tiene parámetros, nombre del informe="+arrayParametros[i].split("\\(")[0]);
String rutaInformes = request.getRealPath("WEB-INF\\informes\\"+arrayParametros[i].split("\\(")[0]);
String nombreHoja=arrayParametros[i].split("\\(")[0].substring(0,arrayParametros[i].split("\\(")[0].length()-4);
DefinicionInforme dd = (DefinicionInforme)UtilidadesInforme.read(rutaInformes);
Contexto contexto = new Contexto();
String[] parametrosArray=arrayParametros[i].split("\\(")[1].replace(")","").split(";");
for(int j=0;j<parametrosArray.length;j++){
contexto.setParamValue(parametrosArray[j].split("=")[0],parametrosArray[j].split("=")[1]);
}
Motor motor = new Motor(dd, contexto);
IInforme informeCalculado = motor.calcular();
re.exportar(nombreHoja,informeCalculado);
}
}
re.guardarEn(rutaSalida+"/prueba.xls");
%>
Múltiples tablas, múltiples archivos Excel

Este enfoque es similar al segundo ejemplo. En la práctica, al exportar archivos Excel, se requiere que cada informe se exporte como un archivo Excel diferente. Sin embargo, posteriormente puede haber problemas relacionados con la descarga, por lo que generalmente se crea un directorio temporal donde se colocan múltiples archivos Excel para permitir la descarga por lotes. Código específico a continuación:

<%@ page contentType="text/html;charset=UTF-8" %>
<%@ page import="com.raqsoft.report.model.*"%>
<%@ page import="com.raqsoft.report.usermodel.*"%>
<%@ page import="com.raqsoft.report.view.*"%>
<%@ page import="com.raqsoft.report.util.*"%>
<%@ page import="com.raqsoft.report.view.excel.ExcelReport"%>
<%
request.setCharacterEncoding("UTF-8");
String parametro = request.getParameter("informe");
if(parametro == null || parametro.trim().length() == 0) 
throw new Exception("Ingrese el nombre del archivo de informe y cadena de parámetros: informe={nombre-sin-parametros}{informe1(param1=valor1;param2=valor2;...)}{informe2(param1=valor1;param2=valor2;...)}...");
String rutaSalida=request.getRealPath("/salida");
String nombreTemporal=Double.toString(Math.random()*100000000).toString().substring(0,6);
String rutaExcel=rutaSalida+"\\"+nombreTemporal;
java.io.File carpeta = new java.io.File(rutaExcel);
if(!carpeta.exists()) {
carpeta.mkdirs();
}
String paramTemp1=parametro.replace("}","");
String paramTemp2=paramTemp1.substring(1,paramTemp1.length());
String[] arrayParametros=paramTemp2.split("\\{");
ReporteExcel re=new ReporteExcel();
for(int i=0;i<arrayParametros.length;i++){
if(arrayParametros[i].lastIndexOf("(")<=0){
String rutaInformes = request.getRealPath("WEB-INF\\informes\\"+arrayParametros[i]);
String nombreHoja=arrayParametros[i].substring(0,arrayParametros[i].length()-4);
DefinicionInforme dd = (DefinicionInforme)UtilidadesInforme.read(rutaInformes);
Contexto contexto = new Contexto();
Motor motor = new Motor(dd, contexto);
IInforme informeCalculado = motor.calcular();
UtilidadesInforme.exportarAExcel2007(rutaExcel+"/"+nombreHoja+".xlsx",informeCalculado,false);
}else{
String rutaInformes = request.getRealPath("WEB-INF\\informes\\"+arrayParametros[i].split("\\(")[0]);
String nombreHoja=arrayParametros[i].split("\\(")[0].substring(0,arrayParametros[i].split("\\(")[0].length()-4);
DefinicionInforme dd = (DefinicionInforme)UtilidadesInforme.read(rutaInformes);
Contexto contexto = new Contexto();
String[] parametrosArray=arrayParametros[i].split("\\(")[1].replace(")","").split(";");
for(int j=0;j<parametrosArray.length;j++){
contexto.setParamValue(parametrosArray[j].split("=")[0],parametrosArray[j].split("=")[1]);
}
Motor motor = new Motor(dd, contexto);
IInforme informeCalculado = motor.calcular();
UtilidadesInforme.exportarAExcel2007(rutaExcel+"/"+nombreHoja+".xlsx",informeCalculado,false);
}
}
re.guardarEn(rutaSalida+"/prueba.xls");
%>

Etiquetas: Excel report-generation batch-export jsp-api multiple-sheets

Publicado el 10-12 00:23