Skip to main content

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: ICabeceraExcelRenderizador dibuja una cabecera estándar (logo, empresa, usuario, título y filtros) en la hoja.
  • Guardado de descargas: IReporteServicio.GuardarComoDescargaAsync persiste 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, ...);
}
}
info

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étodos Exportacion dentro del servicio del reporte (por ejemplo CalidadCarteraServicio.Exportacion). Se invocan desde una acción Exportar... 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 ICabeceraExcelRenderizador para que todos los archivos compartan la misma identidad visual (logo, empresa, usuario, fecha, filtros aplicados).
  • Devuelve ErrorO<DescargaResultadoDto> y guarda el archivo con IReporteServicio.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.
note

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.