Cayaqui.MPS.ExcelExport
0.5.0
See the version list below for details.
dotnet add package Cayaqui.MPS.ExcelExport --version 0.5.0
NuGet\Install-Package Cayaqui.MPS.ExcelExport -Version 0.5.0
<PackageReference Include="Cayaqui.MPS.ExcelExport" Version="0.5.0" />
<PackageVersion Include="Cayaqui.MPS.ExcelExport" Version="0.5.0" />
<PackageReference Include="Cayaqui.MPS.ExcelExport" />
paket add Cayaqui.MPS.ExcelExport --version 0.5.0
#r "nuget: Cayaqui.MPS.ExcelExport, 0.5.0"
#:package Cayaqui.MPS.ExcelExport@0.5.0
#addin nuget:?package=Cayaqui.MPS.ExcelExport&version=0.5.0
#tool nuget:?package=Cayaqui.MPS.ExcelExport&version=0.5.0
Cayaqui.MPS.ExcelExport
Exporta colecciones de DTOs a .xlsx usando los atributos del paquete Cayaqui.MPS.Metadata. Simétrico a Cayaqui.MPS.ExcelImport — decorás tu DTO una sola vez y se importa/exporta con formato consistente.
Distribución propietaria — requiere contrato comercial con Cayaqui. Ver
LICENSE.txt.
Dependencias:
Cayaqui.MPS.Metadata(se registra automáticamente conAddMpsExcelExport) + licencia Syncfusion XlsIO.
v0.5.0 — Mining + Risk extensions (3 secciones nuevas + sparklines inline)
3 nuevas secciones para los verticals mining production + risk QRA, plus sparklines opcionales inline en R9C / Schedule Variance:
var report = new ExcelReport()
.AddTitle("Talara U3 · Mining cut-off 2026-04-30")
.AddR9cReport(new R9cReportSection
{
Rows = r9c, Currency = "USD",
TrendData = cpiHistory // 👈 NEW v0.5 — agrega columna "Trend" con sparkline nativo
})
.AddMonteCarloHistogram(new MonteCarloHistogramSection
{
Samples = qraSamples, Bins = 30, Percentiles = new[] { 50, 80, 90 }
})
.AddPhysicalProgressCurve(new PhysicalProgressCurveSection
{
Points = progressPoints, ControlDate = controlDate, ShowGoalLine = true
})
.AddProductionCurve(new ProductionCurveSection
{
Points = production, NameplateRate = 5_000m, Unit = "t/día"
});
| Sección | Output | Contenido |
|---|---|---|
MonteCarloHistogramSection |
sheet "Monte Carlo" |
IChart tipo Histogram + summary header (N, min, max, mean, P50/P80/P90) + tabla de samples ordenados. Bins configurables. |
PhysicalProgressCurveSection |
sheet "Physical Progress" |
Hasta 4 series % (Baseline / Plan / Actual / Forecast) + opcional Goal horizontal en YMax (100%) + opcional ControlDate vertical stripline. |
ProductionCurveSection |
sheet "Production" |
2 series (Plan / Actual) + opcional NameplateRate horizontal stripline (techo de capacidad de planta). |
R9cReportSection.TrendData y ScheduleVarianceTableSection.TrendData |
columna "Trend" inline | Sparkline nativo Excel (IRange.SparklineGroups) por fila — celdas helper en columnas hidden a la derecha. |
DTOs nuevos: PhysicalProgressPoint, ProductionPoint. Helper público: MonteCarloHistogramSection.Percentile(sortedSamples, p) (linear-interpolation NIST C=R7 — mismo método que numpy.percentile default).
Sin breaking changes. Sparklines son opcionales (TrendData = null mantiene el output v0.4.0 idéntico). +27 tests xUnit (120 total). Ver scripts/migrate-to-excelexport-0.5.0.md.
Out of scope (v0.6.0+): WaterfallChartSection — ExcelChartType.Waterfall no existe en XlsIO 33.2.3 (solo Histogram / BoxAndWhisker / Funnel); el workaround con Column_Stacked queda para iteración futura.
v0.4.0 — Executive cut-off report completo (5 secciones nuevas + TableSection<T>)
Suma 5 secciones EVM y desbloquea TableSection<T> (refactor mínimo de ExcelExporter<T>). Ahora un cut-off mensual completo entra en un solo workbook:
var report = new ExcelReport()
.AddTitle("Talara U3 · Cut-off 2026-04-30")
.AddEvmKpiStrip(new EvmKpiStripSection { Snapshot = evmSnapshot })
.AddEvmSCurveChart(new EvmSCurveChartSection { Points = evmPoints, Bac = 10_000_000m })
.AddCashflowChart(new CashflowChartSection { Points = cashflow, CutOffDate = controlDate })
.AddR9cReport(new R9cReportSection { Rows = r9c, Currency = "USD" })
.AddRiskHeatmap(new RiskHeatmapSection { Risks = risks, View = RiskView.Inherente })
.AddScheduleVariance(new ScheduleVarianceTableSection { Rows = variance, WarnThreshold = 5 })
.AddBurndownChart(new BurndownChartSection { Points = burndown, TargetDate = goLive })
.AddTable(controlAccounts, new TableSectionOptions { SheetName = "CAs" });
await using var stream = await ReportExporter.ExportAsync(report);
| Sección | Output | Contenido |
|---|---|---|
EvmKpiStripSection |
sheet "KPIs" |
Strip 8-cols (CPI/SPI/EV/AC/PV/BAC/EAC/VAC) con cell coloring semáforo via EvmThresholds (default 0.95/0.90/1.05/1.10). |
R9cReportSection |
sheet "R9C" |
Reporte de 9 Columnas canónico (AACE 80R-13). 11 cols + freeze + autofilter + variance coloring + totals. |
RiskHeatmapSection |
sheet "Risk Heatmap" + "Risks" |
Matriz Rows×Cols (default 5×5) con cell coloring por score; sheet anexo con tabla de risks. View configurable: Inherente/Residual/Objetivo. |
ScheduleVarianceTableSection |
sheet "Schedule Variance" |
Tabla baseline/current/forecast + columna SV (días) calculada + cell coloring por WarnThreshold + indent visual jerárquico. |
BurndownChartSection |
sheet "Burndown" |
IChart line con 2 series (Remaining vs Ideal calculado), opcional stripline TargetDate. |
TableSection<T> |
sheet custom | Cualquier colección tipada — delega al IExcelExporter<T> ya existente; respeta atributos de MPS.Metadata. |
DTOs nuevos (sin dep en MPS.Components): EvmKpiSnapshot, R9cEntry, RiskItem + RiskView, VarianceRow, BurndownPoint, EvmThresholds, SemaforoColors.
ExcelExporter<T>.ExportAsync (v0.2.0) sigue intacto — el refactor extrajo RenderToSheetAsync interno reusable. Sin breaking changes. +44 tests xUnit (93 total). Ver scripts/migrate-to-excelexport-0.4.0.md.
v0.3.0 — Reportes con secciones + charts EVM nativos
Nueva API IExcelReportExporter para componer reportes multi-sheet con la Curva S de EVM y el Cashflow mensual + acumulado como IChart Excel nativos (no imágenes — refrescables y editables in-Excel):
@inject IExcelReportExporter ReportExporter
var report = new ExcelReport()
.AddTitle("Talara U3 · Cut-off 2026-04-30")
.AddEvmSCurveChart(new EvmSCurveChartSection
{
Points = evmPoints, // PV, EV, AC, Forecast por mes
Bac = 10_000_000m, // stripline horizontal
ControlDate = new DateTime(2026, 4, 30), // stripline vertical
Currency = "USD"
})
.AddCashflowChart(new CashflowChartSection
{
Points = cashflowPoints, // Plan, Actual, Forecast por mes
CutOffDate = new DateTime(2026, 4, 30),
Currency = "USD",
ShowCumulative = true // 3 columnas + 3 líneas acumuladas (dual-axis)
});
await using var stream = await ReportExporter.ExportAsync(report);
Output: workbook con sheet "Cover" (título + branding logos) + "Curva S" (4 series + striplines BAC/ControlDate) + "Cashflow" (combo dual-axis con 6 series + stripline CutOffDate).
DTOs propios del package (sin dependencia con MPS.Components):
public sealed record EvmSCurvePoint(DateTime Date, decimal? Pv, decimal? Ev, decimal? Ac, decimal? Forecast);
public sealed record CashflowPoint(DateTime Date, decimal Plan, decimal Actual, decimal Forecast);
Si tu data layer ya construye los del componente Blazor, mappeás con un LINQ (mismo shape, distinto namespace).
EvmChartPalette expone los colores canónicos (Plan, Earned, Actual, Forecast, Bac, CutOff) como Syncfusion.Drawing.Color reutilizables — paleta #2E5BFF Plan, #7F56D9 EV, #D92D20 Actual, #039855 Forecast. Forecast/EAC siempre dashed para indicar proyección. Las acumuladas las computa CumulativeBuilder con paridad tested vs MPS.Components.Evm.CashflowChart.BuildDisplayPoints — los valores que ves en Excel son los mismos que los del componente Blazor.
AddTable<T> queda para v0.4.0 (out of scope este release; los reportes que requieran tablas combinan IExcelExporter<T>.ExportAsync con IExcelReportExporter.ExportAsync por ahora).
Sin breaking changes. El IExcelExporter<T>.ExportAsync v0.2.0 sigue idéntico. Ver scripts/migrate-to-excelexport-0.3.0.md. +35 tests xUnit (49 total).
Instalación
dotnet add package Cayaqui.MPS.ExcelExport
builder.Services.AddMpsExcelExport();
Atributos consumidos
| Atributo | Efecto en el export |
|---|---|
[Display(Name, Order, GroupName)] / [Label] |
Header de columna + orden |
[Currency] / [Percentage] / [Date] / [Integer] / [DecimalFormat] / [Duration] |
Formato de celda nativo (number format string) |
[Align] |
Horizontal alignment (Left/Center/Right) |
[ColumnWidth(px)] |
Ancho de columna |
[VisibleIn(RenderTargets.Web)] / [Hidden] |
Columna omitida del export si no incluye Excel |
[Badge(BadgeKind.Success)] |
Background color de las celdas de la columna |
[UpperCase] / [LowerCase] / [TitleCase] / [Truncate] |
Transform aplicado al string antes de escribir |
[ImportIgnore] |
Excluida también del export (simetría) |
[Mask]NO se aplica al export — exportar datos enmascarados sería un bug (pierde el valor original para ediciones). Se respeta el valor sin máscara para que Excel edite bien.
Convenciones importantes
[Percentage] — almacenar ratio 0.0–1.0
Excel interpreta el formato 0.0% multiplicando el valor por 100. Almacenar 75.6 en el DTO produciría 7560% en la celda. Convención correcta:
[Percentage(1)]
public decimal Cpi { get; set; } // ← almacenar 0.756, NO 75.6
Al exportar, la celda se ve 75.6%. Al importar (round-trip), se recupera 0.756.
[Badge] con enum values — color por fila
Sobre una propiedad enum con [BadgeColor] en cada valor, cada fila recibe el color correspondiente al valor de esa fila:
public enum Status
{
[BadgeColor(BadgeKind.Success)] Approved,
[BadgeColor(BadgeKind.Error)] Rejected
}
[Badge] public Status RowStatus { get; set; }
// En Excel: filas con Approved → verde, filas con Rejected → rojo
[Badge(BadgeKind.Success)] (FixedKind) → toda la columna del mismo color.
Uso
public sealed class InvoiceRow
{
[Display(Name = "N°", Order = 1)]
public int InvoiceNumber { get; set; }
[Label("Cliente")] [Display(Order = 2)]
public string CustomerName { get; set; } = "";
[Currency("USD", 2)] [Align(TextAlign.Right)] [ColumnWidth(120)] [Display(Order = 3)]
public decimal Amount { get; set; }
[Date("dd-MMM-yyyy")] [Display(Order = 4)]
public DateTime IssueDate { get; set; }
[Badge(BadgeKind.Success)] [Display(Order = 5)]
public bool IsPaid { get; set; }
[Hidden]
public int InternalId { get; set; }
}
public class InvoiceExportService(IExcelExporter<InvoiceRow> exporter)
{
public async Task<Stream> GenerateAsync(IEnumerable<InvoiceRow> rows)
{
return await exporter.ExportAsync(rows, new ExcelExportOptions
{
SheetName = "Invoices",
FreezeHeaderRow = true,
AutoFilter = true,
HeaderBackgroundColor = "#D9E1F2"
});
}
}
ExcelExportOptions
public sealed class ExcelExportOptions
{
string SheetName = "Data";
bool IncludeHeader = true;
bool StyleHeader = true; // bold + background
string HeaderBackgroundColor = "#D9E1F2";
bool FreezeHeaderRow = true;
bool AutoFilter = true;
bool AutoFitColumns = false; // usa [ColumnWidth] cuando se declara
CultureInfo Culture = CultureInfo.InvariantCulture;
}
Tipos nativos vs texto
El exporter respeta el tipo de .NET para que Excel los trate como datos reales (números son sumables, fechas son filtrables):
| .NET | Excel cell type |
|---|---|
int, long, short, byte, decimal, double, float |
Number |
bool |
Boolean |
DateTime, DateTimeOffset, DateOnly |
DateTime (con format por [Date]) |
Enum |
Text (nombre del valor) |
string |
Text (con transforms opcionales) |
Round-trip Export → Import
var rows = new[] { new InvoiceRow { ... } };
await using var exported = await exporter.ExportAsync(rows); // DTO → xlsx
var result = await importer.ImportAsync(exported); // xlsx → DTO
// result.Rows[0] === rows[0] (values preserved)
Este roundtrip está cubierto por tests.
Tests
Proyecto MPS.Infrastructure.ExcelExport.Tests — 9 tests ✅:
- Header + row values con types nativos (number, text, bool)
[Hidden]excluye columna[Display(Order)]respeta orden declarado[VisibleIn(Web)](sin Excel flag) omite columna[Currency]aplica number format a celdas- Header styled bold + freeze pane activa
- Empty collection produce output sólo con header
- Round-trip: Export → Import preserva valores (int, string, decimal)
Requisitos
- .NET 10.0 o superior
Cayaqui.MPS.Metadata(auto-registrado conAddMpsExcelExport)- Licencia Syncfusion Essential Studio (XlsIO)
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Cayaqui.MPS.Metadata (>= 0.4.0)
- Cayaqui.MPS.Storage (>= 0.2.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.7)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.7)
- Syncfusion.XlsIO.Net.Core (>= 33.2.3)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.9.1 | 189 | 5/26/2026 |
| 0.9.0 | 81 | 5/26/2026 |
| 0.7.4 | 160 | 5/19/2026 |
| 0.7.3 | 89 | 5/19/2026 |
| 0.7.2 | 92 | 5/18/2026 |
| 0.7.1 | 89 | 5/18/2026 |
| 0.7.0 | 96 | 5/18/2026 |
| 0.6.0 | 96 | 5/18/2026 |
| 0.5.1 | 135 | 5/10/2026 |
| 0.5.0 | 94 | 5/10/2026 |
| 0.4.0 | 97 | 5/10/2026 |
| 0.3.0 | 95 | 5/10/2026 |
| 0.2.0 | 397 | 4/24/2026 |
| 0.1.1 | 110 | 4/24/2026 |
| 0.1.0 | 116 | 4/24/2026 |
0.5.0 — Mining + Risk extensions. 3 secciones EVM nuevas: MonteCarloHistogramSection (output canonico de QRA con bins configurables y summary P50/P80/P90 — usa ExcelChartType.Histogram nativo), PhysicalProgressCurveSection (Baseline/Plan/Actual/Forecast en %, con goal line en YMax=100% opcional y ControlDate vertical stripline), ProductionCurveSection (Plan vs Actual mining + opcional NameplateRate horizontal stripline). Plus sparklines inline opcionales en R9cReportSection.TrendData y ScheduleVarianceTableSection.TrendData (IReadOnlyDictionary indexado por Code/WbsCode) usando IRange.SparklineGroups nativo de Excel — agrega una columna "Trend" con sparkline por fila. DTOs nuevos: PhysicalProgressPoint, ProductionPoint. Helper publico MonteCarloHistogramSection.Percentile (linear-interpolation NIST C=R7). Waterfall queda fuera de scope: ExcelChartType.Waterfall no existe en XlsIO 33.2.3, el workaround con Column_Stacked queda para v0.6.0. Sin breaking changes — sparklines opt-in via TrendData null. +27 tests xUnit (120 total). Ver scripts/migrate-to-excelexport-0.5.0.md. v0.4.0 — Executive cut-off report completo. Cinco secciones EVM nuevas: EvmKpiStripSection (strip CPI/SPI/EV/AC/PV/BAC/EAC/VAC con cell coloring semaforo via EvmThresholds), R9cReportSection (Reporte de 9 Columnas canonico AACE 80R-13 con 11 cols + variance coloring + totals), RiskHeatmapSection (matriz NxM con cell coloring por score + sheet anexo de Risks; view configurable Inherente/Residual/Objetivo), ScheduleVarianceTableSection (baseline/current/forecast + SV dias + threshold coloring + indent jerarquico), BurndownChartSection (Remaining vs Ideal + opcional TargetDate stripline). Y TableSection<T> desbloqueada — refactor minimo de ExcelExporter<T> extrayendo RenderToSheetAsync internal reusable, sin breaking. DTOs nuevos: EvmKpiSnapshot, R9cEntry, RiskItem + RiskView, VarianceRow, BurndownPoint, EvmThresholds, SemaforoColors. +44 tests xUnit (93 total). Sin breaking changes — IExcelExporter<T>.ExportAsync sigue identico. Ver scripts/migrate-to-excelexport-0.4.0.md. v0.3.0 — EVM charts nativos en .xlsx (Curva S + Cashflow), refrescables (no imagenes). Nueva API IExcelReportExporter con builder fluido ExcelReport: AddTitle/AddEvmSCurveChart/AddCashflowChart. EvmSCurveChartSection produce 4 series (PV/EV/AC/EAC) sobre IChart combo, con BAC stripline horizontal y ControlDate stripline vertical (ambos como series auxiliares 2-puntos con LinePattern.Dash). CashflowChartSection produce combo dual-axis: 3 columnas (Plan/Actual/Forecast en eje primario) + 3 lineas acumuladas (Plan cum/Actual cum/Forecast cum dashed en eje secundario), con CutOffDate stripline vertical. CumulativeBuilder reproduce con paridad tested la logica de MPS.Components.Evm.CashflowChart.BuildDisplayPoints (cumsum con anchor del Forecast cum en el ultimo Actual cum <= cutoff). Paleta canonica MPS: Plan #2E5BFF, EV #7F56D9, Actual #D92D20, Forecast #039855. AddTable<T> queda para v0.4.0. Sin breaking changes — IExcelExporter<T>.ExportAsync de v0.2.0 sigue identico. +35 tests xUnit (49 total). Ver scripts/migrate-to-excelexport-0.3.0.md. v0.2.0 — HideGridlines (default true) + ExcelExportOptions.Logos (Owner + Cayaqui logos). v0.1.1 — patches. v0.1.0 — Initial release: IExcelExporter<T> con Metadata-attribute-driven header labels, cell format, alignment, width, visibility, column order, badge-based background color.