XmlStackBuilder — API Reference

Kompletní seznam veřejných metod a properties třídy XmlStackBuilder. Většina metod je volatelná z FoxPro přes wwDotnetBridge — výjimky (Stream, IDataReader, interfacy, out parametry, eventy) jsou v tabulkách označené ❌ a mají FoxPro alternativy.

Tip pro AI-asistovaný vývoj sestav: XSB je navržen tak, aby kombinace generátorů (CursorSchemaGenerator, DocumentTemplateGenerator)


Properties

Obecné

Property Typ Popis
Depth int Aktuální hloubka zásobníku elementů (read-only)
CurrentElement XElement Aktuální element na zásobníku (read-only)
Root XElement Kořenový element (read-only)
CsvDelimiter string Oddělovač pro CSV export validačních chyb (default ";")

HTML generování

Property Typ Default Popis
HtmlDocumentTitle string "" Název dokumentu v HTML záhlaví
HtmlCompanyName string "" Název firmy v HTML záhlaví
HtmlReportPeriod string "" Období sestavy (např. "12/2025")
HtmlOutputMode string "print" Režim: "print" nebo "interactive"
HtmlShowTechnicalNames bool false Zobrazit technické názvy elementů
HtmlFormatNumbers bool true Formátovat čísla s oddělovačem tisíců
HtmlHideEmptyValues bool false Skrýt prázdné hodnoty
HtmlXsdValidationPath string "" Cesta k XSD pro inline validaci
HtmlSectionLabelsPath string "" Cesta k .labels souboru s popisky sekcí (auto-detekce vedle HTML/XML)
HtmlErrorMessage string — Poslední chybová zpráva (read-only)
TemplateWarnings string — Varování z validace JSON šablony (read-only)
EmailMode bool false HTML výstup převést na e-mail-friendly variantu (inline CSS, bez script/@media, single-file)

Batch, tisk a průběh

Property Typ Default Popis
BatchOutput string "" Batch režim: "" (off), cesta PDF, "PRINTER:", "PRINTER:název"
ShowProgress bool false Zobrazit WinForms dialog s průběhem renderování
PdfFromHtml bool false Dokumenty: PDF přes HTML→WebView2 místo přímého MigraDoc
PrintDialog bool false Zobrazit dialog při tisku (auto-reset po zobrazení)
PrintFromPage int 0 Od stránky (0 = od začátku)
PrintToPage int 0 Do stránky (0 = do konce)
PrintCopies int 1 Počet kopií (1–999)
PrintDuplex int 0 0=default, 1=simplex, 2=oboustranný vertical, 3=horizontal
PrintCollate bool false Kompletovat kopie
BatchPageCount int 0 Počet stránek v batchi (read-only)
BatchDocumentCount int 0 Počet dokumentů v batchi (read-only)

ShowProgress zobrazí WinForms dialog s progress barem, číslem řádku a tlačítkem "Storno" pro přerušení. Dialog běží na samostatném STA threadu — renderování zůstává synchronní. Při zrušení se nastaví HtmlErrorMessage a Render() vrátí false. Property přežívá Reset() i EndBatch().


XML Builder

Metoda Návrat Popis
CreateRoot(elementName) self Vytvoří kořenový element
CreateRootWithNamespace(elementName, namespaceName) self Vytvoří kořen s namespace
Push(elementName) self Přidá child element a vstoupí do něj
PushWithNamespace(elementName, namespaceName) self Push s explicitním namespace
Push(elementName, content) self Push s obsahem (text/číslo)
Pop() self Vystoupí z aktuálního elementu
PopToRoot() self Vystoupí na kořen
PopTo(depth) self Vystoupí na zadanou hloubku
ResetToRoot() void Vystoupí na kořen (void varianta)
AddAttribute(name, value) self Přidá atribut (prázdné přeskočí)
AddOptionalAttribute(name, value) self Přidá volitelný atribut
AddRequiredAttribute(name, value) self Přidá povinný atribut (null → "")
AddAttributes(params (name, value)[]) self Přidá více atributů najednou
SetValue(value) self Nastaví textový obsah elementu
AddElement(elementName) self Přidá prázdný child element
AddElement(elementName, content) self Přidá child element s obsahem
AddElement(elementName, content, attributes[]) self Přidá element s obsahem a atributy
AddElementWithValue(elementName, content) self Přidá element s validací
AddElementWithXmlContent(elementName, xmlContent) self Vloží surové XML potomky (strip VFPData)
AddElementFromDbf(elementName, dbfPath) int Vloží řádky FoxPro tabulky (DBF + FPT) jako <row …/> ve tvaru CURSORTOXML(…, 3, 16); soubor otevírá sdíleně; počet řádků, -1 = chyba v LastDbfError. Pro velké kurzory místo CURSORTOXML
AddComment(comment) self Přidá XML komentář
AddCData(data) self Přidá CDATA sekci
AddNamespace(prefix, namespaceName) self Přidá namespace deklaraci
SetDefaultNamespace(namespaceName) self Nastaví výchozí xmlns

Velké kurzory: data přímo z DBF (AddElementFromDbf, od 1.1.190)

CURSORTOXML + AddElementWithXmlContent u velkých kurzorů (desítky tisíc řádků, XML desítky MB) ve 32bitovém FoxPro padá na paměti: řetězec se přes wwDotnetBridge převádí do .NET a znovu parsuje. AddElementFromDbf čte tabulku (DBF + FPT memo) přímo ze souboru:

Doporučený postup (ověřený ve FoxPro): COPY TO do dočasné tabulky. Ctí aktivní pořadí, filtr, SET DELETED i klauzule FOR / FIELDS a zapíše i věty, které FoxPro drží jen v paměti — výsledek tak odpovídá tomu, co by vydal CURSORTOXML. Aktuální větu kurzoru COPY TO posune, proto se před ním uloží a po něm vrátí:

Select (lcAlias)
lnRecno = RECNO()
lcTmp = jmenos(ALIAS(), 1)          && dočasný název tabulky i s příponou .dbf

Copy To (m.lcTmp)                   && případně &tcKlauzule. &tcPole.

If Between(m.lnRecno, 1, Reccount())
	Go m.lnRecno
Else
	Locate                          && byl EOF / prázdný kurzor / nová věta v bufferu -> první věta
Endif

lnRows = loBuilder.AddElementFromDbf("data", m.lcTmp)
* surový export: lnRows = loBuilder.ExportDbfToXlsx(m.lcTmp, lcXlsx, "sheet:Data,bool:Ano;Ne")

Erase (m.lcTmp)
If File(Forceext(m.lcTmp, "fpt"))
	Erase (Forceext(m.lcTmp, "fpt"))
Endif

IF m.lnRows < 0                     && chyba (LastDbfError / LastXlsxError) -> postaru přes CURSORTOXML
	CURSORTOXML(lcAlias, "lcXml", 3, 16)
	loBuilder.AddElementWithXmlContent("data", m.lcXml)
ENDIF
Na co myslet Proč
názvy polí COPY TO do volné tabulky zkrátí názvy na 10 znaků (CURSORTOXML je nechá dlouhé) — u kurzoru z DBC s dlouhými názvy se musí shodovat se šablonou
SET DELETED OFF COPY TO zkopíruje i smazané věty a čtení DBF je vždy vynechá (CURSORTOXML by je vypsal)
práh u malých kurzorů je CURSORTOXML stejně dobrý; v tiskové třídě se DBF cesta používá od ~30 000 řádků

Přímé čtení DBF(alias) bez kopie (kurzor READWRITE, bez ORDER()/FILTER(), FLUSH IN … FORCE) je možné, ale závisí na stavu kurzoru; tisková třída používá kopii výše.

Surový export do XLSX z DBF (od 1.1.192): ExportDbfToXlsx(dbfPath, xlsxPath, options) — místo CURSORTOXML(…, 512+…) + ExportCursorXmlToXlsxWithOptions. Typy sloupců bere z hlavičky DBF (stejné jako inline XSD), volby stejné (sheet:, autofilter:0, freeze:0, bool:Ano;Ne), návrat = počet řádků, -1 = chyba v LastXlsxError. S ShowProgress = .T. ukáže dialog „Export do XLSX“ (od 1.1.193; Storno = -1, soubor nevznikne). Saldokonto 135 tisíc řádků ve 32bitovém procesu: 26 s, 220 MB.

Render pak (od 1.1.191) předá data rendererům tabulek přímo, bez převodu na text: saldokonto 135 tisíc řádků ve 32bitovém procesu ~0,8 GB, PDF ~6 minut (viz CHANGELOG 1.1.190–1.1.193).


Výstup XML

Metoda Návrat Popis
ToDocument() XDocument Vrátí interní XDocument
ToXmlString() string XML jako string
ToFormattedXmlString() string XML s odsazením
SaveToFile(filePath) void Uloží XML do souboru
Reset() void Vymaže XML, zachová batch/print/config

Round-trip — úprava existujícího XML

Načtení existujícího XML a nahrazení / doplnění / odebrání opakujících se kolekcí na správné pozici dle XSD, poté uložení zpět (SaveToFile / ToXmlString). Hlavní use-case: doplnit do rozpracovaného přiznání k DPPO věty účetních výkazů (rozvaha VetaUA/VetaUB, výsledovka VetaUD) bez generování celého dokumentu znovu.

Metoda / Property Návrat Popis
LoadXml(xmlOrFile) bool Načte existující XML (string začínající <, jinak cesta k souboru) pro úpravy
RoundTripSchemaPath string Cesta k XSD (nebo XSD obsah) pro správné řazení vkládaných kolekcí. Volitelné
ReplaceCollection(parentPath, elementName, rowsXml) int Smaže všechny elementName pod rodičem, z rowsXml vytvoří nové (na XSD pozici / pozici původních / konec). Vrací počet vložených, -1 chyba
AppendCollection(parentPath, elementName, rowsXml) int Přidá kolekci bez odebrání stávajících. Vrací počet vložených, -1 chyba
RemoveCollection(parentPath, elementName) int Odebere všechny elementName pod rodičem. Vrací počet odebraných, -1 chyba
LastRoundTripError string Popis poslední chyby (prázdné = bez chyby)

Pravidla:

Příklad (FoxPro) — doplnění účetních výkazů do přiznání k DPPO:

loBuilder.LoadXml("priznani_rozpracovane.xml")          && načte existující dokument
loBuilder.RoundTripSchemaPath = "xsd\dppdp9_epo2.xsd"   && (volitelně) pro správné řazení dle XSD

*--- rozvaha aktiva: cursor tmpUA → každý řádek se vloží jako <VetaUA> ---
CURSORTOXML("tmpUA", "lcUA", 3, 16)
loBuilder.ReplaceCollection("DPPDP9", "VetaUA", m.lcUA)  && smaže staré, vloží nové na správné místo

*--- rozvaha pasiva ---
CURSORTOXML("tmpUB", "lcUB", 3, 16)
loBuilder.ReplaceCollection("DPPDP9", "VetaUB", m.lcUB)

*--- výsledovka ---
CURSORTOXML("tmpUD", "lcUD", 3, 16)
loBuilder.ReplaceCollection("DPPDP9", "VetaUD", m.lcUD)

IF loBuilder.ReplaceCollection("DPPDP9", "VetaUA", m.lcUA) = -1
    ? "Chyba: " + loBuilder.LastRoundTripError
ENDIF

loBuilder.SaveToFile("priznani_doplnene.xml")

Příklad (.NET) — statický helper nad XElement:

var doc = XDocument.Load("priznani.xml");
var dppdp9 = doc.Root.Element("DPPDP9");
var order = XmlRoundTrip.GetChildOrderFromXsd("xsd/dppdp9_epo2.xsd", "DPPDP9");

XmlRoundTrip.ReplaceCollection(dppdp9, "VetaUA", rowsXmlUA, order);
XmlRoundTrip.ReplaceCollection(dppdp9, "VetaUB", rowsXmlUB, order);
XmlRoundTrip.ReplaceCollection(dppdp9, "VetaUD", rowsXmlUD, order);
doc.Save("priznani_doplnene.xml");

Deserializace XML → DTO

Čtení XML do XSD-generovaných modelů (Models.Accounting/Payroll/Erp) přes XmlSerializer — opačný směr k builderu. Use-case: čtení potvrzenek / chybových protokolů z EPO či datové schránky, validační smyčka „vygeneruj → deserializuj → porovnej". FoxPro neumí .NET generika ani objektový graf → fasáda DeserializeXml + GetDtoField(path).

Metoda / Property Návrat Popis
DeserializeXml(xmlOrFile, typeName) bool Načte XML (string <… / cesta) do typu typeName (plný "Dphdp3Epo2.Pisemnost", koncovka i prosté jméno). Výsledek do DeserializedObject
GetDtoField(path) string Hodnota pole z DeserializedObject dle cesty ("Dphdp3.Veta1.dan_zocelk", kolekce "Polozky[0].kc" 0-based). Matchuje C# i XML názvy. Prázdné = nenalezeno
DeserializedObject object Poslední deserializovaný objekt (i pro .NET / wwDotnetBridge)
LastDeserializeError string Popis poslední chyby (prázdné = OK)
DtoDeserializer.Deserialize<T>(xmlOrFile) T Statické generické API (.NET)
DtoDeserializer.GetField(root, path) string Path accessor nad libovolným objektem
IF loBuilder.DeserializeXml("odpoved.xml", "Dphdp3Epo2.Pisemnost")
    ? loBuilder.GetDtoField("verzeSW")
ELSE
    ? loBuilder.LastDeserializeError
ENDIF
var p = XmlStackBuilder.Core.DtoDeserializer.Deserialize<Dphdp3Epo2.Pisemnost>("odpoved.xml");

Pozn.: DTO assembly (model) musí být přítomná vedle XmlStackBuilder.Core.dll. Decimal/čísla se formátují invariantně (zachová koncovou nulu, např. 1000.50).


Datová schránka (ISDS) — odeslání podání

Přepravní vrstva pro podání datovou schránkou (ČSSZ REGZEC/JMHZ apod.) — nevyžaduje el. podpis. XSB poskytuje bezstavový SOAP klient + kodek zpráv; stav podání / perzistenci / polling / UI řeší aplikace (viz NAVRH_DATOVA_SCHRANKA_CSSZ.md). Stažené odpovědi ČSSZ se čtou přes deserializaci výše.

Metoda / Property Návrat Popis
IsdsConfigure(env, login, password, certThumbprint) bool env "test"/"prod"; cert thumbprint volitelný (jinak jméno+heslo)
IsdsSenderBoxId string ID naší schránky (odesílatel)
IsdsSendFile(recipientBoxId, subject, xmlFilePath, attachmentName) string Odešle XML soubor jako přílohu; vrací dmID nebo ""
IsdsSendXml(recipientBoxId, subject, xmlContent, attachmentName) string Totéž z XML stringu
IsdsListReceived(fromDateIso, toDateIso) string Plochý <zpravy><zprava dmID… predmet… ref…/></zpravy> k párování
IsdsDownloadResponse(dmId, outputFolder) bool Stáhne zprávu, uloží přílohy do složky, označí jako přečtené
LastIsdsError string Chyba poslední ISDS operace
IsdsClient (.NET) — SendMessage/ListReceivedMessages/DownloadMessage/MarkMessageAsDownloaded
loBuilder.IsdsConfigure("test", "login", "heslo", "")
loBuilder.IsdsSenderBoxId = "abc1234"
lcDmId = loBuilder.IsdsSendFile("ID_schranky_CSSZ", "e-Podání REGZEC", "REGZEC.xml", "REGZEC.xml")
IF EMPTY(lcDmId)
    ? loBuilder.LastIsdsError
ENDIF
*--- později: stáhnout odpověď a přečíst přes deserializaci ---
IF loBuilder.IsdsDownloadResponse(lcOdpovedDmId, "C:\tmp\odp")
    loBuilder.DeserializeXml("C:\tmp\odp\protokol.xml", "<TYP_ODPOVEDI>")
ENDIF

⚠️ Endpointy a přesné názvy polí ISDS jsou označeny k ověření proti czebox testu; síťové metody nejsou unit-testované (offline je jen kodek). Před produkčním nasazením otestovat proti czebox.cz.


Validace XML

Metoda Návrat Popis
SetValidationEnabled(enabled) void Zapne/vypne validaci
RegisterValidationRule(rule) void Registruje pravidlo (regex, min/max, délka)
RegisterElementNamespace(elemName, nsUri, parent) void Registruje namespace pro element
RegisterElementNs(elemName, nsUri, parent) void Totéž bez overloadu (FoxPro)
RegisterRequiredAttribute(key) void Registruje povinný atribut ("Element:Attr")
GetValidationErrors() List Seznam validačních chyb
GetValidationErrorCount() int Počet chyb
HasValidationErrors() bool Jsou chyby?
GetValidationErrorsAsLog() string Chyby jako textový log
GetValidationErrorsAsCsv() string Chyby jako CSV
ClearValidationErrors() void Vymaže chyby

HTML z XML (opis XML s popisky z XSD)

Metoda Návrat Popis
SaveToHtmlFile(htmlPath, xsdPath) bool Uloží XML jako HTML s popisy z XSD
ToHtmlString(xsdPath) string Vrátí HTML string
SaveToHtmlFileWithValidation(htmlPath, xsdPath) bool HTML s inline XSD validací (zvýrazněné chyby)
SaveXmlFileToHtmlWithValidation(xmlPath, htmlPath, xsdPath) bool HTML z XML souboru s validací
SaveToHtmlFileSingleRow(htmlPath, xsdPath) bool HTML varianta „jeden prvek = jeden řádek" (viz níže)

Režim „jeden prvek = jeden řádek" (SingleRowMode)

Varianta HTML opisu XML, kde je každý atribut nebo leaf element na samostatném řádku se třemi sloupci: název | popis z XSD | hodnota. Popis elementu (pokud je v XSD) se navíc zobrazuje vedle nadpisu sekce kurzívou. Opakující se sekce (více záznamů stejného jména) se rozpadnou na samostatné karty s číslováním #1, #2…

Zapnout lze buď jednorázovou metodou SaveToHtmlFileSingleRow, nebo propertou HtmlSingleRowMode = .T. (režim pak platí i pro SaveToHtmlFileWithValidation a SaveXmlFileToHtmlWithValidation).

Property:

Property Typ Default Popis
HtmlSingleRowMode bool false Zapne režim single-row pro všechny HTML opis metody

Použití z FoxPro:

*--- Varianta 1: jednorázová metoda (režim se po zavolání vrátí zpět) ---
loBuilder.SaveToHtmlFileSingleRow("out.html", "C:\xsd\REGZEC")

*--- Varianta 2: property + existující metody (včetně validace) ---
loBuilder.HtmlSingleRowMode = .T.
loBuilder.SaveToHtmlFileWithValidation("out.html", "C:\xsd\REGZEC")

*--- Z XML souboru (bez interního builderu) ---
loBuilder.HtmlSingleRowMode = .T.
loBuilder.SaveXmlFileToHtmlWithValidation("data.xml", "out.html", "C:\xsd\REGZEC")

Použití v C# (HtmlDataRenderer přímo):

var renderer = new HtmlDataRenderer
{
    SingleRowMode = true,
    XsdValidationPath = @"C:\xsd\REGZEC"  // volitelně inline validace
};
renderer.LoadDescriptionsFromXsd(@"C:\xsd\REGZEC");
var doc = XDocument.Load(xmlPath, LoadOptions.SetLineInfo);
renderer.RenderToFile(doc, htmlPath);

CSS třídy výstupu: .single-row-table, .sr-name, .sr-desc, .sr-val, .section-desc, .single-row-card. | ValidateTableReportJson(jsonMetadata) | string | Validuje JSON šablonu tabulkové sestavy | | ValidateDocumentJson(jsonMetadata) | string | Validuje JSON šablonu dokumentu |


Tabulkové sestavy (HTML)

Metoda Návrat Popis
ToTableReport() string HTML sestava (auto-detekce struktury)
ToTableReportWithHeader(title, company, filter) string HTML sestava se záhlavím
ToTableReportWithMetadata(jsonMetadata) string HTML sestava s JSON šablonou
SaveTableReportToFile(htmlPath, title, company, filter) bool Uloží HTML sestavu
SaveTableReportToFileWithMetadata(htmlPath, jsonMetadata) bool Uloží s JSON šablonou (string)
SaveTableReportToFileWithMetadataFile(htmlPath, jsonFilePath) bool Uloží s JSON ze souboru (UTF-8)
GenerateTableReportMetadata() string Vygeneruje JSON šablonu z XML (light)
GenerateTableReportMetadataFull() string Vygeneruje kompletní JSON šablonu

Dokumenty — faktury, dodací listy (HTML)

Metoda Návrat Popis
ToDocumentHtml(jsonMetadata) string HTML dokument z JSON šablony
SaveDocumentToFile(htmlPath, jsonMetadata) bool Uloží HTML dokument (JSON string)
SaveDocumentToFileFromJson(htmlPath, jsonFilePath) bool Uloží HTML dokument (JSON ze souboru)

DOCX — editovatelný Word dokument

Ze stejných JSON šablon + XML dat vytvoří editovatelný .docx (přes DocumentFormat.OpenXml) — vedle HTML/PDF/XLSX. Funguje pro dokumentové šablony (renderer "document" → DocxDocumentRenderer) i pro tabulkové sestavy (renderer "table" → DocxTableReportRenderer). Label šablony do DOCX nejdou. Word si layout/styly řídí sám → konzistentní výstup, ne pixel-shoda s HTML/PDF.

Metoda / cesta Návrat Popis
Render(path.docx, json) bool Auto-detekce typu šablony (dokument/tabulka) i formátu z přípony
SaveDocumentToDocx(docxPath, jsonMetadata) bool Dokument → .docx (XML z interního builderu, JSON string)
SaveDocumentToDocxFromJson(docxPath, jsonFilePath) bool Dokument → .docx (JSON ze souboru, UTF-8)
SaveTableReportToDocx(docxPath, jsonMetadata) bool Tabulková sestava → .docx (XML z interního builderu, JSON string)
SaveTableReportToDocxFromJson(docxPath, jsonFilePath) bool Tabulková sestava → .docx (JSON ze souboru, UTF-8)
DocxDocumentRenderer.RenderToFile/RenderToBytes(...) bool/byte[] Statické API — dokumenty
DocxTableReportRenderer.RenderToDocx/RenderToBytes(...) bool/byte[] Statické API — tabulkové sestavy
loBuilder.Render("faktura.docx", "faktura.json")        && dokument → Word (auto-detekce)
loBuilder.Render("prehled.docx", "prehled.json")        && tabulková sestava → Word (auto-detekce)
loBuilder.SaveDocumentToDocx("faktura.docx", lcJson)     && explicitně dokument
loBuilder.SaveTableReportToDocx("prehled.docx", lcJson)  && explicitně tabulka

Dokumentové bloky: text-block, info-grid, table (+sumExpressions), header-two-column, total-amount, signature, separator, spacer, page-break, columns, image, qr-code, barcode. repeatElement + pageBreakBetween; form-table zatím fallback (text).

Tabulkové sestavy (DocxTableReportRenderer) mají paritu s ostatními renderery: sekce, sloupce (formáty/zarovnání/šířky/expr/template/running totals/hideZero/visibleWhen/negativeRed/suppressRepeat), skupiny (element-based i groupExpression, inline/external záhlaví, tableBreak, reprintHeader, forceNewPage, barvy/headerValues, lookupy), součtové řádky (sumExpressions/sumRows vč. where/labelField/per-cell stylů), footerRows, víceřádkové záhlaví headerRows (colspan/rowspan), rowStyles, alternateRowBackground, dictionary překlad, kontingenční tabulka pivot (→ Word tabulka) i graf chart (→ vložený PNG). Word si stránkuje sám (žádné virtuální pageLayout).

Sdílí šablonový engine ({field}, {element.field}, formáty, coalesce, ternár, funkce) i výrazy s ostatními renderery — jedna šablona = stejný výstup do HTML / PDF / XLSX / DOCX.

Layoutové vlastnosti (jedna šablona → stejný výstup HTML/PDF/DOCX): minHeightMm (header-two-column left/right — vyrovná výšku orámovaných boxů), rowHeightMm (table — min. výška řádku), border/borderFullWidth (rámeček sloupce v columns — podpisové boxy), gap/gapPx (mezera mezi sloupci v px, default 15 — shodná sémantika napříč renderery), { "type": "spacer", "heightMm": N } jako pole v header-two-column (volný řádek).

Kompatibilita s MS Word (proč se .docx otevírá bez „nečitelného obsahu"). DocumentFormat.OpenXml na .NET Frameworku používá System.IO.Packaging z WindowsBase, který zapisuje balíček způsobem, jenž Word sice přijme, ale „opraví" (dialog Nečitelný obsah). Renderer to po sestavení automaticky normalizuje, takže výstup je strukturně shodný s tím, co generuje sám Word:

Tyto problémy OpenXmlValidator nehlásí (kontroluje jen schéma, ne fyzické URI/umístění/strukturu).


Unified Render API

Univerzální metody — auto-detekce typu šablony (tabulka/dokument) a formátu výstupu (HTML/PDF/XLSX/DOCX) z přípony souboru (.docx jen pro dokumentové šablony).

Tabulková šablona může obsahovat sekci "flatten" — deklarativní zploštění hlubokého XML (elektronická podání JMHZ/HOZ/PPPZ/REGZEC/DPH) na ploché tabulky přímo při renderování, vč. filtru na jeden záznam přes SetRenderParam (karta pracovníka) a formátování hodnot. Popis viz TABLE_REPORT_RENDERER_JSON.md → „flatten", hotové šablony v docs/priklady/. Jména osob (JMHZ je neobsahuje) čte flatten ze souboru <xml>.labels vedle datového XML.

Šablona může dědit (od 1.1.144): "extends": "_base/table.json" na kořeni a { "$include": "x.json" } kdekoli v objektu; cesty se řeší relativně k souboru šablony (RenderContext.TemplateDir, nastaví se při předání cesty), u šablony předané jako řetězec relativně k aktuální složce; když soubor vedle šablony není, hledá se v záložní složce TemplateFallbackDir (od 1.1.177 — uživatelská kopie v json_local dědí ze základu v repo_json). Pravidla slučování a konverze složek (xsb factor) viz TABLE_REPORT_RENDERER_JSON.md → „Dědičnost šablon".

Metoda Návrat Popis FoxPro
Render(outputPath, jsonOrFile) bool Renderuje z interního XML builderu ✅
RenderFromFiles(outputPath, jsonOrFile, xmlOrFile) bool Renderuje z externích souborů/stringů ✅
RenderWithDictionary(path, json, IDictionary) bool Render s překladem ze slovníku (Hashtable) ✅
ValidateAndRender(outputPath, jsonOrFile) bool Validace + render. Varování v TemplateWarnings. ✅
RenderToBytes(format, jsonOrFile) byte[] Výstup do paměti (buffrované) ✅
AttachToPdf(sourcePdf, attachment, outputPdf) bool Přiloží soubor (ISDOC/XML) do PDF ✅
RenderToStream(outputStream, format, jsonOrFile) bool Renderuje do Stream (web API, bez bufferu) ❌ Stream
RenderFromFilesToStream(outputStream, format, jsonOrFile, xmlOrFile) bool Stream + externí XML ❌ Stream
RenderWithTranslator(path, json, IDictionaryTranslator, lang) bool Render s překladem labelů přes interface ❌ interface
ValidateAndRenderWithWarnings(path, json, out warnings) bool Stejné jako ValidateAndRender, ale s out ❌ out
InjectDictionary(jsonOrTemplate, IDictionaryTranslator, language) void Manuálně injektovat slovník překladů ❌ interface
OnRenderProgress event Web-friendly progress (Blazor/SignalR) ❌ event
AddDataReader(name, reader) self Streaming z DB readeru do XML ❌ IDataReader
AddDataReaderToPrimaryTable(name, reader) self Stejné + materializace do PrimaryDataTable ❌ IDataReader
SetRenderParam(name, value) void Render-parametr — údaj mimo datové XML (adresa firmy…); přimíchá se do dat jako atribut elementu parametr (bez tečky) / "element.pole". Aktivuje nativní adresu firmy v záhlaví a {parametr.x} placeholdery. Přežívá Reset(). ✅
ClearRenderParams() void Smaže render-parametry nastavené přes SetRenderParam ✅
CheckTemplate(jsonOrFile, xmlOrFile) bool Kontrola šablony (od 1.1.144): neznámé klíče s návrhem opravy, syntaxe každého výrazu a podmínky s pozicí, neznámé funkce, extends; s XML daty i elementy, sloupce a pole. xmlOrFile může být "". true = bez chyb; report (chyby i varování, řádky [chyba] cesta: text) v LastCheckReport. Totéž dělá xsb check. ✅
LastCheckReport string Výsledek posledního CheckTemplate (prázdný = bez nálezů) ✅
LastCheckErrors, LastCheckWarnings int Počty chyb a varování poslední kontroly (od 1.1.180; pro titulek hlášky) ✅
WriteCheckReportHtml(htmlPath) bool Výsledek poslední kontroly jako samostatná HTML stránka pro gourl (od 1.1.180): šablona, data (+ počet elementů), počty, nálezy s odlišením chyb a varování; bez nálezů to řekne výslovně. CheckTemplate od 1.1.180 pozná i Markdown šablonu (.md: vyváženost bloků, pole proti datům) — tisková třída tak má jedno volání pro oba typy. ✅
If !loBuilder.CheckTemplate("repo_json\frx_saldo07.json", "c:\temp\saldo.xml")
   Messagebox(loBuilder.LastCheckReport)
Endif

Akce „zkontrolovat šablonu“ v tiskové třídě (programátor; v tiskall je to nAkce = 90, nasazeno 25. 9. 2026): projde stejná cesta jako tisk (data, výběr šablony vč. json_local a záložní složky), na konci místo renderu kontrola nad skutečnými daty:

This.jfrx_builder.SaveToFile(This.jfrx_builder.FrxXmlDataPath)
This.jfrx_builder.CheckTemplate(This.jfrx_jsonFile, This.jfrx_builder.FrxXmlDataPath)   && JSON i .md
lcHtml = Forceext(This.jfrx_builder.FrxXmlDataPath, "check.html")
If This.jfrx_builder.WriteCheckReportHtml(m.lcHtml)
	gourl(m.lcHtml)
Else
	Messagebox(This.jfrx_builder.LastCheckReport, 48, Transform(This.jfrx_builder.LastCheckErrors) + " chyb", 3000)
Endif

Pravidla pro FoxPro-volatelná API

FoxPro přes wwDotnetBridge přes COM nezvládá:

Proto má XSB dvě varianty kde to dává smysl:

Sloupec „FoxPro" v tabulce ukazuje, co si může FoxPro klient zavolat. ❌ neznamená, že je metoda špatná — jen že má smysl jen v .NET kontextu. Pojmenování zůstává unikátní (ne overloady), aby se při budoucích úpravách FoxPro klienti neporanili při náhodném loBuilder.Render(...) se 3+ parametry, kdy by wwDotnetBridge mohl resolvovat na .NET-only overload.

outputPath: přípona určuje formát — .html, .pdf, .xlsx, PRINTER: (tisk) jsonOrFile: začíná { → JSON string, jinak → cesta k souboru xmlOrFile: začíná < → XML string, jinak → cesta k souboru format (pro Stream): "pdf", "html", "xlsx"

Statické pomocné metody

Metoda Návrat Popis
XmlStackBuilder.GetEmbeddedSchema(templateType) string Vrátí JSON schema z embedded resources ("table", "document", "label")
XmlStackBuilder.DetectTemplateType(json) string Auto-detekce typu šablony ("table"/"document"/"label" nebo null); rozbalí extends, takže pozná i typ zděděný z předka
JsonTemplateValidator.CheckFiles(jsonPath, xmlPath) TemplateValidationResult .NET podoba CheckTemplate (HasErrors, Warnings, FormatAsText()); ValidateWithData(json, typ, xml) pro obsah v paměti

Properties pro mezivrstvu

Property Typ Popis
PrimaryDataTable DataTable První DataTable předaná přes AddDataTable (read-only). Slouží pro Browse režim v mezivrstvě bez parsování XML.
OnRenderProgress event EventHandler<RenderProgressEventArgs> — funguje na .NET 4.8 i .NET 9/10, web-friendly alternativa k WinForms ShowProgress dialogu

PDF generování

Přes WebView2 (HTML → PDF)

Metoda Návrat Popis
SaveHtmlToPdf(htmlPath, pdfPath) bool Konvertuje existující HTML na PDF
SaveDocumentToPdf(pdfPath, jsonMetadata) bool Dokument → HTML → PDF
SaveDocumentToPdfFromJson(pdfPath, jsonFilePath) bool Dokument → PDF (JSON ze souboru)
SaveTableReportToPdf(pdfPath, jsonMetadata) bool Sestava → HTML → PDF
IsPdfAvailable() bool Je WebView2 Runtime nainstalován?

Přímé PDF (MigraDoc) — bez WebView2, vysoký výkon

Metoda Návrat Popis
SaveTableReportToPdfDirect(pdfPath, jsonMetadata) bool Sestava → PDF přímo (JSON string)
SaveTableReportToPdfDirectFromFile(pdfPath, jsonFilePath) bool Sestava → PDF (JSON ze souboru)
SaveDocumentToPdfDirect(pdfPath, jsonMetadata) bool Dokument → PDF přímo (JSON string)
SaveDocumentToPdfDirectFromFile(pdfPath, jsonFilePath) bool Dokument → PDF (JSON ze souboru)

XLSX generování (ClosedXML)

Metoda Návrat Popis
SaveTableReportToXlsx(xlsxPath, jsonMetadata) bool Sestava → Excel (JSON string)
SaveTableReportToXlsxFromFile(xlsxPath, jsonFilePath) bool Sestava → Excel (JSON ze souboru)

XLSX šablona — plnění existujícího sešitu

Naplní data do existující XLSX šablony (zachová hlavičky a formátování) — na rozdíl od XLSX generování, které vytváří nový sešit z JSON definice. Typické použití: portálové import-šablony (např. objednávky stravenek), kde řádky 1–2 jsou hlavičky/popisky a data se vkládají od řádku 3.

Metoda / Property Návrat Popis
FillXlsxTemplate(templatePath, outputPath, startRow, sheet) bool Naplní šablonu z aktuálně sestaveného XML. startRow default 3, sheet = název / číslo (1-based) / prázdné = první list
LastXlsxError string Czech chybová zpráva po FillXlsxTemplate (null = OK)
XlsxTemplateFiller.FillFromXml(xmlData, templatePath, outputPath, startRow, sheet, out err) int Statická varianta — přímo z XML stringu; vrací počet zapsaných řádků

Chování:

* kurzor -> XML (element-centric: nFormat = 1), pole v pořadí sloupců šablony
SELECT objednavky
CURSORTOXML("objednavky", "lcXml", 1, 0, 0, "")

loXsb = loBridge.CreateInstance("XmlStackBuilder.Core.XmlStackBuilder")
loXsb.CreateRoot("objednavka")                    && NEJDŘÍV root (Push ho nezakládá)
loXsb.AddElementWithXmlContent("radky", lcXml)    && strhne <?xml?> i <VFPData>

IF !loXsb.FillXlsxTemplate("sablona.xlsx", "vystup.xlsx", 3, "")
    MESSAGEBOX("Chyba: " + loXsb.LastXlsxError, 16)
ENDIF

Pozor: root dokumentu musí existovat před AddElementWithXmlContent — použij CreateRoot("...") nebo konstruktor CreateInstance("...XmlStackBuilder", "root"). Samotný Push root nezakládá.

Personalizace šablony (statické metody)

Pro šablony určené k vyplnění a návratu (sběrové formuláře — např. výkazy firem skupiny v programu Konsolidace): zápis jednotlivých buněk, výměna bloku řádků (číselník), doplnění hodnot podle klíče a zamknutí listů heslem. Všechny metody jsou statické na XmlStackBuilder.Core.XlsxTemplateFiller, pracují přímo nad zadaným souborem (kopii šablony si předem vyrobí volající, např. COPY FILE), datové vstupy jsou XML z CURSORTOXML(…, 1, 0) s poli po řadě.

Metoda / Property Návrat Popis
SetCellsFromXml(xlsxPath, xmlData) int Každý XML řádek = jeden zápis: 1. pole = list, 2. = adresa buňky ("C6"), 3. = hodnota (typovaná; prázdná buňku vyčistí). Vrací počet zapsaných buněk
FillSheetRowsFromXml(xlsxPath, sheet, startRow, startCol, xmlData) int Blok řádků od buňky (startRow, startCol); starý obsah čistí jen ve sloupcích bloku — ostatní sloupce listu nedotčené
FillColumnByKeyFromXml(xlsxPath, sheet, keyCol, valueCol, startRow, xmlData) int XML dvojice (klíč, hodnota); projde list a kde buňka v keyCol odpovídá klíči, zapíše hodnotu do valueCol. Typicky předvyplnění „minulé období" podle klíče výkazu
ProtectAllSheets(xlsxPath, password) int Zamkne všechny listy heslem (zamčené/odemčené buňky dle stylů šablony); listy zamčené bez hesla přezamkne. Vrací počet zamčených listů
LastError string Chybová zpráva poslední personalizační operace ("" = OK) — z FoxPro čitelná přes GetStaticProperty
* personalizace kopie sablony (FoxPro pres wwDotnetBridge)
COPY FILE (lcSablona) TO (lcVystup)

SELECT Alltrim(kod) + " | " + Alltrim(nazev) AS comb, kod, nazev, ico ;
    FROM firmy WHERE rok = lcRok INTO CURSOR curfir
CURSORTOXML("curfir", "lcXml", 1, 0)
lnN = loBridge.InvokeStaticMethod("XmlStackBuilder.Core.XlsxTemplateFiller", ;
    "FillSheetRowsFromXml", lcVystup, "Číselníky", 2, 1, lcXml)
lcErr = loBridge.GetStaticProperty("XmlStackBuilder.Core.XlsxTemplateFiller", "LastError")

loBridge.InvokeStaticMethod("XmlStackBuilder.Core.XlsxTemplateFiller", ;
    "ProtectAllSheets", lcVystup, lcHeslo)

Reálné nasazení: GEN_XLSX.PRG programu Konsolidace (titulní strana, číselník firem, minulé období z deníku roku−1 podle klíče, zámek heslem z parametru).


E-mailové HTML

Pro rozesílání sestav/faktur e-mailem je potřeba HTML, které snesou e-mailoví klienti — inline CSS (mnozí klienti strhávají <style>), bez <script>/@media/@page, vše v jednom souboru (obrázky base64). Toho dosáhneš dvěma způsoby:

1. Property EmailMode — přepne HTML výstup Render() na e-mailovou variantu:

loBuilder.EmailMode = .T.
loBuilder.Render("faktura_email.html", "sablona.json")   && inline CSS, single-file
loBuilder.EmailMode = .F.

2. Metoda ToEmailHtml(html) — převede libovolné hotové HTML:

lcHtml = loBuilder.ToTableReportWithMetadata(lcJson)     && nebo jakékoliv HTML
lcEmail = loBuilder.ToEmailHtml(lcHtml)
Metoda / Property Návrat Popis
EmailMode bool Zapne e-mailovou konverzi pro .html výstup z Render()
ToEmailHtml(html) string Převede hotové HTML na e-mail-friendly variantu

Co konverze dělá: posbírá pravidla z <style>, inlinuje je na elementy (cascade: tag → třídy → existující inline), odstraní <script>, @media, @page, složené selektory (table.dt th) ponechá v slim <style> v <head> (webmail je ctí).

Nejlépe funguje na tabulkové sestavy (jsou <table>-based → korektní i v desktopovém Outlooku). Dokumenty s flex layoutem (faktury) se ve webmailu (Gmail, Apple Mail, web Outlook) zobrazí správně; v desktopovém Outlooku se flex zjednoduší — pro e-mail volte jednodušší šablony.


FRX konvertor

Metoda Návrat Popis
ConvertFrxToJson(frxXml) string FRX XML → JSON šablona (auto-detekce typu)
ConvertFrxToJsonFile(frxXmlPath, outputJsonPath) bool FRX soubor → JSON soubor (auto-detekce)
ConvertFrxToTableReportJson(frxXml) string FRX → JSON (vynuceně tabulka)
ConvertFrxToDocumentJson(frxXml) string FRX → JSON (vynuceně dokument)
ConvertFrxToTableReportJsonFile(frxXmlPath, outputJsonPath) bool FRX soubor → JSON soubor (vynuceně tabulka)
ConvertFrxToDocumentJsonFile(frxXmlPath, outputJsonPath) bool FRX soubor → JSON soubor (vynuceně dokument)
GenerateSampleXmlFromJson(jsonTemplate) string JSON šablona → vzorové XML
GenerateSampleXmlFromJsonWithRoot(jsonTemplate, rootName) string Vzorové XML s vlastním kořenem
GenerateFoxProCodeFromJson(jsonTemplate) string JSON šablona → FoxPro PRG kód
GenerateFoxProCodeFromJsonWithRoot(jsonTemplate, rootName) string PRG s vlastním kořenem
ConvertFrxToAllFiles(frxXmlPath, outputFolder) bool FRX → JSON + XML + PRG (auto-detekce)
ConvertFrxToTableReportAllFiles(frxXmlPath, outputFolder) bool FRX → JSON + XML + PRG (vynuceně tabulka)
ConvertFrxToDocumentAllFiles(frxXmlPath, outputFolder) bool FRX → JSON + XML + PRG (vynuceně dokument)
LastFrxCheckReport string Od 1.1.148: report validátoru (jako xsb check) nad šablonou z posledního ConvertFrx*/ConvertLbx*; prázdný = bez nálezů

Od 1.1.148 konvertor překládá „Print When" (supexpr) do visibleWhen (FrxConditionTranslator: .and./.or./.not., empty(), inlist() → IN, .t./.f., $ → LIKE, aliasy hlava.x → header.x, otiskserv.otiskobjekt.x → header.x); co nejde přeložit (m. proměnné, _pageno, recno()), zůstává jen v anotaci _printWhen. U sloupců sestavy vzniká visibleWhen pouze z hlavičkové podmínky (řádková by skryla celý sloupec). Dědičnost: existuje-li v cílové složce _base\<typ>.json, zapíše se šablona jako potomek s "extends" a jen odlišnostmi (vzorové XML a PRG z úplné šablony). | ExtractLiteralsFromJson(jsonTemplate) | string | Extrahuje přeložitelné texty jako XML | | ExtractLiteralsFromJsonFile(jsonFilePath) | string | Totéž ze souboru |

Auto-detekce typu (table/document) z FRX někdy klasifikuje špatně. Varianty s vynuceným typem (TableReport/Document v názvu) toto obcházejí.

Přímé čtení FRX/LBX souboru (bez FoxPro) — od 1.1.120

Všechna souborová API konvertoru (ConvertFrxToJsonFile, ConvertFrxToAllFiles, ConvertLbxToJsonFile, …) přijímají kromě XML exportu i rovnou cestu k .frx/.lbx souboru — mezikrok „otevři FRX ve FoxPro a exportuj CURSORTOXML" odpadá:

*-- Dřív (tiskserver, jfrx_convertfrxtojson):
*   USE report.frx ALIAS tmpReport SHARED AGAIN
*   CURSORTOXML("tmpReport", "lcXml", 3, 16) + STRCONV + STRTOFILE do temp XML
*   loBuilder.ConvertFrxToJsonFile(m.lcXmlFile, m.lcJsonFile)
*-- Teď stačí:
loBuilder.ConvertFrxToJsonFile("repo\saldo11.frx", "repo_json\frx_saldo11.json")
loBuilder.ConvertFrxToAllFiles("c:\reporty\CENIK.FRX", "c:\vystup\")   && json + sample.xml + prg

Jak to funguje:

Volba typu (od 1.1.121): štítek se konvertuje VÝHRADNĚ podle přípony .lbx (u souborového vstupu) nebo přes ConvertLbx* metody. Dřívější auto-detekce „header objcode=53 = label" byla chybná — hlavičkový záznam objtype=1/objcode=53 má každý FRX i LBX (ověřeno na 1 636 FRX + 79 LBX z MANW/repo), takže auto API konvertovalo od 3/2026 všechno včetně faktur jako štítek. U XML stringu bez přípony se auto-detekuje jen table/document.

Výjimka — obálky a štítky uložené jako .frx (1.1.131): adresa na obálku se v tabulkovém ani dokumentovém rendereru nedá vysázet správně, potřebuje absolutní pozicování. Takové reporty se proto poznají podle geometrie a jdou do label rendereru: všechny bandy kromě detailu prázdné, detail band nad 60 mm, do 12 objektů, žádné kreslené čáry. Kritérium bylo změřeno na 2 012 FRX — vybere 58 souborů a rozlišuje i uvnitř jedné rodiny názvů (AOBALDLL = obálka → štítek, AOBALDL = poštovní arch → tabulka). Nejde o návrat k chybě z 1.1.121: rozhoduje geometrie celého reportu, ne příznak v hlavičce. MLINE(pole, n) se převede na formát MLn:šířka, par.get_par("x") na {parametr.x}.

Kvalita dokumentové konverze (1.1.122–1.1.132, viz docs/navrhy/NAVRH_FRX_DOKUMENTY_2026-08.md): hlavička faktury z PageHeader/Title bandu se už nezahazuje (popiskový pruh = spodní řádkový cluster), popisky sloupců se párují překryvem x-intervalů (popisek PŘED hodnotou se správně nepáruje jako záhlaví sloupce), hranice a poměr dvousloupcového layoutu se počítají z reálných souřadnic (největší vodorovná mezera; ratio z naměřených rozsahů, ne „50:50").

Od 1.1.129 dál:

Verze Změna
1.1.129 Formulářová mřížka se bere z čar, které FRX kreslí (objtype 6/7) — hranice buněk, colspan/rowspan z chybějících úseků, výška řádku ze zdroje. Kde originál čáry nekreslí, výstup je bez rámečků.
1.1.130 Středník = konec řádku (adresa a2;a3;… už nepřichází o zbytek); popisky sloupců se hledají i v GroupHeaderu; patičky tabulkových sestav se nezahazují (sumRows s value — hlavní kniha); číselná konstanta není název pole; dvě adresy s nakresleným rámečkem → header-two-column; šířky sloupců ve znakových jednotkách, částky se stropem 12 číslic.
1.1.131 Obálky a štítky z .frx do label rendereru (viz výše).
1.1.132 Popisky bandu se dělí na hlavičkové bloky — když band nese víc záhlaví nad víceřádkovým detailem (oddíly B a C souhrnného hlášení DPH), patří i-tý blok i-tému řádku.

⚠️ Výstup je startovací bod, ne hotová šablona. Konvertor nemůže odvodit lookupy na číselníky ({osnova.nazev} u čísla účtu), nadpisy stran hlavičky („DODAVATEL"/„ODBĚRATEL" ve FRX nejsou), sloupce, které ve starém reportu chyběly, ani rozdělení rekapitulací do samostatných tabulek.

Pozn.: nejde o obecné čtení DBF dat (to zůstává v ComsysNetSupportLib — mezi knihovnami se závislost nezavádí; tady je jen minimální interní kopie čtecí logiky pro FRX/LBX).


Generování JSON šablon z cursor schema

Generování JSON šablon pro tabulkové sestavy přímo z definice FoxPro kurzoru (cursor schema). Vstupem je string se schématem tabulky a volitelné parametry — výstupem je JSON s odhadnutými šířkami sloupců v mm.

Metoda Návrat Popis
GenerateColumnsFromSchema(cursorSchema, options) string Vrátí JSON fragment s columns a printColumns
GenerateReportFromSchema(outputJsonPath, cursorSchema, options) bool Zapíše kompletní JSON report šablonu do souboru

cursorSchema: Dva podporované formáty:

options: Řetězec "key1:value1,key2:value2,..." s konfigurací:

Klíč Default Popis
dataFontPt 8 Velikost fontu datových buněk (pt)
pageSize A4 Formát papíru: A4, A3
orientation auto portrait, landscape, auto
maxDecimal 2 Max počet desetinných míst
maxLenString 20 Max šířka textových sloupců (znaky)
groups — Skupiny: stredisko;ucet (; odděluje). Prefix - = sestupné řazení skupiny (např. -datum;stredisko) — emituje "sortDesc": true. Popisek za |: rada|Řada;grp2|-*Měsíc — nahradí Proper(klíč) v label/sumLabel (s { se použije doslova); úvodní - v popisku = hideGroupFooterIfSingle, * = hideGroupHeader (jako popisek v FoxPro makerepo2)
labels — Vlastní popisky sloupců: cena_celk=Cena celkem;mnozstvi=Množství (; odděluje, dělí se na prvním =); delší popisek rozšíří sloupec
noWrap false true = textové sloupce (C, V, M) dostanou "noWrap": true (ořez místo zalomení, jako FRX bez „Stretch with overflow“)
noTotalColumns — Sloupce bez součtů: id;doklad (; odděluje)
sumExpressions — Explicitní agregace přebíjející auto-generaci. Formát: pole=FUNC;pole2=FUNC2 (např. castka=SUM;pocet=COUNT;cena=AVG). Podporované funkce: SUM, COUNT, AVG, MIN, MAX. Bez =FUNC se použije SUM.
grandTotal true Celkový souhrnný řádek (Celkem). false = neemitovat section-level sumLabel/sumExpressions, zachovat group-level.
rowNumberLabel — Vlastní popisek sloupce s čísly řádků (default #). Emituje se jen když rowNumbers ≠ false.
element data Název XML elementu se záznamy
title — Nadpis sestavy (podporuje {element.field})
tfiltr — Filtr sestavy (podporuje {element.field})
culture cs-CZ Kultura pro formátování
lang cs Jazyk popisků: cs, sk, en, de. Ovlivní default sumLabel, groupSumPrefix, pageLabel, printedLabel.
sumLabel Celkem (cs) Popisek souhrnného řádku — přebije lang.
groupSumPrefix Celkem za (cs) Prefix pro group sum row ({prefix} {groupValue}) — přebije lang.
pageLabel Strana … z … (cs) Formát pageHeader — přebije lang.
printedLabel Vytištěno: (cs) Footer text vytištění — přebije lang.
rowNumbers false Číslování řádků: false, global, group

Escape sekvence v options stringu

Options string používá : a , jako oddělovače. Pro hodnoty obsahující tyto znaky použijte zpětné lomítko:

Sekvence Význam
\, Literál čárky v hodnotě
\: Literál dvojtečky v hodnotě
\\ Literál zpětného lomítka

Příklady:

title:Přehled faktur\, Q1 2026,orientation:landscape
tfiltr:Datum\: 2026-01-01..2026-03-31
sumLabel:Celkem\, netto,lang:cs

Lokalizační defaulty

lang sumLabel groupSumPrefix pageLabel printedLabel
cs Celkem Celkem za Strana … z … Vytištěno:
sk Spolu Spolu za Strana … z … Vytlačené:
en Total Total for Page … of … Printed:
de Gesamt Summe für Seite … von … Gedruckt:

Individuální sumLabel/groupSumPrefix/pageLabel/printedLabel v options vždy přebijí default z lang.


Tisk

Jednorázový tisk

Metoda Návrat Popis
PrintWithDialog(jsonOrFile) bool Tisk s dialogem (XML z builderu)
PrintFromFilesWithDialog(jsonOrFile, xmlOrFile) bool Tisk s dialogem (externí soubory)
PrintSilent(jsonOrFile, printer, fromPage, toPage) bool Tichý tisk (XML z builderu)
PrintFromFilesSilent(jsonOrFile, xmlOrFile, printer, from, to) bool Tichý tisk (externí soubory)
PrintPdfFile(pdfPath, printerName) bool Tisk PDF přes SumatraPDF

Utility

Metoda Návrat Popis
GetAvailablePrinters() string Seznam tiskáren (oddělené \n)
GetDefaultPrinter() string Název výchozí tiskárny
GetReportPageCount(jsonOrFile) int Počet stránek sestavy (−1 = chyba)
GetPrinterCapabilities(printerName) string Schopnosti tiskárny (duplex, papír, zásobník, barva)

Batch tisk / PDF

Metoda Návrat Popis
EndBatch() int Ukončí batch (sloučí PDF / vyčistí). Vrátí počet stránek.
ResetPrint() void Resetuje tiskové properties na default

Batch se řídí přes property BatchOutput — viz sekce Properties.


Generování dokumentových šablon z XML dat

Automatické generování JSON šablon pro dokumentový renderer ("renderer": "document") z XML dat. Heuristická analýza XML struktury — detekce archetypu (faktura/dopis/protokol), klasifikace elementů, generování bloků.

Metoda Návrat Popis
GenerateDocumentFromXml(options) string Vygeneruje JSON šablonu z XML v builderu. Vrátí JSON string.
GenerateDocumentFromXmlToFile(outputJsonPath, options) bool Vygeneruje JSON šablonu z XML v builderu a uloží přímo do souboru (UTF-8).
GenerateDocumentFromXmlFile(outputJsonPath, xmlFilePath, options) bool Vygeneruje JSON šablonu z externího XML souboru a uloží do souboru (UTF-8).

options: Řetězec "key1:value1,key2:value2,..." s konfigurací (nebo "" pro výchozí):

Klíč Default Popis
type auto Archetyp: faktura, dopis, protokol, formular, dokument. Auto = heuristická detekce.
title "" Nadpis dokumentu
culture cs-CZ Kultura pro formátování (čísla, datumy)
pageMarginMm 8 Okraje stránky v mm
style "" Styl: bordered (rámeček kolem bloků)

Auto-detekce archetypu (pokud type není zadán):

Archetyp Podmínka
faktura Vlastní firma + protistrana + tabulka s celkovým součtem
dopis Vlastní firma + protistrana, bez tabulky
protokol Vlastní firma + tabulka, bez protistrany
formular Tabulka bez vlastní firmy a protistrany (bankovní formuláře, příkazy k úhradě)
dokument Fallback — bloky v pořadí elementů

Příklad:

*--- Vrátí JSON string ---
lcJson = loBuilder.GenerateDocumentFromXml("type:faktura,title:Faktura")

*--- Uloží přímo do souboru (řeší cp1250/UTF-8) ---
loBuilder.GenerateDocumentFromXmlToFile("C:\json\faktura.json", "type:faktura,title:Faktura")

*--- Z externího XML souboru ---
loBuilder.GenerateDocumentFromXmlFile("C:\json\faktura.json", "C:\data\data.xml", "")

VS Code editor

Metoda Návrat Popis
OpenReportEditor(jsonPath, xmlPath) bool Otevře VS Code s IntelliSense + live preview
OpenReportEditorWithSchemas(jsonPath, xmlPath, schemaFolder) bool Totéž s explicitní cestou ke schématům
OpenReportEditorNew(jsonPath, xmlPath, templateType) bool Pokud JSON neexistuje nebo je prázdný, vygeneruje výchozí šablonu z XML a otevře VS Code
WriteEditorGuide(jsonPath, xmlPath) bool Zapíše CLAUDE.md vedle šablony (návod pro Claude Code / AI: workflow, xsb check, dědičnost extends se základem a zděděnými klíči, struktura XML dat, reference JSON, jazyk výrazů) bez spouštění VS Code — totéž generuje OpenReportEditor. Od 1.1.147; DevCli xsb guide <json> [xml].
TemplateFallbackDir (vlastnost) string Záložní složka pro extends/$include (od 1.1.177): relativní cesta, která vedle šablony není, se hledá odsud. Nastavit jednou po vytvoření builderu: loBuilder.TemplateFallbackDir = Fullpath("repo_json") — kopie šablony v json_local pak dál dědí ze základu i sourozenců. Platí pro render, CheckTemplate, editor (CLI dostane --fallback-dir) i překlad literálů. Ambientní pro vlákno; "" vypne. ✅
ExpandTemplateToFile(sourceJsonPath, targetJsonPath) bool Zmrazená kopie šablony (od 1.1.177): zapíše zdroj s rozbaleným extends/$include (odsazeně, _info říká, že nedědí). Kopie je samostatná jako FRX v LocalRep — změny základu se nepropíší; jen na výslovné přání, standardní kopie = prosté Copy File + TemplateFallbackDir. Chyba v HtmlErrorMessage. ✅

OpenReportEditorNew — pre-fill + editor v jednom kroku:

Parametr Popis
jsonPath Cesta k JSON šabloně (nemusí existovat)
xmlPath Cesta k XML datům (pro analýzu struktury)
templateType "document" — dokumentová šablona (heuristická), "table" — minimální tabulková šablona

Pokud JSON soubor existuje a není prázdný, otevře se bez přegenerování (existující práce se nepřepisuje).

Příklad:

*--- Nový dokument (faktura) ---
loBuilder.OpenReportEditorNew("C:\json\nova_faktura.json", "C:\data\sample.xml", "document")

*--- Nová tabulková sestava ---
loBuilder.OpenReportEditorNew("C:\json\nova_sestava.json", "C:\data\sample.xml", "table")

VS Code snippety: Při otevření editoru se automaticky generuje .vscode/blocks.code-snippets s 26 snippety. Prefix doc- pro dokumentové bloky (header, info-grid, table, total, text, signature, separator, spacer, image, qr, columns, form-table, page-break), prefix rep- pro tabulkové struktury (column, column-expr, column-template, group, sum, sumrows, footer-row, lookup, row-style, header-rows, page-header, page-footer, section).


Markdown → HTML

Metoda Návrat Popis
RenderMarkdownToHtml(markdownContent, outputPath) bool Markdown string → HTML soubor
RenderMarkdownFileToHtml(markdownPath, outputPath) bool Markdown soubor → HTML soubor

Bloky ```mermaid se v HTML vykreslí jako diagramy (Mermaid runtime se injektuje jen když dokument diagram obsahuje; zdroj lze přepnout na lokální mermaid.min.js env proměnnou XSB_MERMAID_SRC — offline prostředí). Od 1.1.101, platí i pro xsb md a net48 Cli.exe --md.


Přímý export XML → JSON / CSV / XML / XLSX (bez šablony)

Třída DataExporter — statická utilita pro rychlý export XML dat do běžných formátů bez nutnosti JSON šablony. Ideální pro User Reports, kde uživatel chce data rovnou do Excelu nebo systému třetí strany.

Export z XML stringu

Metoda Návrat Popis
DataExporter.ExportToJson(outputPath, xmlString, out errorMessage) bool XML → JSON (type-aware: čísla, boolean bez uvozovek)
DataExporter.ExportToCsv(outputPath, xmlString, out errorMessage) bool XML → CSV (UTF-8 BOM, ; oddělovač, RFC 4180 escape)
DataExporter.ExportToXml(outputPath, xmlString, out errorMessage) bool XML → reformátované XML (UTF-8 deklarace, odsazení)
DataExporter.ExportToXlsx(outputPath, xmlString, out errorMessage) bool XML → XLSX (surový výpis, typované buňky — viz níže)
DataExporter.ExportToXlsx(outputPath, xmlString, options, out errorMessage, out rowCount) bool Varianta s volbami a počtem řádků

Export z XML souboru

Metoda Návrat Popis
DataExporter.ExportFileToJson(outputPath, xmlFilePath, out errorMessage) bool Načte XML soubor a exportuje do JSON
DataExporter.ExportFileToCsv(outputPath, xmlFilePath, out errorMessage) bool Načte XML soubor a exportuje do CSV
DataExporter.ExportFileToXml(outputPath, xmlFilePath, out errorMessage) bool Načte XML soubor a reformátuje do UTF-8
DataExporter.ExportFileToXlsx(outputPath, xmlFilePath, out errorMessage) bool Načte XML soubor a exportuje do XLSX
DataExporter.ExportFileToXlsx(outputPath, xmlFilePath, options, out errorMessage, out rowCount) bool Varianta s volbami a počtem řádků

Surový export do XLSX (ExportToXlsx / fasáda ExportCursorXmlToXlsx)

Náhrada za COPY TO … TYPE XL5 a exporty přes Excel COM: jeden list, první řádek = názvy sloupců (tučně, zmrazený, autofiltr), typované buňky (datum jako datum, čísla jako čísla, logické jako boolean), šířky sloupců podle obsahu. Bez JSON šablony — formátované sestavy dělá XlsxTableReportRenderer.

FoxPro fasáda (instanční, wwDotnetBridge-friendly):

Metoda Návrat Popis
loBuilder.ExportCursorXmlToXlsx(xmlOrFile, xlsxPath) int Počet datových řádků; -1 = chyba (detail v LastXlsxError)
loBuilder.ExportCursorXmlToXlsxWithOptions(xmlOrFile, xlsxPath, options) int Totéž s volbami
loBuilder.ExportDbfToXlsx(dbfPath, xlsxPath, options) int Totéž přímo z DBF (typy z hlavičky, bez XML) — velké kurzory, viz „Velké kurzory“

xmlOrFile — začíná < → XML string, jinak cesta k souboru. options — "klíč:hodnota" oddělené čárkou:

Volba Význam
sheet:Název listu název listu (ořeže se na 31 znaků; čárku v názvu nahradit mezerou)
autofilter:0 vypne autofiltr
freeze:0 vypne zmrazení hlavičky
bool:Ano;Ne logické hodnoty jako text místo nativní boolean buňky

Logické hodnoty: bez volby se zapíše nativní boolean buňka — Excel ji zobrazí jako PRAVDA/NEPRAVDA (dle jazyka Office) a filtruje ji jako logickou hodnotu. Volba bool: zapíše místo toho text ve stejné konvenci "trueText;falseText", jakou používá format sloupce v JSON šablonách (TableReportModel.ApplyBoolFormat): bool:Ano;Ne, bool:A;N, bool:x; (true = „x", false = prázdno), bool:[✓];[–]. Formát bez ; je chyba (ne tiché ignorování). Ostatní typy sloupců volba neovlivní.

Proč XML z CURSORTOXML (a ne DBF/CSV): XSB záměrně neumí číst DBF (DbfReader je v ComsysNetSupportLib — závislost mezi knihovnami se nezavádí) a CSV cestou by se ztratily datové typy (vše by byl text, nebo by se muselo hádat).

Do proměnné, nebo do souboru? Fasáda pozná obojí (xmlOrFile — začíná < → XML string, jinak cesta k souboru):

do proměnné — CURSORTOXML(alias, "lcXml", 3, 16, 0, "1") do souboru — navíc flag 512
Kód kratší, žádný temp soubor ani úklid temp soubor + ERASE
Kódování past nevzniká — wwDotnetBridge předá text jako Unicode, deklarace se u stringu ignoruje viz varování níže
Velikost limit VFP stringu ~16 MB bez limitu — pro velké kurzory

Pro běžné sestavy je proměnná lepší volba; na soubor sáhněte u opravdu velkých kurzorů.

Inline XSD schéma zapíná 6. parametr cSchemaName = "1" (ne flag — viz VFP help _5wn12pq2w). V XML je pak přesný popis sloupců: typ (xsd:date, xsd:decimal, xsd:boolean, xsd:int, xsd:string), počet desetinných míst (fractionDigits → formát buňky, např. 0.00) i pořadí sloupců kurzoru. Čte se z obou tvarů — atributového (nOutputFormat 3) i element-centrického (1). Hodnoty jsou v invariantním tvaru (ISO datum, desetinná tečka), takže nezáleží na SET POINT.

Bez schématu export funguje taky, ale typy se odhadují konzervativní heuristikou po sloupcích — sloupec je typovaný, jen když VŠECHNY neprázdné hodnoty odpovídají stejnému typu; kódy s vedoucí nulou („0123", VS, kód obce) zůstanou textem. Schéma je proto doporučené: jen s ním se do výstupu dostanou i sloupce prázdné ve všech řádcích a logická pole s hodnotami 1/0 (bez schématu je heuristika nechá číslem — příznak od čísla nelze poznat).

⚠️ Kódovací past CURSORTOXML — týká se JEN výstupu do souboru: bez encoding flagů (bity 16/32 = 0) VFP zapíše bajty v ANSI kódové stránce stroje (v ČR windows-1250), ale do deklarace dá encoding="Windows-1252" — č se pak přečte jako è, ř jako ø. Od 1.1.111 to ExportFileToXlsx řeší samo (deklarace „Windows-1252" → dekóduje ANSI stránkou stroje), přesto do souboru vždy přidávejte +48 (UTF-8 s překladem) nebo +16 (deklarovaná stránka kurzoru), ať je soubor korektní i pro jiné konzumenty.

*-- Běžný případ: přes proměnnou (konvence tiskserveru — atributové XML + inline schéma)
LOCAL lcXml, lnRows
lcXml = ""
CURSORTOXML(Alias(), "lcXml", 3, 16, 0, "1")
lnRows = loBuilder.ExportCursorXmlToXlsxWithOptions(m.lcXml, "C:\export\prehled.xlsx", "bool:Ano;Ne")
IF m.lnRows < 0
    ? loBuilder.LastXlsxError
ENDIF

*-- Velký kurzor: přes soubor (bez 16MB limitu stringu)
LOCAL lcTmp
lcTmp = Addbs(Sys(2023)) + Sys(2015) + ".xml"
CURSORTOXML(Alias(), m.lcTmp, 3, 512 + 48, 0, "1")
lnRows = loBuilder.ExportCursorXmlToXlsx(m.lcTmp, "C:\export\prehled.xlsx")
ERASE (m.lcTmp)

Poznámky: NULL (vynechaný element) → prázdná buňka; formát čísel dle fractionDigits bez tisícového oddělovače (roky a kódy se nezobrazí jako „2 026"); datum dd.mm.yyyy; šířky sloupců se měří z prvních 1000 řádků, strop 60 znaků; název listu se ořeže na 31 znaků.

Chování

Příklad

string err;
bool ok = DataExporter.ExportToCsv(@"C:\export\faktury.csv", xmlString, out err);
if (!ok) MessageBox.Show(err);
*-- Z FoxPro přes wwDotnetBridge
LOCAL lcErr
lcErr = ""
llOk = loBridge.InvokeStaticMethod("XmlStackBuilder.Core.DataExporter", "ExportFileToCsv", ;
    "C:\export\faktury.csv", "C:\data\faktury.xml", @lcErr)

Poznámky