Exportación
Visión general
La exportación permite llevar los datos de Crono a archivos que se descargan o comparten fuera del sistema. A diferencia de otros frameworks orientados a feeds de productos con proveedores instalables, en Crono la exportación está orientada a reportes y grillas: cada reporte o listado provee su propio exportador, casi siempre a Excel.
Los exportadores se apoyan en tres piezas compartidas:
- Biblioteca Excel: se usa EPPlus (
OfficeOpenXml) para construir los libros de cálculo. - Cabecera institucional:
ICabeceraExcelRenderizadordibuja una cabecera estándar (logo, empresa, usuario, título y filtros) en la hoja. - Guardado de descargas:
IReporteServicio.GuardarComoDescargaAsyncpersiste el archivo generado y devuelve el resultado de descarga.
Exportador por reporte
Un exportador típico expone una interfaz con un método ExportarAsync que devuelve un ErrorO<DescargaResultadoDto> (patrón de resultado con posibles errores). Recibe los mismos filtros que el reporte (fecha de corte, rango, etc.).
public interface IBalanceGeneralExcelExportador
{
Task<ErrorO<DescargaResultadoDto>> ExportarAsync(
DateOnly? fechaCorte = null,
CancellationToken token = default);
}
La implementación obtiene los datos del servicio del reporte, renderiza la cabecera estándar, escribe las filas y guarda el archivo como descarga:
public class BalanceGeneralExcelExportador : IBalanceGeneralExcelExportador
{
private readonly IBalanceGeneralReporteServicio _balance;
private readonly ICabeceraExcelRenderizador _cabecera;
private readonly IReporteServicio _reporteServicio;
public BalanceGeneralExcelExportador(
IBalanceGeneralReporteServicio balance,
ICabeceraExcelRenderizador cabecera,
IReporteServicio reporteServicio)
{
_balance = balance;
_cabecera = cabecera;
_reporteServicio = reporteServicio;
}
public async Task<ErrorO<DescargaResultadoDto>> ExportarAsync(
DateOnly? fechaCorte = null, CancellationToken token = default)
{
var balanceOError = await _balance.ObtenerBalanceAsync(fechaCorte, token);
if (balanceOError.EsError)
return balanceOError.Errores;
var dto = balanceOError.Valor;
using var paquete = new ExcelPackage();
var hoja = paquete.Workbook.Worksheets.Add("Balance General");
// Cabecera institucional estándar
var cabecera = await _cabecera.RenderizarAsync(hoja, new CabeceraExcelOpciones
{
Titulo = $"Balance General al {dto.FechaCorte:dd/MM/yyyy}",
TotalColumnas = 2,
TextoFiltros = $"Moneda: {dto.MonedaSimbolo} ({dto.MonedaCodigo})"
}, token);
int fila = cabecera.FilaInicioTabla;
// ... escribir grupos, filas y totales a partir de "fila" ...
// Guardar el archivo como descarga y devolver el resultado
// return await _reporteServicio.GuardarComoDescargaAsync(paquete, ...);
}
}
La cabecera estándar (CabeceraExcelOpciones: Titulo, TotalColumnas, TextoFiltros) devuelve la fila a partir de la cual empieza la tabla (FilaInicioTabla), de modo que todos los reportes comparten el mismo encabezado con logo, empresa y usuario.
Exportación desde reportes y grillas
En la práctica, la exportación aparece de dos formas:
- Exportadores dedicados de un reporte, como
BalanceGeneralExcelExportador, o métodosExportaciondentro del servicio del reporte (por ejemploCalidadCarteraServicio.Exportacion). Se invocan desde una acciónExportar...del controlador. - Exportación de grilla: los listados construidos con el componente de grilla (
grilladatos) ofrecen un botón de exportar a Excel que envía los ids seleccionados (o todos) a la acción de exportación correspondiente.
Ejemplos reales en el módulo de reportes: BalanceGeneralExcelExportador, CalidadCarteraServicio.Exportacion, y los distintos métodos Exportar...ExcelAsync (comprobantes de pago, préstamos desembolsados, pagos directos, cobranzas de campo, etc.).
Buenas prácticas
- Reutiliza siempre
ICabeceraExcelRenderizadorpara que todos los archivos compartan la misma identidad visual (logo, empresa, usuario, fecha, filtros aplicados). - Devuelve
ErrorO<DescargaResultadoDto>y guarda el archivo conIReporteServicio.GuardarComoDescargaAsync, en lugar de escribir en disco manualmente, para que la descarga quede registrada y disponible. - Mantén los totales al pie y respeta el formato de moneda y fechas de la organización.
Crono aún no cuenta con un framework de proveedores de exportación instalables ni con perfiles/programación de exportación como otros sistemas de comercio. Si en el futuro se requiere (por ejemplo, feeds recurrentes hacia terceros), esta sección se ampliará con ese diseño.