Cayaqui.MPS.ExcelExport
0.9.1
dotnet add package Cayaqui.MPS.ExcelExport --version 0.9.1
NuGet\Install-Package Cayaqui.MPS.ExcelExport -Version 0.9.1
<PackageReference Include="Cayaqui.MPS.ExcelExport" Version="0.9.1" />
<PackageVersion Include="Cayaqui.MPS.ExcelExport" Version="0.9.1" />
<PackageReference Include="Cayaqui.MPS.ExcelExport" />
paket add Cayaqui.MPS.ExcelExport --version 0.9.1
#r "nuget: Cayaqui.MPS.ExcelExport, 0.9.1"
#:package Cayaqui.MPS.ExcelExport@0.9.1
#addin nuget:?package=Cayaqui.MPS.ExcelExport&version=0.9.1
#tool nuget:?package=Cayaqui.MPS.ExcelExport&version=0.9.1
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.9.0 — CoverSheetSection: logo Cayaqui en footer
CoverSheetSection agrega un área de footer al final de la portada con el logo corporativo Cayaqui (izquierda) y el texto "Powered by Cayaqui · MPS Project Suite" (derecha). Se activa pasando LogoOptions.MpsCompanyLogo en ExcelExportOptions.Logos.
var logos = new LogoOptions
{
OwnerLogo = new BytesLogo { Bytes = ownerLogoBytes },
MpsCompanyLogo = new BytesLogo { Bytes = cayaquiLogoBytes } // nuevo
};
var opts = new ExcelExportOptions
{
Theme = theme,
Logos = logos
};
v0.8.0 — Template corporativo: CoverSheetSection + ReportTheme
Sistema de branding unificado para workbooks profesionales. Un solo ReportTheme configura la portada, footer y tab color de todas las hojas.
var theme = new ReportTheme
{
ReportTitle = "Monthly Project Report",
ProjectName = "Talara U3 — Expansion",
CompanyName = "Cayaqui S.A.",
PreparedBy = "Project Controls Team",
Version = "1.0",
ReportDate = new DateTime(2026, 4, 30),
ConfidentialityLabel = "CONFIDENCIAL",
PrimaryColorHex = "#0F2044", // deep navy
AccentColorHex = "#C9961A", // amber gold
TitleFont = "Calibri Light",
BodyFont = "Calibri"
};
var report = new ExcelReport()
.AddCoverSheet() // portada corporativa oscura
.AddEvmKpiStrip(new EvmKpiStripSection { Snapshot = kpiSnapshot })
.AddEvmSCurveChart(new EvmSCurveChartSection { Points = sCurve, Bac = 10_000_000m })
.AddCashflowChart(new CashflowChartSection { Points = cashflow });
var stream = await exporter.ExportAsync(report, new ExcelExportOptions { Theme = theme });
CoverSheetSection genera un sheet con:
- Banda superior oscura (primary color) con logos cliente/Cayaqui
- Título del reporte (26pt, Calibri Light) + nombre del proyecto + fecha
- Franja de acento ámbar superior e inferior
- Tabla de información: Proyecto / Empresa / Preparado por / Fecha / Versión / Clasificación
Footer automático aplicado a todas las hojas cuando Theme está configurado:
- Izquierda: fecha del reporte (formato
dd-MMM-yy) - Centro:
ConfidentialityLabel(ej."CONFIDENCIAL") - Derecha:
"Página &P de &N"
Tab color: todas las hojas (excepto Cover) reciben PrimaryColorHex como color de pestaña.
ReportTheme.MpsCorporateDark es el preset default (deep navy #0F2044 + amber #C9961A). Se activa automáticamente cuando Theme = null en CoverSheetSection.
| Propiedad | Default |
|---|---|
PrimaryColorHex |
"#0F2044" (deep navy) |
AccentColorHex |
"#C9961A" (amber gold) |
TitleFont |
"Calibri Light" |
BodyFont |
"Calibri" |
ConfidentialityLabel |
"CONFIDENCIAL" |
Version |
"1.0" |
Logos se configuran en ExcelExportOptions.Logos:
var options = new ExcelExportOptions
{
Theme = theme,
Logos = new LogoOptions
{
OwnerLogo = new BytesLogo(ownerLogoBytes),
CayaquiLogo = new BytesLogo(cayaquiLogoBytes)
}
};
Sin breaking changes. Requiere Cayaqui.MPS.ReportModels ≥ 0.4.0.
v0.7.4 — R9C esquema actualizado
R9cReportSection ahora usa el nuevo esquema R9C: PO / CO / PC / Comprometido / Incurrido / Pagado / Trends / EAC / %Ejec. La columna Varianza fue eliminada. Totals row calcula %Ejec = sumIncurrido / sumEAC. Requiere Cayaqui.MPS.ReportModels ≥ 0.3.5.
v0.7.3 — 6 nuevas secciones EPC
6 nuevas secciones de project controls para ingeniería/procura:
var report = new ExcelReport()
.AddTitle("Talara U3 · Cut-off 2026-04-30")
.AddWbsBudgetTable(new WbsBudgetTableSection
{
Title = "Presupuesto WBS",
Rows = new[]
{
new WbsBudgetRow("1.0", "Ingeniería", Level: 0, Bac: 5_000_000m, Ev: 4_200_000m, Ac: 4_500_000m, Eac: 5_357_143m, PercentComplete: 0.84m, Currency: "USD"),
new WbsBudgetRow("1.1", "Diseño básico", Level: 1, Bac: 2_000_000m, Ev: 2_000_000m, Ac: 2_100_000m, Eac: 2_100_000m, PercentComplete: 1.00m, Currency: "USD"),
new WbsBudgetRow("1.2", "Diseño detalle", Level: 1, Bac: 3_000_000m, Ev: 2_200_000m, Ac: 2_400_000m, Eac: 3_272_727m, PercentComplete: 0.73m, Currency: "USD"),
}
})
.AddEngProgressTable(new EngProgressTableSection
{
Title = "Avance Ingeniería",
Rows = new[]
{
new EngProgressRow("ENG-001", "Plano P&ID", "Proceso",
PlanPct: 0.90m, ActualPct: 0.85m,
PlannedCompletion: new DateTime(2026, 5, 15),
ForecastCompletion: new DateTime(2026, 5, 22)),
}
})
.AddLookaheadTable(new LookaheadTableSection
{
Title = "Lookahead 3 Semanas",
Rows = new[]
{
new LookaheadRow("1.2.1", "Rev. planos estructurales", "J. Pérez",
new DateTime(2026, 5, 19), new DateTime(2026, 5, 23),
LookaheadStatus.InProgress),
}
})
.AddEvmControlChart(new EvmControlChartSection
{
Title = "Control Chart SV/CV",
Points = controlChartPoints // IEnumerable<ControlChartPoint>
})
.AddRaciMatrix(new RaciMatrixSection
{
Title = "Matriz RACI",
Items = new[]
{
new RaciEntry("Diseño básico", "Ing. Jefe", RaciRole.Responsible),
new RaciEntry("Diseño básico", "Gerente Proy", RaciRole.Accountable),
new RaciEntry("Diseño básico", "Cliente", RaciRole.Consulted),
}
})
.AddPoRegister(new PoRegisterSection
{
Title = "Registro de Órdenes de Compra",
Items = new[]
{
new PoEntry("PO-001", "Aceros del Sur", "Estructuras metálicas",
450_000m, "USD", "Approved",
IssueDate: new DateTime(2026, 3, 1),
DeliveryDate: new DateTime(2026, 6, 30)),
}
});
| Sección | Sheet default | Tipo | Descripción |
|---|---|---|---|
WbsBudgetTableSection |
"WBS Budget" |
tabla 9 cols | Code / WBS Name (indentado) / BAC / EV / AC / EAC / CV / CPI / % Done. CV verde/rojo; CPI semáforo ≥0.95/0.85. |
EngProgressTableSection |
"Eng Progress" |
tabla 8 cols | Code / Title / Discipline / Plan% / Actual% / Deviation / Planned Date / Forecast Date. Deviation verde/rojo. |
LookaheadTableSection |
"Lookahead" |
tabla 7 cols | WBS Code / Activity / Responsible / Start / Finish / Status / Comments. Status coloreado. |
EvmControlChartSection |
"EVM Control Chart" |
line chart | SV (ámbar) y CV (azul) en el tiempo con línea cero de referencia. |
RaciMatrixSection |
"RACI Matrix" |
tabla pivot | Actividades × Roles. R=azul, A=púrpura, C=ámbar, I=neutro. |
PoRegisterSection |
"PO Register" |
tabla 7 cols | PO# / Supplier / Description / Amount (con currency) / Status / Issue Date / Delivery Date. |
Requiere Cayaqui.MPS.ReportModels ≥ 0.3.3. Sin breaking changes.
v0.6.0 — Migración a ReportModels + 8 secciones Fase 2
Migración de DTOs a Cayaqui.MPS.ReportModels (nuevo peer-dependency, zero-dep): EvmKpiSnapshot, EvmSCurvePoint, CashflowPoint, BurndownPoint, R9cEntry, RiskItem+RiskView, VarianceRow, PhysicalProgressPoint, ProductionPoint. Los namespaces se mantienen via global using — sin breaking changes para consumers existentes. SemaforoColors y EvmChartPalette conservan sus APIs públicas y delegan internamente a ReportModels.
8 nuevas secciones Fase 2:
var report = new ExcelReport()
.AddTitle("Talara U3 · Cut-off 2026-04-30")
.AddContingencyDrawdown(new ContingencyDrawdownSection
{
Points = contingencyPoints, ControlDate = controlDate
})
.AddWaterfall(new WaterfallSection
{
Steps = new[]
{
new WaterfallStep("BAC", WaterfallStepKind.Total, 10_000_000m),
new WaterfallStep("Contingencia usada", WaterfallStepKind.Subtract, 500_000m),
new WaterfallStep("Reserva gestión", WaterfallStepKind.Subtract, 200_000m),
new WaterfallStep("EAC pendiente", WaterfallStepKind.Forecast, 9_300_000m),
}
})
.AddResourceHistogram(new ResourceHistogramSection
{
Buckets = resourceBuckets, CapacityLimit = 40m, CapacityUnit = "HH/mes"
})
.AddManagementReserveTracker(new ManagementReserveTrackerSection
{
Events = mrEvents, InitialReserve = 500_000m, Currency = "USD"
})
.AddTornadoChart(new TornadoChartSection { Items = tornadoItems, Currency = "USD" })
.AddMilestoneStrip(new MilestoneStripSection { Milestones = milestones })
.AddRiskRegisterTable(new RiskRegisterTableSection { Entries = riskRegister })
.AddChangeOrderLog(new ChangeOrderLogSection { Entries = changeOrders, Currency = "USD" });
| Sección | Sheet | Tipo | Descripción |
|---|---|---|---|
ContingencyDrawdownSection |
"Contingency" |
line chart | Plan/Actual contingencia restante, optional ControlDate |
WaterfallSection |
"Waterfall" |
stacked column | Spacer invisible + color por WaterfallStepKind |
ResourceHistogramSection |
"Resources" |
stacked column | Pivote Period×Category + optional Capacity line |
ManagementReserveTrackerSection |
"MR Tracker" |
tabla | Eventos + running balance + semáforo |
TornadoChartSection |
"Tornado" |
bar horizontal | Low/High deviations ordenadas por range |
MilestoneStripSection |
"Milestones" |
tabla | Row coloring por MilestoneHealth |
RiskRegisterTableSection |
"Risk Register" |
tabla 10 cols | Score cell coloring |
ChangeOrderLogSection |
"Change Orders" |
tabla 8 cols | Status cell coloring |
149 tests en MPS.Infrastructure.ExcelExport.Tests (todos passing). Sin breaking changes. Requiere Cayaqui.MPS.ReportModels ≥ 0.2.0.
v0.5.1 — Patch: paleta de curvas alineada con design system MPS
Fix de paleta en PhysicalProgressCurveSection y ProductionCurveSection. v0.5.0 publicaba con colores invertidos respecto al componente Blazor real (MPS.Components.Evm.PhysicalProgressCurve/ProductionCurve):
| Sección | Serie | v0.5.0 (incorrecto) | v0.5.1 (correcto) |
|---|---|---|---|
| Physical Progress | Baseline | #9CA3AF sin dash |
#44403C dashed |
| Physical Progress | Actual | #039855 (verde) |
#D92D20 (rojo) con markers |
| Physical Progress | Forecast | #F79D1E dashed |
#039855 (verde) dashed |
| Production | Plan | #2E5BFF (azul EVM) |
#7F56D9 (púrpura mining) |
| Production | Actual | #D92D20 (rojo) |
#0086C9 (cyan) |
| Production | Nameplate | #101828 (negro) |
#D92D20 (rojo dashed) |
EvmChartPalette agrega 2 constantes públicas: Baseline (#44403C) y Cyan (#0086C9). +2 tests de regresión por sección. Sin breaking changes en API — solo cambia el output visual.
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.18.0)
- Cayaqui.MPS.ReportModels (>= 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 | 58 | 5/26/2026 |
| 0.9.0 | 30 | 5/26/2026 |
| 0.7.4 | 153 | 5/19/2026 |
| 0.7.3 | 82 | 5/19/2026 |
| 0.7.2 | 85 | 5/18/2026 |
| 0.7.1 | 83 | 5/18/2026 |
| 0.7.0 | 90 | 5/18/2026 |
| 0.6.0 | 89 | 5/18/2026 |
| 0.5.1 | 132 | 5/10/2026 |
| 0.5.0 | 91 | 5/10/2026 |
| 0.4.0 | 94 | 5/10/2026 |
| 0.3.0 | 92 | 5/10/2026 |
| 0.2.0 | 394 | 4/24/2026 |
| 0.1.1 | 107 | 4/24/2026 |
| 0.1.0 | 113 | 4/24/2026 |
0.9.1 — CoverSheetSection: logo aspect ratio preserved (fit-within maxW×maxH without distortion). 0.9.0 — CoverSheetSection Cayaqui company footer logo via LogoOptions.MpsCompanyLogo. 0.7.4 — R9cReportSection: esquema R9C actualizado (Incurrido/Pagado/Trends/EAC). Totals row usa sumIncurred/sumEac. Requiere ReportModels ≥ 0.3.5. 0.7.3 — 6 new sections: WbsBudgetTableSection, EngProgressTableSection, LookaheadTableSection, EvmControlChartSection (SV/CV line chart), RaciMatrixSection (pivot table), PoRegisterSection. 6 new fluent builder methods on ExcelReport.
0.7.2 — Fix: MPS.Licensing.dll incluido en lib/net10.0/ del .nupkg (faltaba en 0.7.0/0.7.1 → 502.5 en IIS).
0.7.1 — Fix: re-publicación de 0.7.0 con binarios correctos. Sin diferencia de API.
0.7.0 — Licensing: AddMpsExcelExport acepta licenseKey opcional (ECDSA P-256). Sin clave válida, el workbook generado incluye hoja de marca de agua y footer en cada pestaña. ExcelLicenseState registrado en DI. Sin breaking changes.
0.6.0 — Migración DTOs a Cayaqui.MPS.ReportModels (sin breaking changes) + 8 secciones Fase 2: ContingencyDrawdownSection, WaterfallSection, ResourceHistogramSection, ManagementReserveTrackerSection, TornadoChartSection, MilestoneStripSection, RiskRegisterTableSection, ChangeOrderLogSection. 149 tests. v0.5.1 — Patch: paleta de PhysicalProgressCurveSection y ProductionCurveSection alineada con MPS.Components Blazor. PhysicalProgressCurveSection: Baseline cambia de #9CA3AF a #44403C dashed (paridad), Actual cambia de verde #039855 a rojo #D92D20 con markers (era Forecast color), Forecast cambia de naranja #F79D1E a verde #039855 dashed (era Actual color). ProductionCurveSection: Plan cambia de #2E5BFF azul a #7F56D9 púrpura, Actual cambia de #D92D20 rojo a #0086C9 cyan, NameplateRate stripline cambia de #101828 negro a #D92D20 rojo dashed. EvmChartPalette agrega Baseline (#44403C) y Cyan (#0086C9) como constantes públicas. +2 tests de regresión. Suite total: 122. Sin breaking changes — solo afecta el output visual de los charts. v0.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.