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)
- AI nástroj (Claude Code / GPT) + Live Preview ve VS Code nahradila ruční editaci JSON šablon. Detaily a praktické příklady v
AI_WORKFLOW.md.
| 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 ";") |
| 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) |
| 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().
| 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 |
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:
<row …/> jsou shodné s CURSORTOXML(alias, …, 3, 16) — názvy polí malými písmeny, čísla jak leží
v souboru (3048.02), datum yyyy-MM-dd, prázdné datum "", logické true/false, NULL = atribut chybí;LastDbfError, do dokumentu se nic nevloží.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).
| 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 |
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:
parentPath — lomítková cesta k rodiči (case-insensitive, ignoruje namespace), např. "DPPDP9"
nebo "Pisemnost/DPPDP9". Prázdné = root. První segment může (ale nemusí) být jméno rootu.rowsXml — libovolně pojmenované řádky (typicky <row> z CURSORTOXML, vč. <?xml?> deklarace
a <VFPData> wrapperu — obojí se automaticky strhne). Každý řádek se přejmenuje na elementName
a zkopírují se jeho atributy i child obsah. Namespace se převezme od existujících sourozenců, jinak od rodiče.RoundTripSchemaPath: nové elementy se vloží na správné místo dle XSD sekvence (i když dosud
v dokumentu nebyly). Bez schématu: ReplaceCollection vloží na pozici původních elementů, jinak na konec.XmlRoundTrip (ResolveParent, GetChildOrderFromXsd, ReplaceCollection,
AppendCollection, RemoveCollection) je k dispozici i bez instance builderu (pracuje nad XElement).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");
Č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).
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.
| 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 |
| 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) |
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 |
| 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 |
| 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) |
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.OpenXmlna .NET Frameworku používáSystem.IO.Packagingz 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:
- relativní relationship targety místo absolutních
/word/...(Word absolutní cesty repairuje),- standardní
[Content_Types].xml(Default xml=application/xml+Overridepro/word/document.xml), zapsané jako první entry v ZIP,- obrázky ve
word/media/s odpovídajícím content-typem (JPG/PNG dle obsahu),- strukturně validní tabulky: každá buňka končí odstavcem, dvě sousední tabulky odděluje odstavec, tělo nekončí tabulkou,
settings.xmlscompatibilityMode=15(žádný „režim kompatibility").Tyto problémy
OpenXmlValidatornehlásí (kontroluje jen schéma, ne fyzické URI/umístění/strukturu).
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
FoxPro přes wwDotnetBridge přes COM nezvládá:
out / ref parametry — COM je předává nespolehlivěStream, IDataReader — FoxPro nemá protějšek, nelze předatIDictionaryTranslator) — FoxPro je neimplementujeProto má XSB dvě varianty kde to dává smysl:
RenderWithDictionary(Hashtable), ValidateAndRender (warning v property)RenderWithTranslator(IDictionaryTranslator), ValidateAndRenderWithWarnings(out warnings), RenderToStream(Stream)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"
| 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 |
| 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 |
| 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? |
| 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) |
| Metoda | Návrat | Popis |
|---|---|---|
SaveTableReportToXlsx(xlsxPath, jsonMetadata) |
bool | Sestava → Excel (JSON string) |
SaveTableReportToXlsxFromFile(xlsxPath, jsonFilePath) |
bool | Sestava → Excel (JSON ze souboru) |
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í:
outputPath — originál zůstává nedotčený.startRow dolů se vyčistí (obsah, formátování zůstává).YYYY-MM-DD) → datum, jinak text; kódy s vedoucí nulou zůstanou textem.<rows>/<row> i přímý CURSORTOXML() výstup (řádky pojmenované dle aliasu kurzoru).* 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žijCreateRoot("...")nebo konstruktorCreateInstance("...XmlStackBuilder", "root"). SamotnýPushroot nezakládá.
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).
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.
| 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í.
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:
< = XML export jako dřív,
cokoli jiného = VFP tabulka) — stará XML cesta funguje beze změny.FrxNativeReader) — před čtením se frx+frt zkopírují do tempu
a čte se kopie (FileShare.ReadWrite), takže nevadí, že soubor drží běžící FoxPro
nebo otevřený report designer. FRT/LBT musí ležet vedle tabulky.SET DELETED ON — přímé čtení je tedy o chlup věrnější.FrxConverter.ReadFrxFileToXml(frxPath) (.NET) —
vrátí atributové XML ve tvaru CURSORTOXML(…, 3, …).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 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:
"CREATE TABLE U (Den D, Rada C(2), Castka N(15,2))""Den D,Rada C(2),Castka N(15,2)"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 |
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
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.
| 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 |
| 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) |
| 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.
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", "")
| 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).
| 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.
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.
| 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ů |
| 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ů |
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 toExportFileToXlsxř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ů.
true/false se emitují bez uvozovek. Ostatní jako JSON string s escapováním.;, ", \r nebo \n; vnitřní " se zdvojí). UTF-8 BOM pro správné rozpoznání diakritiky v Excelu." " odsazením.bool a chybu přes out string errorMessage (prázdný string při úspěchu).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)
bool. Při false viz HtmlErrorMessage.jsonOrFile — začíná { → JSON string, jinak cesta k souboru.xmlOrFile — začíná < → XML string, jinak cesta k souboru.