NETReporter 3.9.2

NETReporter

Knihovna pro generování reportů (PDF, SVG, HTML, JSON) z deklarativních JSON šablon a JSON dat.

Šablona popisuje stránku, sekce, rozvržení, styly a bindingy na data; knihovna ji zvaliduje, vyhodnotí nad daty a vykreslí. PDF a SVG kreslí QuestPDF, grafy OxyPlot.

Instalace

Balíček je v privátním NuGet feedu Advisor Software:

dotnet nuget add source https://nuget.advisor-soft.com/v3/index.json --name AdvisorSoft
dotnet add package NETReporter

Požadavky: .NET 10.

Rozhraní (IReportRenderer, ITemplateTools) a sdílené typy (RenderOptions, diagnostiky…) jsou v balíčku NETReporter.Abstractions, který se nainstaluje sám. Aplikace, která report jen zadává a vykreslí ho ReportServer, použije místo této knihovny tenký klient NETReporter.Client (bez QuestPDF a dalších těžkých závislostí; přihlášení API tokenem): viz docs/user/pouziti-knihovny.md a průvodce klientem v repozitáři.

Rychlý start

using NetReporter;

var renderer = new ReportRenderer();

await using var template = File.OpenRead("template.json");
await using var data = File.OpenRead("data.json");
await using var pdf = await renderer.RenderAsync(template, data);   // výchozí formát je PDF

await using var file = File.Create("report.pdf");
await pdf.CopyToAsync(file);

S DI kontejnerem (ReportRenderer se registruje jako singleton):

services.AddNetReporter();                        // ReportRenderer, TemplateSchemaParser, TemplateAnalyzer, VisualTreeBuilder
services.AddNetReporter<MyPipelineObserver>();    // + vlastní IReportPipelineObserver

var renderer = serviceProvider.GetRequiredService<ReportRenderer>();

RenderAsync bere šablonu a data jako Stream a vrací Stream s výstupem (pozice 0). Při neplatné šabloně vyhodí InvalidOperationException s diagnostikami (zpráva + JSON cesta).

Šablona v kostce

{
  "version": "1.0",
  "meta": { "name": "Faktura", "culture": "cs-CZ", "palette": { "primary": "#1A73E8" } },
  "page": { "size": "A4", "orientation": "Portrait", "marginsMm": { "top": 15, "right": 12, "bottom": 15, "left": 12 } },
  "styles": {
    "base": { "font": "Arial", "fontSize": 9 },
    "h1": { "fontSize": 16, "bold": true, "color": "primary" }
  },
  "content": {
    "root": {
      "type": "Stack",
      "gapMm": 3,
      "items": [
        { "type": "Text", "text": "Faktura {{$.Number}}", "styleRef": "h1" },
        { "type": "Text", "text": "Vystaveno: {{$.Issued:dd.MM.yyyy}}, celkem {{$.Total:C2}}" },
        {
          "type": "Table",
          "columns": [
            { "key": "name", "header": "Položka", "width": "3*" },
            { "key": "price", "header": "Cena", "width": "1*", "align": "Right" }
          ],
          "rows": {
            "source": "$.Items",
            "as": "item",
            "cells": {
              "name": { "text": "{{item.Name}}" },
              "price": { "text": "{{item.Price:N2}}" }
            }
          }
        }
      ]
    }
  },
  "pageFooter": {
    "root": { "type": "PageNumbers", "mode": "Current", "showTotal": true, "separator": " / " }
  }
}
  • Sekce: pageBackground, pageHeader, reportHeader, content, reportFooter, firstPageFooter, pageFooter, pageOverlay.
  • Vodoznak a razítko: kořenové watermark (text nebo obrázek, podmínka visibleIf, průhlednost v barvě) na každé stránce PDF, SVG, HTML i JSON; z kódu RenderOptions.Watermark.
  • Rozvržení: Stack, Row, Box, Absolute, Spacer, PageBreak; libovolný uzel lze opakovat nad kolekcí přes "repeat": { "source": "$.Items", "as": "item" }; "keepTogether": true (u Stack, Row, Box, Text, Paragraph, Table) zabrání zalomení uzlu přes stránku – nevejde-li se na zbytek stránky, přesune se celý na další.
  • Obsah: Text, Paragraph, HttpLink, Image, Line, PageNumbers, Barcode, Code2D (QR, DataMatrix…), PaymentQr (QR platba SPAYD a EPC s kontrolou IBAN), Checkbox, Emoji (barevné emoji Twemoji jako vektor), Icon (ikony FontAwesome Free, s licencí i Pro, jako vektor), Table (skupiny, souhrny, stránkování), Chart.
  • Binding: {{$.Cesta.K.Hodnote}} (kořen dat), {{alias.Pole}} (položka repeat/tabulky/grafu), formát za dvojtečkou ({{$.Total:N2}}, {{$.Date:dd.MM.yyyy}}), C# výrazy s prefixem # ({{#item.Qty * item.Price}}), systémové proměnné now, page.number, page.total. Formátuje se podle meta.culture.
  • Styly: pojmenované styly v styles (base platí pro vše), odkaz styleRef a inline style; písmo, barvy (#RRGGBB nebo název z meta.palette), okraje a výplně v mm, rámečky, zarovnání. Styl lze vybrat podle dat – styleRef může obsahovat binding, jehož výsledkem je jméno stylu ("styleRef": "{{# item.Overdue ? \"overdue\" : \"\" }}"); tabulky mají styl řádku rows.styleRef a buňky rows.cells.<key>.styleRef / style.

Kompletní popis formátu je v přibalené dokumentaci (viz níže) – kapitola 02_template_format.md.

Grafy

{
  "type": "Chart",
  "chartType": "Column",
  "source": "$.Months",
  "as": "m",
  "category": "{{m.Month}}",
  "series": [
    { "name": "2025", "value": "m.Revenue", "color": "primary" },
    { "name": "Plán", "value": "#m.Revenue * 1.1", "dashed": true }
  ],
  "valueAxis": { "format": "N0" },
  "legend": { "position": "Top" }
}

Typy Column, Bar, Line, Area, Pie, Donut; více sérií, paleta, legenda, osy, popisky hodnot, skládání. Kombinovaný graf: série může přepsat typ ("type": "Line") a čáry mohou mít druhou osu vpravo ("axis": "Secondary" + secondaryValueAxis). Grafy jsou vektorové ve všech výstupech. Podrobnosti: 02_template_format.md §7.11 a 17-charts.md.

Výstupní formáty

await using var output = await renderer.RenderAsync(template, data, new RenderOptions { Format = RenderFormat.Svg });
Formát Popis
RenderFormat.Pdf výchozí; plnohodnotné PDF se stránkováním
RenderFormat.Svg stejný layout a stránkování jako PDF; jeden SVG se stránkami pod sebou (data-pages, <svg data-page="N">)
RenderFormat.Html HTML náhled bez stránkování (vhodný pro editor/prohlížeč)
RenderFormat.Json strukturovaný výsledek renderu – vyhodnocené texty, data grafů, metadata obrázků a kódů; pro automatické a AI kontroly
RenderFormat.Webp obrázek stránky se stejným layoutem jako PDF (ztrátový, bílé pozadí); RenderAsync vrací první stránku, všechny RenderWebpPagesAsync
RenderFormat.Png obrázek stránky bezeztrátově (bílé neprůhledné pozadí); RenderAsync vrací první stránku, všechny RenderPngPagesAsync
RenderFormat.Jpeg obrázek stránky ztrátově, bez průhlednosti; RenderAsync vrací první stránku, všechny RenderJpegPagesAsync

Každou SVG stránku zvlášť vrací RenderSvgPagesAsync:

IReadOnlyList<string> pages = await renderer.RenderSvgPagesAsync(template, data);

Do SVG se nevkládají fonty – prohlížeč použije písmo nainstalované v systému (pozice znaků zůstanou zachované).

Každou stránku jako obrázek WebP vrací RenderWebpPagesAsync (rozlišení RenderOptions.ImageDpi 1–600, výchozí 288, kvalita ImageQuality; všechny stránky jsou najednou v paměti):

IReadOnlyList<byte[]> pages = await renderer.RenderWebpPagesAsync(template, data, new RenderOptions { ImageDpi = 150 });

Stejně funguje RenderPngPagesAsync (bezeztrátově, ImageQuality se ignoruje) a RenderJpegPagesAsync (ztrátově, kvalita ImageQuality).

Ladění šablon: new RenderOptions { Format = RenderFormat.Html, RenderBindingsAsExpressions = true } zobrazí místo hodnot samotné binding výrazy. RenderOptions.DebugMode přidá k HTML výstupu ladicí atributy (data-nr-type s typem uzlu u prvků s id), ladicí CSS a skript pro vizuální editor šablon; výstup bez něj se nemění.

Limit stránek: PDF/SVG render skončí RenderPageLimitExceededException po překročení RenderOptions.MaxPages (výchozí 10 000, 0 = bez limitu) – ochrana před šablonou se zacykleným layoutem. CancellationToken se kontroluje i během generování stránek. Všechny formáty se renderují souběžně: od QuestPDF 2026.9 je souběžné generování PDF/SVG v jednom procesu bezpečné a ReportRenderer ho neserializuje, takže propustnost roste s počtem vláken.

Metadata PDF

Vlastnosti dokumentu (Název, Autor, Předmět, Klíčová slova, Aplikace, Jazyk) se nastavují v meta.document. Hodnoty jsou texty s bindingy vyhodnocené nad daty; prázdný výsledek se nezapíše, klíčová slova mohou být pole a bez language se použije meta.culture. Metadata se zapisují jen do PDF.

"meta": {
  "name": "Faktura",
  "culture": "cs-CZ",
  "document": { "title": "Faktura {{$.Number}}", "author": "{{$.Supplier}}", "keywords": [ "faktura", "{{$.Number}}" ] }
}

Podrobnosti: 02_template_format.md §1.4.

Profesionální PDF

Hlavičkový papír, připojená PDF, PDF/A, přílohy a šifrování se doplňují do PDF po vygenerování (post-processing přes qpdf z balíčku QuestPDF; šablony bez těchto funkcí dávají stejné PDF jako dřív).

Hlavičkový papír a připojená PDF (šablona; fragment): page.letterhead vloží stránku PDF pod obsah stránek, meta.document.append připojí PDF za dokument. Zdroj je cesta k souboru, http(s) URL nebo data URI, nejčastěji {{$.Assets.Název}}:

"meta": { "assets": { "Hlavicka": "data:application/pdf;base64,JVBERi0…" },
          "document": { "append": [ "https://firma.cz/vop.pdf" ] } },
"page": { "size": "A4", "orientation": "Portrait", "marginsMm": { "top": 40, "right": 15, "bottom": 25, "left": 15 },
          "letterhead": { "src": "{{$.Assets.Hlavicka}}", "pages": "FirstAndRest" } }

pages: All (výchozí), First, FirstAndRest (první stránka 1. stránkou podkladu, ostatní 2. stránkou). Nedostupný zdroj render nezastaví: PDF vznikne bez něj a RenderOptions.OnBindingDiagnostics (nebo pozorovatel) dostane varování NRP036 s JSON cestou zdroje; kontrolujte je, než fakturu odešlete. Server, který renderuje cizí šablony, má nastavit ResourcePolicy = ResourcePolicy.Server (zdroje ze souborů zakázané, stahování jen z veřejných adres, limity velikosti a času).

PDF/A-3b s přílohou (ISDOC), vstupní data v PDF a heslo:

var options = new RenderOptions
{
    PdfConformance = PdfConformance.PdfA3B,
    Attachments = [ IsdocWriter.CreateAttachment(isdocInvoice) ],   // ISDOC z dat faktury (NetReporter.Isdoc), nebo vlastní new PdfAttachment { ... }
    EmbedData = true,                                   // vstupní JSON jako data.json (null = podle meta.document.embedData)
};

// šifrování (AES-256) nejde spojit s PDF/A
var secured = new RenderOptions { Encryption = new PdfEncryption { UserPassword = "ctenar", OwnerPassword = "vlastnik", AllowModification = false } };

PDF/A-2b přílohy nepovoluje. Volby PDF u jiného formátu než PDF a neslučitelné volby jsou ArgumentException. IsdocWriter složí ISDOC 6.0.2 z IsdocInvoice (součty a rekapitulaci DPH dopočítá, UUID je stabilní, výstup je ověřený proti oficiálnímu XSD); PDF/A ověřte nástrojem veraPDF. Podrobnosti: user/pouziti-knihovny.md a dev/07_renderer_questpdf.md.

Validace šablony

Šablonu lze zkontrolovat bez renderu. Parser ji ověří proti vestavěnému schématu a vrátí diagnostiky s JSON cestou k chybě:

using NetReporter.Common;
using NetReporter.Template.Parsing;

var parser = new TemplateSchemaParser();                  // výchozí ParserValidationMode.Strict
var result = parser.Parse(templateJson);

if (!result.Success)
{
    foreach (var d in result.Diagnostics.Where(d => d.Severity == DiagnosticSeverity.Error))
        Console.WriteLine($"{d.JsonPath}: {d.Message} ({d.Code})");
}
  • Strict hlásí neznámé vlastnosti a chybný obsah stylů (neznámá vlastnost, špatný typ, neplatný enum) jako chybu, Compat jako varování (new TemplateSchemaParser(validationMode: ParserValidationMode.Compat); při renderu new RenderOptions { ValidationMode = ParserValidationMode.Compat }, varování pak dostane pozorovatel v ParseCompletedContext.Diagnostics).
  • Diagnostiky mají stabilní Code a JsonPath (např. $.content.root.items[2].rows.source).
  • Schéma šablon (typy uzlů, vlastnosti, enumy) vrací TemplateSchemaProvider.Create().

Podrobnosti: kapitola 03_parser_and_validation.md.

Data, která šablona čte

Chybějící datové pole se vykreslí prázdné a nikdo o tom nezjistí. Analyzátor zjistí ze šablony (bez renderu), která pole dat čte, a složí z nich JSON Schema nebo ukázková data:

using NetReporter.Template.DataContract;

var contract = new TemplateDataContractAnalyzer().Analyze(templateJson);
foreach (var field in contract.EnumerateFields())
    Console.WriteLine($"{field.Path}  {field.Kind}");          // $.Invoice.Items[*].Total  Number

string schema = contract.ToJsonSchema();                        // JSON Schema 2020-12, bez povinných polí
string sample = new TemplateSampleDataGenerator().GenerateJson(contract);   // deterministická ukázková data

Druh pole se odvodí z použití, formátu a názvu (názvový odhad kontrakt označí); C# výrazy {{# …}} se čtou jen podle zápisu. Podrobnosti: user/pouziti-knihovny.md a kapitola 05_binding_system.md.

Sledování pipeline

IReportPipelineObserver dostává události OnPipelineStarted, OnParseStarted/Completed, OnRenderStarted/Completed (doba, velikost výstupu) a OnError (fáze, kategorie, stabilní kód chyby) – vhodné pro metriky a logování. Registruje se přes AddNetReporter<TObserver>() nebo konstruktor ReportRenderer. Knihovna loguje přes ILogger, pokud předáte ILoggerFactory.

RenderCompletedContext v OnRenderCompleted nese také BindingDiagnostics a OmittedBindingDiagnostics: chyby v bindingech (nedokončené {{, nečíselná hodnota grafu…) render nezastaví, takže je jinak neuvidíte. Shodné diagnostiky se slučují a počet omezuje RenderOptions.MaxBindingDiagnostics (výchozí 200, 0 sběr vypne). Při selhání renderu je (do chyby nasbírané) nese i PipelineError v OnError.

Dokumentace v balíčku

Balíček obsahuje dokumentaci knihovny a šablon ve složce docs/ (po instalaci v %USERPROFILE%\.nuget\packages\netreporter\<verze>\docs\, na Linuxu ~/.nuget/packages/netreporter/<verze>/docs/). Rozcestník je docs/README.md:

Soubor Obsah
docs/user/pouziti-knihovny.md průvodce použitím knihovny krok za krokem
docs/dev/02_template_format.md formát šablony – sekce, uzly, vlastnosti, repeat, tabulky, grafy
docs/dev/03_parser_and_validation.md parser a validace šablon, diagnostiky
docs/dev/04_style_system.md stylovací systém
docs/dev/05_binding_system.md binding a výrazy
docs/dev/17-charts.md grafy – chování a omezení
docs/dev/18-emoji-a-ikony.md emoji a ikony FontAwesome – vestavěné sady, Pro a stahování verzí, licence
docs/dev/01_introduction.md, 06_runtime_pipeline.md, 07_renderer_questpdf.md, 08_program_flow_example.md, 09_extensibility.md architektura knihovny, pipeline, renderer, rozšiřitelnost

Seznam změn všech verzí je v souboru CHANGELOG.md v kořeni balíčku; změny konkrétní verze ukazuje NuGet v release notes balíčku.

Licence

MIT, © Advisor Software s.r.o.

Zdrojový kód, ukázkové šablony a změny verzí: repozitář projektu.

No packages depend on NETReporter.

- Template editor and ReportServer web: help tips (i) next to the controls whose meaning is not obvious at first sight (the preview options, page settings, table and chart editors, properties, versions, assets and ISDOC in the editor; templates, render options, jobs, API tokens, users and metrics on the web). The shared component `HelpTip` (`NetReporter.UiShared`) renders an icon or a dotted-underlined text with the text in `title`; one delegated script `nrTip.js` shows a bubble on hover, focus and tap, so a tip needs no JavaScript or Syncfusion of its own. The texts live in `HelpTipStrings.resx` and `.en.resx` of each application and `HelpTipTests` checks that every key is used and translated. - Website: documentation in `web/manual/` (static pages on the same design system, side navigation and a table of contents per page). The library manual (10 chapters) covers both variants side by side, the full library `NETReporter` rendering in process and the thin client `NETReporter.Client` rendering on ReportServer with an API token: installation and registration, rendering and formats, PDF/A, attachments, ISDOC and encryption, resources and fonts, validation and diagnostics with the full list of `NRP` codes, the data contract, the client, the REST API and the MCP server, and a chapter on using the remote MCP server from AI agents (registration in Claude Code, VS Code and other clients, static and personal tokens, tools, render outputs, limits, errors). The template manual (10 chapters) describes the template format property by property: page, sections and watermarks, styles, palette and fonts, bindings, formats and expressions, layout nodes, content nodes, tables, charts, metadata, assets and ISDOC, and an invoice built step by step. The home page links the manuals from the navigation and a new section. Celý seznam změn: CHANGELOG.md v balíčku a https://dev.azure.com/advsoft/Knihovny/_git/NetReporter?path=/src/NetReporter/CHANGELOG.md

Version Downloads Last updated
3.9.2 3 10/28/2026
3.9.1 1 10/27/2026
3.9.0 6 10/20/2026
3.8.1 6 10/19/2026
3.8.0 4 10/19/2026
3.7.0 4 10/19/2026
3.6.0 6 10/17/2026
3.5.1 62 10/15/2026
3.5.0 4 10/15/2026
3.4.2 5 10/15/2026
3.4.0 4 10/12/2026
3.3.0 5 10/11/2026
3.2.2 5 10/10/2026
3.2.1 4 10/10/2026
3.2.0 4 10/10/2026
3.1.1 4 10/09/2026
3.1.0 5 10/09/2026
3.0.1 8 10/08/2026
3.0.0 5 10/08/2026
2.2.1 5 10/05/2026
2.2.0 4 10/05/2026
2.1.0 9 10/04/2026
2.0.1 8 10/04/2026
2.0.0 5 10/03/2026
1.7.0 6 10/03/2026
1.6.0 5 10/02/2026
1.5.0 12 10/02/2026
1.4.0 6 10/01/2026
1.3.0 4 10/01/2026
1.2.0 5 10/01/2026
1.1.1 6 09/30/2026
1.1.0 8 09/30/2026
1.0.10 4 09/29/2026
1.0.9 4 09/29/2026
1.0.8 16 09/29/2026
1.0.7 115 09/24/2026
1.0.6 9 09/24/2026
1.0.5 7 09/24/2026
1.0.4 11 09/24/2026
1.0.3 8 09/24/2026
1.0.2 13 09/23/2026
1.0.0 7 09/23/2026
0.9.1 13 09/23/2026
0.9.0 87 09/14/2026
0.8.1 25 02/20/2026
0.8.1-preview.1 34 02/13/2026
0.7.1-preview.2 32 02/10/2026
0.7.1-preview.1 33 02/10/2026
0.7.0 30 02/10/2026
0.0.6 28 02/01/2026
0.0.5 19 02/01/2026
0.0.0-alpha.0.17 35 02/01/2026