![]() |
VOOZH | about |
dotnet add package Cayaqui.Reports --version 0.3.5
NuGet\Install-Package Cayaqui.Reports -Version 0.3.5
<PackageReference Include="Cayaqui.Reports" Version="0.3.5" />
<PackageVersion Include="Cayaqui.Reports" Version="0.3.5" />Directory.Packages.props
<PackageReference Include="Cayaqui.Reports" />Project file
paket add Cayaqui.Reports --version 0.3.5
#r "nuget: Cayaqui.Reports, 0.3.5"
#:package Cayaqui.Reports@0.3.5
#addin nuget:?package=Cayaqui.Reports&version=0.3.5Install as a Cake Addin
#tool nuget:?package=Cayaqui.Reports&version=0.3.5Install as a Cake Tool
Nuevo IWorkbookTemplateFiller (impl. XlsIO, registrado por AddCayaquiReports()): rellena un workbook existente preservando fórmulas, gráficos nativos, sparklines y formatos. Para informes corporativos donde las hojas frontales calculan sobre hojas de datos y las anclas son fijas (complementa el render por markers de IReportService).
var spec = new WorkbookFillSpec()
.Clear("1 BUDGET", 19, 2, 103, 18) // limpia datos de ejemplo
.Set("PORTADA", "H24", "EPC-001") // ref A1
.Set("1 BUDGET", 19, 2, "1.1") // fila/columna 1-based
.Set("DATA", 19, 12, 1250.5m) // coerción CLR → celda
.AddImage("FOTOS", "B10", jpegBytes);
await using var filled = filler.Fill(templateStream, spec); // .xlsx listo, fórmulas vivas
Generación de reportes Excel · Word · PowerPoint · PDF basada en templates OpenXML, para .NET 10. Usa Syncfusion File Formats (XlsIO, DocIO, Presentation) — .xlsx/.docx/.pptx nativos con MailMerge, template markers y placeholder replacement.
Distribución propietaria — requiere contrato comercial con Cayaqui. Ver
LICENSE.txt.
Dependencias:
Cayaqui.Storageregistrado (para cargar templates + GenerateAndStoreAsync) + licencia Syncfusion válida del consumidor.
🆕 ReportTypographyOptions — fuentes opt-in en el render. Nueva propiedad ReportRenderOptions.Typography con cuatro slots:
BodyFontName — cuerpo / labels.TableFontName — celdas/runs en tablas (hereda de Body si null).NumericFontName — valores numéricos (hereda de Table → Body si null).ChartFontName — chart text (reservado; depende del template).Helper ReportTypographyOptions.CayaquiDefault() retorna la convención canónica Cayaqui (Body="Inter", Table/Numeric/Chart="Roboto Condensed") — alineado con Cayaqui.Components ≥ 0.29.
var options = new ReportRenderOptions
{
Typography = ReportTypographyOptions.CayaquiDefault()
};
await reportService.GenerateAsync("monthly-status.xlsx", data, options: options);
Si Typography es null (default), los renderers respetan la fuente del template — cero impacto sobre 0.5.x.
Aplicación por renderer:
UsedRange. cell.HasNumber || HasFormula || HasDateTime → EffectiveNumeric; resto → EffectiveTable. Aplicado también en RenderMultiSheetAsync.^\(?[+\-]?\$?[\d.,\s]+(\)?\s*(%|k|M|kUSD|MUSD|USD|CLP|PEN|EUR|GBP)?\)?$) → EffectiveNumeric. Runs en tablas (no numéricos) → EffectiveTable. Resto → BodyFontName.Caveats:
PdfConformance.PdfA2b o PdfA3b (embeben fuentes).Lunes 5 de mayo). Para esos casos, asegurar la fuente directamente en el template.{{Field}} en múltiples runs (formato parcial — ej. negrita solo en {{), el reemplazo silenciosamente fallaba. Ahora se consolidan los runs a paragraph-level si ningún run individual hace match.ValidateTemplateAsync con extensiones desconocidas — antes throweaba InvalidOperationException violando el contrato "validate, don't throw". Ahora retorna IsValid=false con el error en Errors.SlideSize.Width/Height — funciona con widescreen, 4:3 (720×540) y custom.Title/Author/Subject/Keywords/Creator se aplican en PdfDocument antes del primer save, no via PdfLoadedDocument post. Ahorra una pasada de IO/parse para PDFs solo-metadata.IReportService.ConvertToPdfAsync(stream, format, options, ct) — permite aplicar metadata/watermark/password/PDF-A en conversión directa de PDF (sin pasar por un template).ColorParser único — DRY de los 4 ParseColor duplicados en Word/Excel/PPT/PDF.PowerPoint_scalar_placeholder_survives_run_fragmentation + Validate_unknown_extension_returns_invalid_not_throws.Cayaqui.Metadata 0.4.0 integrado — IExtendedPropertyResolver.Format resuelve [Display(Name)] para enums automáticamente en MailMerge / markers / placeholders.SkiaSharp.NativeAssets.Linux (PDF rendering en containers).%var% parser quirk (workaround: registrar key y key+"%").RequiredFields + RequiredFieldsMode (Throw/Warn/Ignore).{{image:key}} / %image:key%).ReportContext fluent builder.dotnet add package Cayaqui.Reports
dotnet add package Cayaqui.Storage
Registrar en Program.cs:
builder.Services.AddCayaquiStorage(opt => opt.UseFileSystem("./templates-root"));
builder.Services.AddCayaquiReports(opt =>
{
opt.TemplatesContainer = "report-templates";
opt.SyncfusionLicenseKey = "<your-license-key>"; // o registrar en otro punto
});
Cayaqui.Reports usa placeholders distintos por formato porque cada motor Syncfusion tiene su gramática nativa. Esto es deliberado (no se quiere reescribir lo que ya hace MailMerge en Word). Pero el template author tiene que conocerlas todas.
| Concepto | Word .docx |
Excel .xlsx |
PowerPoint .pptx |
Header/Footer |
|---|---|---|---|---|
| Scalar | «FieldName» (DocIO MailMerge) |
%FieldName% (XlsIO markers) |
{{FieldName}} (handlebars custom) |
{date}, {datetime}, plus user dict |
| Nested | «Customer.Name» |
%Customer.Name% |
{{Customer.Name}} |
n/a |
| Iteración | «TableStart:Items» … «TableEnd:Items» (group) |
%Items.Property% (collection markers) |
{{#foreach Items}} … {{/foreach}} (slide clone) |
n/a |
| Imagen | {{image:key}} (DocIO Find + AppendPicture) |
%image:key% (cell → AddPicture) |
{{image:key}} (textbox → replace shape) |
n/a |
| Header/footer auto | Header/Footer injection sección |
PageSetup.CenterHeader/Footer |
HeadersFooters.Footer slot |
tokens {date} {time} {datetime} |
«» lo entiende DocIO MailMerge nativamente. Los field codes («Total \# "$#,##0.00"») funcionan con untyped data; ojo: en 0.5.x los grupos pasan strings al DataTable, así que el field code Word no aplica sobre data ya pre-formateada por [Currency]/[Date]. Si querés Word field codes, setea ApplyExtendedProperties = false en ReportRenderOptions.%% es el formato nativo de XlsIO Template Markers. El parser en XlsIO 33.2.3 tiene un quirk con el % final — el paquete registra el variable como key y key% (workaround documentado).{{}} es custom (Syncfusion Presentation no tiene marker engine nativo). Se implementó con regex sobre el texto del slide. Desde 0.5.0 maneja runs fragmentados (placeholder partido por formato).{token} single-brace es solo para los strings de Header / Footer / Watermark — no para el cuerpo del template.var ctx = ReportContext.Create()
.With("ProjectCode", "LBX-01")
.With("ControlDate", DateTime.UtcNow)
.With("Customer", new { FullName = "Acme Corp", TaxId = "12345-6" })
.WithCollection("Items", invoice.Lines)
.WithImage("logo", File.ReadAllBytes("logo.png"), "image/png")
.WithImage("signature", signatureBytes);
await using var pdf = await reports.GenerateAsync(
"invoice.docx",
ctx.Build(),
format: ReportFormat.Pdf,
options: ctx.ToOptions(new ReportRenderOptions
{
PdfTitle = "Invoice {invoice.Number}",
PdfAuthor = "Cayaqui",
PdfConformance = PdfConformance.PdfA2b,
RequiredFields = new[] { "ProjectCode", "ControlDate" },
RequiredFieldsMode = RequiredFieldsMode.Throw
}));
Template Word (invoice.docx):
Invoice for {{image:logo}} — issued «ControlDate»
...
Signature: {{image:signature}}
Template Excel (report.xlsx), cell B1: %image:logo%, cell B20: %image:signature%.
Template PowerPoint (cover.pptx), text box con {{image:logo}}.
await reports.GenerateAsync("invoice.docx", data,
options: new ReportRenderOptions
{
Images = new Dictionary<string, ReportImage>
{
["logo"] = new ReportImage { Data = logoBytes, ContentType = "image/png",
WidthPx = 120, HeightPx = 40 },
["signature"] = new ReportImage { Data = sigBytes, ContentType = "image/png" }
}
});
var opts = new ReportRenderOptions
{
PdfTitle = "Monthly Status — April 2026",
PdfAuthor = "Project Controls Team",
PdfSubject = "EVM snapshot for LBX-01",
PdfKeywords = "evm;cpi;spi;monthly;lbx-01",
PdfCreator = "Cayaqui",
PdfConformance = PdfConformance.PdfA2b
};
await using var pdf = await reports.GenerateAsync("monthly-status.docx", data,
format: ReportFormat.Pdf, options: opts);
Si solo querés convertir un PDF arbitrario y aplicarle metadata sin pasar por un template:
// Nuevo en 0.5.0 — overload con ReportRenderOptions
await using var pdf = await reports.ConvertToPdfAsync(
sourceStream, ReportFormat.Word,
new ReportRenderOptions { PdfTitle = "Report", Watermark = "CONFIDENTIAL" });
try
{
await reports.GenerateAsync("invoice.docx", data,
options: new ReportRenderOptions
{
RequiredFields = new[] { "CustomerName", "InvoiceTotal", "DueDate" },
RequiredFieldsMode = RequiredFieldsMode.Throw
});
}
catch (ReportRenderException ex) when (ex.Message.Contains("Required fields"))
{
_log.LogError("Invoice data incomplete: {Message}", ex.Message);
}
| Formato | Implementación |
|---|---|
| Word | DocIO TextWatermark diagonal, semitransparente |
| Excel | Shape de texto centrado por sheet (no rotado — XlsIO 33.x limita ITextBoxShape.Rotation) |
| PowerPoint | Text box rotado -45° por slide, centrado relativo a SlideSize (0.5.0: respeta 4:3 / widescreen / custom) |
| Overlay post-conversion con rotación -45° y opacity 0.35 |
await reports.GenerateAsync("doc.docx", data,
options: new ReportRenderOptions
{
Watermark = "CONFIDENTIAL",
WatermarkColor = "#E5E7EB"
});
.xlsx. Si querés diagonal, exporta a PDF (format: ReportFormat.Pdf) — el post-process aplica la rotación.DataTable, los field codes Word («Total \# "$#,##0.00"») no formatean. Setea ApplyExtendedProperties = false para preservar tipos numéricos en grupos, o usá los atributos [Currency] / [Date] del DTO (recomendado).DataBinding.Flatten profundidad fija = 3 niveles. DTOs con nesting más profundo (A → B → C → D) pierden niveles. Aplaná o referenciá explícitamente las hojas que necesites.Cayaqui.Storage registradoCayaqui.Metadata 0.4.0+ (auto-resuelto)| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 net10.0 is compatible. net10.0-android net10.0-android was computed. net10.0-browser net10.0-browser was computed. net10.0-ios net10.0-ios was computed. net10.0-maccatalyst net10.0-maccatalyst was computed. net10.0-macos net10.0-macos was computed. net10.0-tvos net10.0-tvos was computed. net10.0-windows net10.0-windows was computed. |
This package is not used by any NuGet packages.
This package is not used by any popular GitHub repositories.
0.7.0 — Workbook fill: nuevo `IWorkbookTemplateFiller` (impl XlsIO) + `WorkbookFillSpec` (clears → celdas → imágenes, refs A1 o fila/columna 1-based, coerción de tipos CLR). Rellena plantillas .xlsx EXISTENTES preservando fórmulas, gráficos nativos, sparklines y formatos — para informes corporativos de layout fijo con hojas frontales calculadas. Registrado en `AddMpsReports()` (TryAdd). Sin breaking changes.
0.6.2 — Rebuild contra Cayaqui.Metadata 0.20.0 (refactor de namespaces: tipos movidos a Cayaqui.Metadata.Attributes/.Resolver/.Models/.Branding). Sin cambios de API propios; corrige TypeLoadException/CS7069 al consumir este paquete junto a Metadata 0.20.0.
0.6.0 — Tipografía opt-in. Nuevo `ReportTypographyOptions` (BodyFontName / TableFontName / NumericFontName / ChartFontName) en `ReportRenderOptions.Typography`. Si null, los renderers respetan la fuente del template (backward-compatible). Si seteado, aplica fuentes después del merge: Excel walks UsedRange y aplica NumericFontName a celdas con valor numérico/fórmula/datetime y TableFontName al resto; Word/PowerPoint walk paragraphs/runs y aplican BodyFontName globalmente, TableFontName dentro de tablas, NumericFontName a runs cuyo texto matchea patrón numérico (regex con soporte para %, paréntesis, k/M/USD/CLP/PEN/EUR). Helper `ReportTypographyOptions.MpsDefault()` retorna la convención canónica MOVES (Body=Inter, Table/Numeric/Chart=Roboto Condensed) — alineado con Cayaqui.Components ≥ 0.29. Para fuentes custom, asegurar disponibilidad en el sistema que abre el archivo o embeber con `PdfConformance.PdfA2b/PdfA3b`. v0.5.0 — Hardening: PowerPoint placeholders fragmentados, ValidateTemplateAsync robusto, SlideSize real, PDF metadata pre-save, ConvertToPdfAsync con options. Sin breaking changes — Typography es opt-in.