Stilo.Reports
1.0.0
dotnet add package Stilo.Reports --version 1.0.0
NuGet\Install-Package Stilo.Reports -Version 1.0.0
<PackageReference Include="Stilo.Reports" Version="1.0.0" />
<PackageVersion Include="Stilo.Reports" Version="1.0.0" />
<PackageReference Include="Stilo.Reports" />
paket add Stilo.Reports --version 1.0.0
#r "nuget: Stilo.Reports, 1.0.0"
#:package Stilo.Reports@1.0.0
#addin nuget:?package=Stilo.Reports&version=1.0.0
#tool nuget:?package=Stilo.Reports&version=1.0.0
Stilo.Reports
A self-contained, RDL/RDLC-compatible report designer and viewer for Blazor. Drag-and-drop designer, pagination/rendering engine, chart and Tablix (table/list/matrix) support, PDF export — all written from scratch in C#, with no external report server, no native dependencies, and no data ever leaves your process.
Works in Blazor Server and Blazor WebAssembly.
Installation
dotnet add package Stilo.Reports
Stilo.Reports depends on Stilo.Documents (used for PDF export). It does not depend on Stilo.Maestro.
Quick start
1. Register services
// Program.cs
builder.Services.AddStiloReports();
2. Make sure <HeadOutlet> is rendered
StiloReportViewer and StiloReportDesigner inject their stylesheet via <HeadContent>. Standard Blazor Web App/Server/WASM project templates already render a <HeadOutlet> in App.razor — if yours doesn't, add one so the report CSS actually reaches the page:
<HeadOutlet @rendermode="InteractiveServer" />
No <script> tag is needed — the JS module is imported by the components themselves at runtime.
3. Show a report
@page "/report"
@using Stilo.Reports.Components
@using Stilo.Reports.Data
<StiloReportViewer ReportDefinition="_report" DataSources="_dataSources" HtmlToPdfConverter="_pdfConverter" />
@code {
private Report _report = null!;
private IEnumerable<ReportDataSource> _dataSources = null!;
[Inject] private Stilo.Documents.Converters.IHtmlToPdfConverter _pdfConverter { get; set; } = null!;
protected override void OnInitialized()
{
// Option A: build the report from code (see "Building a report from code" below)
_report = BuildMyReport();
// Option B: load an existing .rdl / .rdlc file
// _report = Stilo.Reports.Rdl.RdlReader.Read(File.ReadAllText("Invoice.rdlc"));
_dataSources = new[]
{
ReportDataSource.FromEnumerable("Orders", myOrders), // myOrders: IEnumerable<T>
};
}
}
HtmlToPdfConverter is optional — without it the viewer's "Export PDF" button stays disabled, everything else works. Get an implementation the same way you would for Stilo.Documents in general (inject it from DI, or construct one directly).
Building a report from code
Reports are plain object graphs — you never have to hand-write RDL XML to build one. The most important types (Stilo.Reports.Models):
using Stilo.Reports.Models;
var report = new Report
{
Description = "Monthly Invoice",
PageWidth = RdlSize.FromMm(210),
PageHeight = RdlSize.FromMm(297),
};
report.Body.Height = RdlSize.FromMm(250);
var title = new Textbox
{
Name = "Title",
Top = RdlSize.FromMm(10), Left = RdlSize.FromMm(10),
Width = RdlSize.FromMm(150), Height = RdlSize.FromMm(10),
Paragraphs = { new Paragraph { Runs = { new TextRun { Value = "=\"Invoice #\" & Fields!InvoiceNumber.Value" } } } },
};
report.Body.Items.Add(title);
report.DataSets.Add(new DataSet
{
Name = "Orders",
Fields = { new Field { Name = "InvoiceNumber" }, new Field { Name = "Total" } },
});
Key model types: Report (Body, PageHeader/PageFooter, DataSources, DataSets, Parameters, EmbeddedImages), ReportBody/PageSection (Height, Items), and every positionable item derives from ReportItem (Name, Top/Left/Width/Height as RdlSize, ZIndex, Style, Hidden, ToolTip, Bookmark): Textbox, Rectangle (can nest other items), Line, ImageItem, BarcodeItem, Tablix, Chart, SubReport, Indicator, DataBar, Sparkline.
RdlSize is a value type with FromMm, FromInches, FromPoints, FromPixels(px, dpi) factory methods (and Parse/TryParse/ToRdlString() for round-tripping).
Any string property that starts with = is an expression (see "Expression language" below); anything else is treated as a literal.
Supplying data
Reports never execute a query themselves — DataSet/DataSource/Query on the model exist only for RDL round-trip compatibility (opening/saving files created by other tools). You always supply the actual rows in-process:
using Stilo.Reports.Data;
var dataSources = new[]
{
ReportDataSource.FromEnumerable("Orders", myOrders), // any IEnumerable
ReportDataSource.FromDataTable("Legacy", myDataTable), // System.Data.DataTable
};
Each ReportDataSource.Name must match a DataSet.Name referenced by the report (via Tablix.DataSetName, Chart.DataSetName, etc.).
Opening and saving .rdl / .rdlc files
using Stilo.Reports.Rdl;
Report report = RdlReader.Read(xmlString); // or RdlReader.Read(stream)
string xml = RdlWriter.Write(report); // RdlWriter.Write(report, RdlSchemaVersion.V2016) to pick a schema version
The reader tolerates RDL 2008/2010/2016 namespace variants and typical Visual Studio/SSDT report authoring quirks (unit variants, interleaved rd:* designer-only attributes, etc.).
StiloReportViewer parameters
| Parameter | Type | Description |
|---|---|---|
Title |
string? |
Optional title bar text. |
ReportDefinition |
Report? |
The report to render, as an object. |
ReportXml |
string? |
Alternative to ReportDefinition: raw .rdl/.rdlc XML. Takes priority over ReportDefinition when set. |
DataSources |
IEnumerable<ReportDataSource>? |
Data for the report's DataSets. |
ParameterValues |
Dictionary<string, object?>? |
Pre-filled values for Report.Parameters (otherwise the viewer prompts for them). |
SubReports |
IReadOnlyDictionary<string, SubReportResolution>? |
Resolves SubReport items by name — see below. |
HtmlToPdfConverter |
IHtmlToPdfConverter? |
Enables the "Export PDF" button. |
OnDrillthrough |
EventCallback<DrillthroughEventArgs> |
Raised when the user clicks a Textbox with a Drillthrough action. There is no report catalog built into the library — your app decides what happens (navigate, open a dialog, ...). |
Viewer features: parameter prompt bar (auto-generated inputs per Report.Parameters, dropdown/checkbox/date based on type), pagination controls, zoom (50–200%), refresh, in-page text search with highlighting, bookmarks navigation, PDF export, print, drillthrough.
Subreports
var subReports = new Dictionary<string, SubReportResolution>
{
["CustomerNotes"] = new SubReportResolution
{
Report = notesReport,
DataSources = new[] { ReportDataSource.FromEnumerable("Notes", notes) },
},
};
Pass this to SubReports on the viewer (or PreviewSubReports on the designer). Resolution is by the SubReport.ReportName string used in the parent report — nesting works recursively, and multi-page subreports split correctly across parent pages.
StiloReportDesigner parameters
| Parameter | Type | Description |
|---|---|---|
ReportName |
string (default "Report1") |
Display name shown in the designer's title field. |
Report / ReportChanged |
Report? |
The report being edited. Supports @bind-Report. If null on init, a blank report is created automatically. |
PreviewDataSources |
IEnumerable<ReportDataSource>? |
Feeds the designer's embedded "Preview" tab. If omitted, the designer auto-generates mock rows per DataSet so previews are never structurally empty (the standalone viewer never does this — only the designer). |
PreviewSubReports |
IReadOnlyDictionary<string, SubReportResolution>? |
Same as SubReports on the viewer, for the embedded preview. |
HtmlToPdfConverter |
IHtmlToPdfConverter? |
Enables PDF export from within the embedded preview tab. |
<StiloReportDesigner @bind-Report="_report" PreviewDataSources="_previewData" HtmlToPdfConverter="_pdfConverter" />
@code {
private Report _report = new();
private IEnumerable<ReportDataSource> _previewData = Array.Empty<ReportDataSource>();
}
Opening and saving
.rdl/.rdlcfiles is handled internally by the designer's own toolbar (Open/Save buttons trigger a browser file upload/download) — there is noReportXmlparameter on the designer; work with theReportobject via@bind-Report.
Designer features
- Toolbox, grouped: Basic (Textbox, Image, Line, Rectangle, Barcode 1D, Barcode 2D), Comparison (Column/Bar/Stacked Column/Stacked Bar/100% Stacked Column/100% Stacked Bar charts), Data (Table, List, Matrix, Data Bar, Sparkline, Indicator), Distribution (Area/Line/Pie/Scatter charts), Subreports, Shapes — searchable, drag-and-drop onto the canvas.
- Design surface: resizable header/body/footer sections, millimeter rulers, snap-to-grid, live per-item-type preview (including a real row/column preview for Tablix, not a placeholder).
- Selection & editing: multi-selection, 8-handle resize, align/distribute for multi-selection, Tablix column resize by dragging borders, cut/copy/paste, undo/redo.
- Property grid: contextual per item type (position/size, style, borders, colors, font, data set/field bindings, chart series editor, action editor, etc.).
- Expression editor: field/parameter/global tree browser + autocomplete text editor (functions, aggregates — see below).
- Data panel: manage
DataSources,DataSets and theirFields, plus per-dataset filters. - Parameters panel: manage
Report.Parameters(type, prompt, default/valid values, nullable/multi-value/hidden flags). - Label sheet wizard: generates a grid layout (N columns × M rows) of repeating labels bound to a data set/field, with size presets — see "Label sheets" below.
- Embedded live preview tab, backed by the real
StiloReportViewer.
Rendering engine capabilities
- Tablix (table/list/matrix region): row groups with subtotals, multi-level nested groups, sorting, filters, and true Matrix pivot mode (dynamic columns discovered from data, with nested column groups and per-cell aggregation).
- Charts: 10 types — Column, Bar, Line, Pie, Area, Scatter, Stacked Column, Stacked Bar, 100% Stacked Column, 100% Stacked Bar — rendered as SVG.
- Indicator / Data Bar / Sparkline mini-visuals for KPI-style single values and trend lines.
- Barcode / QR code items, generated on the fly (no image assets to manage) — see "Barcodes and QR codes" below.
- SubReport, resolved recursively, with independent data sources and correct multi-page splitting.
- Actions: hyperlink, bookmark link, and drillthrough on text.
- Rich text:
MarkupType="HTML"runs render raw HTML instead of escaped text. - Reflow:
Textbox.CanGrowpushes following content down based on estimated wrapped-text height; overflowing content splits cleanly across page boundaries (both for growing textboxes and for Tablix regions that don't fit on one page — the Tablix header repeats on every continuation page). - PDF export: the same HTML the viewer renders is converted to PDF via
Stilo.Documents'IHtmlToPdfConverter— what you see in the viewer is what you get in the PDF.
Expression language
RDL-style expressions, starting with =:
Fields!Name.Value,Fields!Name.IsMissingParameters!Name.ValueGlobals!PageNumber,Globals!TotalPages,Globals!ReportName,Globals!ExecutionTimeReportItems!Name.Value- Operators:
+ - * / Mod,&(string concatenation), comparisons,And/Or/Not - Functions:
IIf,Format,Today,Now,Len,UCase,LCase,Trim,Round,Int,CStr,CInt,CDbl,CDate,RowNumber - Aggregates (operate over the current group/data scope):
Sum,Count,CountRows,Avg,Min,Max
Barcodes and QR codes
Add a BarcodeItem anywhere a regular item can go — including inside a Tablix cell, so each data row gets its own barcode:
var barcode = new BarcodeItem
{
SymbologyType = "QrCode", // see Stilo.Documents.Bars.BarcodeImageWriter.SupportedTypes
ValueExpression = "=Fields!Sku.Value",
ShowText = true,
Width = RdlSize.FromMm(25), Height = RdlSize.FromMm(25),
};
Supported symbologies at the time of writing: QR Code, Code128, EAN-13, Code39. The designer exposes the same capability via the "Barcode 1D"/"Barcode 2D" toolbox tools and a quick field-picker in the property grid.
Label sheets
For "print N labels per page" scenarios (product tags, shipping labels, ...), use the designer's label sheet wizard (toolbar button) instead of building the grid by hand: pick columns/rows (or a size preset), label dimensions, margins/gutter, a data set and field, and a symbology — it generates a Tablix using a pivot on the built-in RowNumber() function to lay a flat list of records out as an N-column grid, with one barcode (and optional caption) per cell. The generated Tablix is a completely ordinary part of the report model — nothing wizard-specific is persisted, so the result opens and edits like any other Tablix, and works through the normal RDL round-trip.
Dependencies
Stilo.Documents— PDF export engine (IHtmlToPdfConverter) and barcode/QR code generation (Stilo.Documents.Bars).Microsoft.AspNetCore.Components.Web9.x.
License
Proprietary — commercial use requires written authorization from Francesco Paolo Passaro — info@digitalsolutions.it
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. 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. |
-
net9.0
- Microsoft.AspNetCore.Components.Web (>= 9.0.0)
- Stilo.Documents (>= 1.0.0)
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 |
|---|---|---|
| 1.0.0 | 108 | 7/8/2026 |