Tento návod je určen pro úpravu JSON šablon obchodních dokumentů (faktury, dodací listy, objednávky, nabídky) ve VS Code s live preview.
Obsah:
┌───────────────────────────────────────────────────────────┐
│ XML data + JSON šablona → HTML / PDF │
│ (z aplikace) (vaše úpravy) (výstup) │
└───────────────────────────────────────────────────────────┘
XML data — připraví aplikace. Obsahují data dokumentu: dodavatel, odběratel, položky, ceny.
JSON šablona — tu upravujete vy. Říká rendereru, jak má dokument vypadat: jaké bloky, v jakém pořadí, s jakými daty.
Výstup — HTML (náhled), PDF (tisk/email).
Editaci spustíte z aplikace. Otevře se VS Code s JSON souborem a v prohlížeči se zobrazí HTML náhled.
Pozor: JSON soubor musí být validní. Nejčastější chyba: čárka za poslední položkou v
{}nebo[]. VS Code chybu červeně podtrhne.
Na rozdíl od tabulkové sestavy (kde je jedna velká tabulka), dokument se skládá z bloků, které se řadí shora dolů. Každý blok má svůj typ a vlastnosti.
{
"renderer": "document", ← typ šablony (volitelné, pro jednoznačnou identifikaci)
"aliases": { ... }, ← zkratky pro dlouhé XML cesty (volitelné)
"document": { ... }, ← nastavení dokumentu
"pageHeader": { ... }, ← záhlaví stránky (opakuje se)
"pageFooter": { ... }, ← zápatí stránky (opakuje se)
"blocks": [ ← pole bloků — v tomto pořadí se vykreslí
{ "type": "header-two-column", ... },
{ "type": "info-grid", ... },
{ "type": "table", ... },
{ "type": "total-amount", ... },
{ "type": "signature", ... }
]
}
document){
"document": {
"title": "FAKTURA – daňový doklad",
"culture": "cs-CZ",
"orientation": "portrait",
"pageSize": "A4",
"pageMarginMm": 8,
"overflow": "auto"
}
}
| Vlastnost | Co dělá | Příklad |
|---|---|---|
renderer |
Typ šablony (volitelné — bez něj se typ pozná z obsahu JSON) | "document" |
title |
Název dokumentu (podporuje {element.field} placeholdery) |
"FAKTURA – daňový doklad", "Inventura účtu {ucty.ucet}" |
culture |
Formát čísel/datumů | "cs-CZ" |
orientation |
Orientace | "portrait" (výška), "landscape" (šířka) |
pageSize |
Velikost papíru | "A4", "A3", "Letter" |
pageMarginMm |
Okraje stránky v mm | 8 |
overflow |
Jak řešit dlouhý dokument | viz níže |
fontSizePt |
Základní velikost písma v pt (vše se škáluje) | 9 (výchozí), 8, 10 |
fontFamily |
Název písma dokumentu | "Segoe UI" (výchozí), "Arial", "Calibri" |
attachmentTitle |
Titulek přílohy (attachment mode). "" = potlačit |
"PŘÍLOHA k faktuře {header.faktura}" |
attachmentRef |
Text „viz příloha" na straně 1. "" = potlačit |
"Rozpis položek viz příloha" |
repeatElement |
Opakování dokumentu pro kolekci (viz sekce 19) | "upominky" |
pageBreakBetween |
Page-break mezi opakovanými dokumenty | true (výchozí) |
resetPageNumbers |
Resetovat číslování stránek pro každý opakovaný dokument | false (výchozí) |
overflow)| Režim | Kdy použít |
|---|---|
"flow" |
Vše na jedné stránce (krátký dokument) |
"auto" |
Doporučeno — automaticky rozhodne: krátký → flow, dlouhý → attachment |
"continue" |
Stránkování s opakujícím se záhlavím/zápatím |
"attachment" |
Strana 1 = hlavička + "viz příloha", strany 2+ = tabulka položek |
"paged" |
Plnohodnotné stránkování řádek po řádku — pro výkazy jako rozvaha, kde tabulky přesahují stránku |
Tip: Pro faktury použijte
"auto"— krátké faktury se vejdou na 1 stránku, dlouhé se automaticky roztáhnou do přílohy.
Rozvaha a podobné výkazy: Použijte
"paged"— každá tabulka se automaticky stránkuje řádek po řádku, záhlaví tabulky se opakuje na každé stránce.
paged mode{
"renderer": "document",
"document": {
"title": "{header.title}",
"culture": "cs-CZ",
"pageMarginMm": 8,
"overflow": "paged",
"fontSizePt": 8
},
"pageHeader": {
"left": "{header.title}",
"right": "Strana {page}",
"heightMm": 8,
"fromPage": 2
},
"blocks": [
{
"type": "table",
"element": "data",
"where": "lk1=A",
"headerRows": [
[
{ "text": "Označ.", "rowspan": 2, "align": "center" },
{ "text": "A K T I V A", "rowspan": 2 },
{ "text": "Číslo\nřádku", "rowspan": 2, "align": "center" },
{ "text": "Běžné účetní období", "colspan": 3, "align": "center" },
{ "text": "Minulé úč.\nobdobí", "rowspan": 2, "align": "center" }
],
[
{ "text": "Brutto", "align": "center" },
{ "text": "Korekce", "align": "center" },
{ "text": "Netto", "align": "center" }
]
],
"columns": {
"klic_tisk": { "label": "k", "width": "13mm" },
"nazev": { "label": "Název", "width": "60mm", "maxWidth": "60mm" },
"radek": { "label": "ř.", "align": "center", "format": "N0", "suppressRepeat": true, "width": "10mm" },
"brutto": { "label": "Brutto", "align": "right", "format": "{prnobj.format}", "hideZero": true, "width": "25mm" },
"korekce": { "label": "Korekce", "align": "right", "format": "{prnobj.format}", "hideZero": true, "width": "25mm" },
"netto": { "label": "Netto", "align": "right", "format": "{prnobj.format}", "hideZero": true, "width": "25mm" },
"loni": { "label": "Loni", "align": "right", "format": "{prnobj.format}", "hideZero": true, "width": "25mm" }
}
},
{
"type": "table",
"element": "data",
"where": "lk1=P",
"pageBreakBefore": true,
"columns": {
"klic_tisk": { "label": "k", "width": "13mm" },
"nazev": { "label": "Název", "width": "80mm", "maxWidth": "100mm" },
"radek": { "label": "ř.", "align": "center", "suppressRepeat": true, "width": "10mm" },
"netto": { "label": "Netto", "align": "right", "format": "{prnobj.format}", "hideZero": true, "width": "35mm" },
"loni": { "label": "Loni", "align": "right", "format": "{prnobj.format}", "hideZero": true, "width": "35mm" }
}
}
]
}
Klíčové prvky rozvahy:
"overflow": "paged" — stránkování řádek po řádku"where": "lk1=A" / "where": "lk1=P" — filtrování aktivních/pasivních řádků ze sdíleného elementu data"format": "{prnobj.format}" — dynamický formát čísla (N0/N2) z XML atributu prnobj.format"suppressRepeat": true na sloupci radek — čísla řádků se zobrazí jen při změně"maxWidth": "60mm" — zalamování dlouhých názvů"pageBreakBefore": true na druhé tabulce — pasiva vždy začínají na nové stráncepageHeader / pageFooter)Opakuje se na každé stránce (v režimech continue, auto/attachment):
{
"pageHeader": {
"left": "EFES spol. s r.o.",
"center": "",
"right": "Strana {page} z {pages}",
"fromPage": 2
},
"pageFooter": {
"center": "Vytištěno: {date}"
}
}
| Placeholder | Co zobrazí |
|---|---|
{page} |
Číslo stránky |
{pages} |
Celkový počet stránek |
{title} |
Název dokumentu |
{date} |
Aktuální datum (dd.MM.yyyy) |
{datetime} |
Aktuální datum a čas (dd.MM.yyyy HH:mm:ss) |
fromPage: 2 — záhlaví se zobrazí až od 2. stránky (1. stránka má vlastní hlavičku).
| Typ | K čemu slouží | Typické použití |
|---|---|---|
header-two-column |
Dvě adresy vedle sebe | Dodavatel + odběratel |
info-grid |
Tabulka klíč-hodnota | Číslo FV, VS, datumy |
table |
Datová tabulka s řádky | Položky faktury |
form-table |
Formulářová tabulka s pevnými řádky | Daňová přiznání (DPH) |
total-amount |
Celková částka | "Celkem k úhradě: 75 020 Kč" |
text-block |
Volný text | Poznámky, zápis v OR |
signature |
Podpisy | Vystavil / Převzal |
separator |
Vodorovná čára | Oddělení sekcí |
spacer |
Prázdný prostor | Vertikální mezera |
image |
Obrázek | Logo, fotografie |
qr-code |
QR kód | QR platba |
barcode |
Čárový kód | EAN produktu |
columns |
Bloky vedle sebe | QR kód vedle tabulky |
header-two-column — dodavatel a odběratel{
"type": "header-two-column",
"ratio": "50:50",
"left": {
"title": "DODAVATEL",
"element": "dodavatel",
"logo": { "file": "logo.jpg", "maxWidthMm": 30, "position": "left" },
"fields": [
{ "field": "nazev", "style": "title" },
{ "field": "ulice" },
{ "template": "{psc} {mesto}" },
{ "separator": true },
{ "label": "IČO", "field": "ico" },
{ "label": "DIČ", "field": "dic" }
]
},
"right": {
"title": "ODBĚRATEL",
"element": "odberatel",
"bordered": true,
"fields": [
{ "field": "nazev", "style": "title" },
{ "field": "ulice" },
{ "template": "{psc} {mesto}" },
{ "separator": true },
{ "label": "IČO", "field": "ico" },
{ "label": "DIČ", "field": "dic", "visibleWhen": "odberatel.dic" }
]
}
}
┌─────────────────────────┬───────────────────────────┐
│ DODAVATEL │ ┌─ODBĚRATEL─────────────┐ │
│ [logo] EFES spol. s r.o.│ │ BAKPA INVEST s.r.o. │ │
│ Neklanova 18 │ │ Komoranská 2428/17 │ │
│ 128 00 Praha 2 │ │ 143 00 Praha 4 │ │
│ ────────────────────── │ │ ──────────────────── │ │
│ IČO: 13150529 │ │ IČO: 07240244 │ │
│ DIČ: CZ6209260915 │ │ │ │
│ │ └───────────────────────┘ │
└─────────────────────────┴───────────────────────────┘
| Vlastnost | Co dělá | Příklad |
|---|---|---|
title |
Nadpis nad adresou | "DODAVATEL" |
element |
XML element s daty (podporuje tečkovou notaci: "faktura.dodavatel") |
"dodavatel" |
bordered |
Rámeček kolem | true |
logo |
Logo v hlavičce | viz níže |
fields |
Pole s údaji | viz níže |
{ "field": "nazev", "style": "title" } ← hodnota z XML, tučně
{ "field": "ulice" } ← hodnota z XML
{ "label": "IČO", "field": "ico" } ← popisek + hodnota
{ "template": "{psc} {mesto}" } ← šablona z více polí
{ "separator": true } ← oddělovací čára
{ "type": "spacer", "heightMm": 5 } ← prázdný prostor
Tip: Pokud je XML hodnota prázdná, řádek se automaticky skryje (včetně popisku). Pokud chcete zobrazit i prázdný řádek, použijte
templatemístofield.
| Vlastnost | Co dělá |
|---|---|
field |
Název XML atributu |
label |
Popisek před hodnotou |
template |
Šablona: "{psc} {mesto}" |
style |
"title", "bold", "italic", "bold-italic", "small" + suffix -right/-center pro zarovnání (např. "title-right", "bold-center") |
format |
Formát: "dd.MM.yyyy", "N2" |
separator |
Oddělovací čára (alternativně { "type": "separator" }) |
type |
"spacer" = prázdný prostor, "separator" = oddělovací čára |
heightMm |
Výška spaceru v mm (výchozí 5) |
visibleWhen |
Podmíněná viditelnost |
{
"logo": {
"file": "C:\\data\\logo.jpg",
"maxWidthMm": 30,
"position": "left"
}
}
| Vlastnost | Co dělá |
|---|---|
file |
Cesta k souboru |
maxWidthMm |
Max. šířka v mm |
maxHeightMm |
Max. výška v mm |
position |
"top" (logo nad textem), "left" (logo vedle textu) |
info-grid — mřížka klíč-hodnota{
"type": "info-grid",
"element": "doklad",
"columns": 2,
"labelWidth": "40%",
"borderless": true,
"items": [
{ "label": "Číslo faktury", "field": "cislo", "style": "title" },
{ "label": "Variabilní symbol", "field": "vs" },
{ "separator": true },
{ "label": "Způsob úhrady", "template": "Příkazem k úhradě" },
{ "label": "Den splatnosti", "field": "splatnost", "format": "dd.MM.yyyy", "style": "bold" },
{ "label": "Den vystavení", "field": "vystaveni", "format": "dd.MM.yyyy" }
]
}
┌──────────────────────────────────────────────────────────┐
│ Číslo faktury: FV2600244 Variabilní symbol: 2600244 │
│ ──────────────────────────────────────────────────────── │
│ Způsob úhrady: Příkazem Den splatnosti: 16.02.2026 │
│ Den vystavení: 02.02.2026 │
└──────────────────────────────────────────────────────────┘
| Vlastnost | Co dělá | Příklad |
|---|---|---|
element |
XML element s daty | "doklad" |
columns |
Počet sloupců (1–3) | 2 |
labelWidth |
Šířka popisku | "40%" |
borderless |
Bez horní/dolní čáry | true |
| Vlastnost | Co dělá |
|---|---|
label |
Popisek |
field |
XML atribut |
template |
Statický text nebo {field} šablona (vždy viditelný) |
format |
Formát: "dd.MM.yyyy", "N2" |
style |
"title", "bold", "italic", "bold-italic", "small", "muted" + suffix -right/-center (např. "title-right") |
separator |
Oddělovací čára |
visibleWhen |
Podmíněná viditelnost |
heightMm |
Minimální výška value boxu v mm (pro form styl) |
XML data:
<doklad cislo="FV2600244" vs="2600244" splatnost="2026-02-16" />
JSON definice:
{
"type": "info-grid", "element": "doklad", "columns": 2,
"items": [
{ "label": "Číslo faktury", "field": "cislo", "style": "title" },
{ "label": "VS", "field": "vs" },
{ "label": "Splatnost", "field": "splatnost", "format": "dd.MM.yyyy", "style": "bold" }
]
}
Výstup:
| Číslo faktury: FV2600244 | VS: 2600244 |
|---|---|
| Splatnost: 16.02.2026 |
fieldStyle: "form")Pro úřední formuláře (daňová přiznání apod.) kde potřebujete popisek nahoře a orámovaný textbox pod ním:
{
"type": "info-grid",
"element": "hlavicka",
"columns": 2,
"fieldStyle": "form",
"items": [
{ "label": "Finančnímu úřadu pro", "field": "nazev_fu" },
{ "label": "DIČ", "field": "dic", "style": "bold" }
]
}
Finančnímu úřadu pro DIČ
┌──────────────────┐ ┌──────────────────┐
│ hlavní město │ │ CZ41189710 │
└──────────────────┘ └──────────────────┘
Klíčové vlastnosti:
fieldStyle": "form" — zapne formulářový režimheightMm na položce nastaví minimální výšku rámečku (např. "heightMm": 25 pro razítkový prostor)form-inline — popisek vlevo, textbox vpravo{
"type": "info-grid",
"element": "hlavicka",
"fieldStyle": "form-inline",
"columns": 3,
"items": [
{ "label": "řádné", "field": "cb_radne", "style": "bold", "width": "10mm" },
{ "label": "dodatečné", "field": "cb_dodatecne", "width": "10mm" },
{ "label": "opravné", "field": "cb_opravne", "width": "10mm" }
]
}
řádné ┌──┐ dodatečné ┌──┐ opravné ┌──┐
│ X│ │ │ │ │
└──┘ └──┘ └──┘
Na rozdíl od "form" (label nahoře, box dole), "form-inline" umístí popisek vlevo a orámovaný textbox vpravo na jednom řádku. Typické pro formuláře typu DPH přiznání.
| Vlastnost | Co dělá | Příklad |
|---|---|---|
width na položce |
Fixní šířka textboxu | "10mm", "22mm" |
align: "right" na položce |
Textbox zarovnaný k pravému okraji | (label vlevo, box úplně vpravo) |
compact){
"type": "info-grid",
"element": "hlavicka",
"compact": true,
"items": [ ... ]
}
Vlastnost compact: true zmenší padding a řádkování v info-gridu. Užitečné pro formuláře s mnoha řádky.
table — tabulka s položkami{
"type": "table",
"element": "polozky",
"primary": true,
"showRowNumbers": true,
"columns": {
"nazev": { "label": "Název", "align": "left" },
"pocet": { "label": "Množství", "align": "right", "format": "N2", "width": "60px" },
"mj": { "label": "MJ", "align": "center", "width": "30px" },
"jc": { "label": "Cena/ks", "align": "right", "format": "N2", "width": "80px" },
"cena": { "label": "Celkem", "align": "right", "format": "N2", "width": "90px" }
},
"sumExpressions": [
{ "field": "cena", "expr": "SUM(cena)", "format": "N2" }
],
"sumLabel": "Celkem"
}
┌────┬──────────────────────┬──────────┬─────┬──────────┬───────────┐
│ # │ Název │ Množství │ MJ │ Cena/ks │ Celkem │
├────┼──────────────────────┼──────────┼─────┼──────────┼───────────┤
│ 1 │ Služby VT │ 40,00 │ h │ 1 815,00 │ 72 600,00 │
│ 2 │ Správa serveru │ 1,00 │ ks │ 2 420,00 │ 2 420,00 │
├────┼──────────────────────┼──────────┼─────┼──────────┼───────────┤
│ │ Celkem │ │ │ │ 75 020,00 │
└────┴──────────────────────┴──────────┴─────┴──────────┴───────────┘
| Vlastnost | Co dělá | Příklad |
|---|---|---|
element |
XML element s <row> potomky |
"polozky" |
where |
Filtr řádků ze sdíleného elementu: "lk1=A", "stav!=Z", "pole" (neprázdné) |
"lk1=A" |
primary |
Primární tabulka (pro attachment mode) | true |
showRowNumbers |
Sloupec s číslem řádku (#) | true |
compact |
Menší písmo a padding | true |
hideZero |
Skrýt nulové hodnoty | true |
columns |
Definice sloupců | viz níže |
sumExpressions |
Součty | viz tabulkový návod |
sumLabel |
Popisek součtu | "Celkem" |
filterBy |
Filtrování řádků podle repeat prvku (viz sekce 19) | ["organizace"] |
headerRows |
Víceřádkové záhlaví tabulky s colspan/rowspan. Nahradí automatické záhlaví z columns.label. |
viz níže |
detailBorders |
Styl čar mezi datovými řádky: "all", "h-dashed", "none", "vertical", ... (viz sekce 23) |
"h-dashed" |
groups |
Skupiny v tabulce — záhlaví skupiny, sum řádky skupiny, grand total (viz sekce 23) | viz níže |
Pokud tabulka potřebuje složitější záhlaví (např. rozvaha se sloučenými buňkami), použijte headerRows. Každý prvek pole = jeden řádek záhlaví, každý řádek = pole buněk.
{
"type": "table",
"element": "aktiva",
"headerRows": [
[
{ "text": "Označ.", "rowspan": 2 },
{ "text": "A K T I V A", "rowspan": 2 },
{ "text": "Číslo\nřádku", "rowspan": 2 },
{ "text": "Běžné účetní období", "colspan": 3, "align": "center" },
{ "text": "Minulé úč.\nobdobí", "rowspan": 2, "align": "center" }
],
[
{ "text": "Brutto\n1", "align": "center" },
{ "text": "Korekce\n2", "align": "center" },
{ "text": "Netto\n3", "align": "center" }
]
],
"columns": { ... }
}
Vlastnosti buňky záhlaví:
| Vlastnost | Výchozí | Popis |
|---|---|---|
text |
"" |
Text buňky (\n pro nový řádek) |
colspan |
1 |
Sloučení sloupců doprava |
rowspan |
1 |
Sloučení řádků dolů |
align |
z columns |
Zarovnání: "left", "center", "right" |
style |
"bold" |
Styl: "bold", "normal" |
background |
výchozí | CSS barva pozadí |
Tip: Pokud
headerRowschybí, záhlaví se generuje automaticky zcolumns[].label(jednořádkové) — zpětná kompatibilita.
Sloupce dokumentové tabulky mají stejné vlastnosti jako v tabulkové sestavě: label, align, format, width, maxWidth, hide, hideZero, suppressRepeat, expr, round, running, template, visibleWhen.
| Vlastnost | Popis |
|---|---|
suppressRepeat |
Potlačit opakované hodnoty — zobrazí se jen při změně (jako FoxPro suppressRepeat). Typicky na sloupci číslo řádku. |
maxWidth |
Max šířka s word-wrapem (např. "60mm"). Text se zalomí na více řádků. |
format |
Může být dynamický: "{prnobj.format}" — hodnota se vezme z XML atributu před renderováním. |
XML data:
<polozky>
<row nazev="Služby VT" pocet="40" mj="h" jc="1815" cena="72600" />
<row nazev="Správa serveru" pocet="1" mj="ks" jc="2420" cena="2420" />
</polozky>
JSON definice:
"columns": {
"nazev": { "label": "Název" },
"pocet": { "label": "Mn.", "align": "right", "format": "N2" },
"jc": { "label": "Cena/ks", "align": "right", "format": "N2" },
"cena": { "label": "Celkem", "align": "right", "format": "N2" }
}
Výstup:
| Název | Mn. | Cena/ks | Celkem |
|---|---|---|---|
| Služby VT | 40,00 | 1 815,00 | 72 600,00 |
| Správa serveru | 1,00 | 2 420,00 | 2 420,00 |
{
"subFields": [
{ "field": "ean", "label": "EAN" },
{ "field": "sarze", "label": "Šarže" },
{ "field": "poznamka" }
]
}
│ 1 │ Služby VT │ 40,00 │ h │ 72 600,00 │
│ │ EAN: 8594001234567 | Šarže: L2026-01 │
SubFields se zobrazí na druhém řádku pod hlavním. Pokud jsou všechny prázdné, řádek se nevykreslí.
| Vlastnost | Co dělá |
|---|---|
field |
XML atribut |
label |
Popisek (volitelný) |
format |
Formát hodnoty |
visibleWhen |
Podmíněná viditelnost |
SubFields podporují Markdown s prefixem ^ (viz blok text-block).
Sloupec tabulky může přistupovat k hodnotám z jiného XML elementu:
{
"columns": {
"cizi": { "label": "Cena {header.mena}", "format": "N2" },
"prepocet": { "label": "Cena Kč", "expr": "cizi * header.kurz", "format": "N2" },
"s_menou": { "label": "Celkem", "template": "{cena:N2} {header.mena}" }
}
}
header.mena — hodnota atributu mena z XML elementu <header>expr, template i labelTečková notace funguje i v dalších blocích — viz sekci 17.
form-table — formulářová tabulkaBlok form-table slouží pro tisk formulářů s pevně danými řádky — typicky daňová přiznání (DPH, silniční daň apod.). Na rozdíl od bloku table, kde řádky pocházejí z XML dat, zde jsou řádky definované přímo v JSON a data se doplňují z XML přes klíč (keyField).
┌────────────────────────────────────────────────────────────────┐
│ I. Zdanitelná plnění │
├──────────────────────────────────────┬────┬──────────┬─────────┤
│ Dodání zboží (§13, §14) základní │ 1 │ 1 752 218│ 367 966│
│ snížená │ 2 │72 591 721│8 711 007│
│ Pořízení z JČS (§16) základní │ 3 │ 0│ 0│
│ snížená │ 4 │49 637 566│5 956 508│
└──────────────────────────────────────┴────┴──────────┴─────────┘
{
"type": "form-table",
"element": "dph",
"keyField": "r1",
"sections": [
{
"title": "I. Zdanitelná plnění",
"columns": {
"popis": { "width": "53%" },
"sazba": { "width": "8%", "fontSize": 7, "align": "center" },
"radek": { "label": "ř.", "width": "4%", "align": "center" },
"s2": { "label": "Základ daně", "width": "17%", "align": "right", "format": "N0" },
"s3": { "label": "Daň na výstupu", "width": "18%", "align": "right", "format": "N0" }
},
"rows": [
{
"popis": { "value": "Dodání zboží (§13, §14)", "rowspan": 2 },
"sazba": "základní", "radek": "1", "_key": "001"
},
{ "sazba": "snížená", "radek": "2", "_key": "002" }
]
}
]
}
| Vlastnost | Co dělá | Příklad |
|---|---|---|
element |
XML element s daty | "dph" |
keyField |
Atribut v XML pro párování řádků | "r1" |
sections |
Pole sekcí tabulky | viz níže |
fontSize |
Velikost písma celé tabulky (pt) | 8 |
Každá sekce má vlastní nadpis, sloupce a řádky:
| Vlastnost | Co dělá | Příklad |
|---|---|---|
title |
Nadpis sekce (šedé pozadí) | "I. Zdanitelná plnění" |
columns |
Definice sloupců sekce | viz níže |
rows |
Pole řádků s daty | viz níže |
showHeader |
Zobrazit záhlaví sloupců (true/false) |
false — skryje záhlaví |
Sloupce se definují jako objekt — klíč = název, hodnota = vlastnosti:
| Vlastnost | Co dělá | Příklad |
|---|---|---|
label |
Záhlaví sloupce | "Základ daně" |
width |
Šířka (% nebo px) |
"17%" |
align |
Zarovnání (left/center/right) |
"right" |
format |
Formát čísla | "N0" = celá čísla, "N2" = 2 des. místa |
fontSize |
Velikost písma sloupce (pt) | 7 |
Každý řádek je objekt. Klíče odpovídají sloupcům. Speciální klíče začínají _:
| Vlastnost | Co dělá | Příklad |
|---|---|---|
_key |
Klíč pro párování s XML | "001" → hledá <row r1="001" .../> |
_bold |
Tučný řádek | true |
_fontSize |
Velikost písma řádku (pt) | 9 |
_noBorder |
Bez dolního okraje | true |
Hodnota buňky může být:
Prostý text/číslo — hodnota z JSON nebo doplněná z XML:
{ "sazba": "základní", "radek": "1", "_key": "001" }
Objekt s vlastnostmi — pro rowspan, colspan, formát, zarovnání:
{
"popis": { "value": "Dodání zboží (§13, §14)", "rowspan": 2 },
"sazba": "základní"
}
| Vlastnost buňky | Co dělá | Příklad |
|---|---|---|
value |
Text buňky | "Dodání zboží" |
rowspan |
Sloučení řádků dolů | 2 |
colspan |
Sloučení sloupců doprava | 3 |
format |
Přepíše formát sloupce | "N2" (koeficient v jinak N0 sloupci) |
align |
Přepíše zarovnání sloupce | "center" |
template |
Šablona s {field} placeholdery |
"{s2:N2} %" |
"_key": "001"keyField hodnotou "001":
<dph>
<row r1="001" s2="1752218" s3="367966"/>
</dph>
s2, s3) se doplní z nalezeného XML řádkupopis, sazba, radek) zůstanou z JSONPozor: Hodnoty
_keyv JSON musí přesně odpovídat hodnotámkeyFieldv XML. Pokud se data nezobrazují, zkontrolujte, že se klíče shodují (včetně mezer a formátu čísla).
Různé sekce mohou mít různé sloupce (např. sekce I má 5 sloupců, sekce II jen 3):
{
"title": "II. Ostatní plnění",
"columns": {
"popis": { "width": "74%" },
"radek": { "label": "ř.", "width": "4%", "align": "center" },
"s3": { "label": "Hodnota", "width": "22%", "align": "right", "format": "N0" }
},
"rows": [
{ "popis": "Dodání zboží do JČS (§64)", "radek": "20", "_key": "020" },
{ "popis": "Vývoz zboží (§66)", "radek": "22", "_key": "022" }
]
}
Některé sekce nepotřebují opakovat záhlaví sloupců — použijte "showHeader": false:
{
"title": "V. Krácení nároku na odpočet daně",
"showHeader": false,
"columns": { ... },
"rows": [ ... ]
}
total-amount — celková částka{
"type": "total-amount",
"element": "doklad",
"field": "celkem_s_dph",
"label": "Celkem k úhradě",
"format": "N2",
"suffix": "Kč"
}
Celkem k úhradě .............. 75 020,00 Kč
| Vlastnost | Co dělá | Příklad |
|---|---|---|
element |
XML element | "doklad" |
field |
Pole s částkou | "celkem_s_dph" |
label |
Popisek vlevo, podporuje {element.field} a {date} |
"Celkem k {doklad.ke_dni}:" |
format |
Formát čísla | "N2" |
suffix |
Text za částkou, podporuje {field} a {element.field} |
"Kč" nebo "{mena}" |
style |
"large" pro větší písmo |
text-block — volný text{
"type": "text-block",
"lines": [
"Fakturujeme Vám za dodané služby.",
"Ceny jsou zaokrouhleny na celé Kč."
]
}
{
"type": "text-block",
"element": "header",
"field": "text_pod_r"
}
Label se překládá přes dictionary a zobrazí se jen pokud je pole neprázdné:
{
"type": "text-block",
"element": "header",
"field": "zpracoval",
"label": "Vyřizuje"
}
Výstup: „Vyřizuje: Marianna Dávidházy"
{
"type": "text-block",
"element": "doklad",
"template": "Objednávka č. {objednavka} ze dne {datum_obj:dd.MM.yyyy}"
}
{
"type": "text-block",
"element": "dodavatel",
"lines": ["{rejstrik}"],
"style": "small"
}
| Vlastnost | Co dělá |
|---|---|
lines |
Řádky textu |
element |
XML element pro placeholdery |
field |
Pole s textem (auto-hide když prázdné) |
label |
Popisek před hodnotou — „Label: hodnota" (překládá se přes dictionary) |
template |
Šablona s {pole} placeholdery |
style |
"title", "bold", "italic", "bold-italic", "small" (malé šedě) + suffix -right/-center (např. "bold-right") |
align |
Zarovnání textu: "left", "center", "right" (přepíše výchozí ze style) |
fontSize |
Velikost písma v pt (přepíše výchozí) |
Příklad — text s vlastním zarovnáním a velikostí:
{
"type": "text-block",
"lines": ["Strana 1"],
"align": "center",
"fontSize": 12
}
^)Textové hodnoty začínající ^ se zpracují jako Markdown:
XML: text_pod_r="^**Důležité:** zboží je ==nereklamovatelné=="
| Markdown | Výsledek |
|---|---|
**tučné** |
tučné |
*kurzíva* |
kurzíva |
==zvýrazněné== |
zvýrazněné (žlutě) |
* odrážka |
odrážkový seznam |
1. číslovaný |
číslovaný seznam |
Markdown funguje v: text-block (field, lines), subFields tabulky.
signature — podpisy{
"type": "signature",
"left": "Vystavil: {doklad.vystavil}",
"right": "Razítko a podpis dodavatele:\nPřevzal: _______________"
}
Vystavil: Novák Jan Razítko a podpis dodavatele:
Převzal: _______________
| Vlastnost | Co dělá |
|---|---|
left |
Levý podpis. Podporuje {field}, {element.field}, {date}, \n = nový řádek |
right |
Pravý podpis. Stejné placeholdery jako left |
leftImage |
Obrázek razítka/podpisu vlevo |
rightImage |
Obrázek razítka/podpisu vpravo |
separator — čára{ "type": "separator" }
{ "type": "separator", "style": "thick" }
{ "type": "separator", "style": "double" }
| Styl | Jak vypadá |
|---|---|
| (žádný) | Tenká šedá čára |
"thick" |
Tlustá čára |
"double" |
Dvojitá čára |
spacer — mezera{ "type": "spacer", "heightMm": 15 }
Vloží prázdné místo zadané výšky.
image — obrázek{
"type": "image",
"file": "logo.png",
"maxWidthMm": 40,
"align": "center"
}
| Vlastnost | Co dělá |
|---|---|
file |
Cesta k souboru |
src |
Přímé base64 data |
element + field |
Dynamicky z XML |
maxWidthMm |
Max. šířka v mm |
maxHeightMm |
Max. výška v mm |
align |
"left", "center", "right" |
qr-code — QR kód{
"type": "qr-code",
"template": "SPD*1.0*ACC:{ucet.iban}*AM:{doklad.celkem}*CC:CZK*MSG:Faktura {doklad.cislo}",
"sizeMm": 30,
"label": "QR platba"
}
| Vlastnost | Co dělá |
|---|---|
content |
Statický text QR kódu |
template |
Šablona s {element.field} placeholdery |
element + field |
Hodnota z XML |
sizeMm |
Velikost v mm (výchozí 35) |
label |
Popisek |
labelPosition |
"above" nebo "below" |
barcode — čárový kód{
"type": "barcode",
"content": "8594001234567",
"format": "EAN-13",
"widthMm": 50,
"heightMm": 15,
"showText": true
}
| Vlastnost | Co dělá |
|---|---|
content |
Obsah kódu |
format |
"EAN-13", "EAN-8", "Code128", "Code39", "UPC-A" |
widthMm |
Šířka v mm |
heightMm |
Výška v mm |
showText |
Zobrazit text pod kódem |
columns — bloky vedle sebeUmístí libovolné bloky do sloupců vedle sebe:
{
"type": "columns",
"ratio": "70:30",
"verticalAlign": "center",
"columns": [
{
"blocks": [
{ "type": "table", ... }
]
},
{
"blocks": [
{ "type": "qr-code", ... }
]
}
]
}
┌──────────────────────────────────┬──────────────┐
│ │ │
│ TABULKA POLOŽEK │ ┌──────┐ │
│ ┌────┬──────┬──────┐ │ │ QR │ │
│ │ # │ Naz. │ Cena │ │ │ kód │ │
│ ├────┼──────┼──────┤ │ └──────┘ │
│ │ 1 │ ... │ ... │ │ QR platba │
│ └────┴──────┴──────┘ │ │
│ │ │
└──────────────────────────────────┴──────────────┘
70 % 30 %
| Vlastnost | Co dělá | Příklad |
|---|---|---|
ratio |
Poměr šířek sloupců | "50:50", "70:30", "25:50:25" |
verticalAlign |
Svislé zarovnání | "top", "center", "bottom" |
gap |
Mezera mezi sloupci (px) | 15 |
Uvnitř columns mohou být libovolné bloky, včetně dalších columns (vnořování).
border){
"type": "columns",
"ratio": "50:50",
"columns": [
{
"blocks": [ { "type": "info-grid", ... } ]
},
{
"border": true,
"blocks": [
{ "type": "spacer", "heightMm": 28 },
{ "type": "text-block", "style": "small", "lines": ["Otisk podacího razítka"] }
]
}
]
}
Vlastnost border: true na sloupci přidá viditelný šedý rámeček (1px solid) s vnitřním paddingem. Typické pro formuláře — rámeček kolem prostoru pro razítko nebo podpis.
visibleWhen)Kterýkoliv blok (nebo jeho část) můžete podmíněně skrýt/zobrazit:
{ "type": "info-grid", "visibleWhen": "header.je_cizi_mena", ... }
| Podmínka | Popis | Příklad |
|---|---|---|
"pole" |
Zobrazit pokud pole má hodnotu | "header.je_platce" |
"!pole" |
Zobrazit pokud pole je prázdné | "!header.sleva" |
"pole=hodnota" |
Zobrazit pokud pole = hodnota | "header.mena=EUR" |
"pole!=hodnota" |
Zobrazit pokud pole ≠ hodnota | "header.mena!=CZK" |
"pole>hodnota" |
Číslo větší než | "header.kurz>1" |
"pole>=hodnota" |
Číslo větší nebo rovno | "header.sazba>=21" |
"pole<hodnota" |
Číslo menší než | "header.sleva<100" |
"pole<=hodnota" |
Číslo menší nebo rovno | "header.pocet<=0" |
visibleWhen funguje na:
Tečková notace {element.field} umožňuje v šablonách odkazovat na hodnoty z jiného XML elementu než toho, ke kterému blok patří. Např. info-grid patří elementu doklad, ale potřebujete zobrazit měnu z elementu header.
{element.pole} → prostá hodnota
{element.pole:N2} → formátovaná hodnota (číslo, datum)
{element.pole:40} → ořízne na 40 znaků
{element.pole:40.} → ořízne na 40 + trojtečka …
{element.pole:40w} → ořízne na poslední celé slovo ≤ 40
{element.pole:40w.} → celé slovo + trojtečka …
element — název XML elementu (přímý potomek root)pole — název atributu v daném elementu| Místo | Příklad |
|---|---|
info-grid template |
"template": "{header.mena} (kurz {header.kurz:N2})" |
header-two-column template |
"template": "IČO: {ico} \| Měna: {header.mena}" |
text-block lines |
"lines": ["Měna: {header.mena}, kurz: {header.kurz:N2}"] |
text-block template |
"template": "Faktura {header.cislo} ze dne {header.datum:dd.MM.yyyy}" |
tabulka label |
"label": "Cena {header.mena}" |
tabulka expr |
"expr": "cizi * header.kurz" |
tabulka template |
"template": "{cena:N2} {header.mena}" |
total-amount suffix |
"suffix": "{header.mena}" |
| signature text | "left": "Vystavil: {header.vystavil}" |
| visibleWhen | "visibleWhen": "header.je_cizi_mena" |
Info-grid — měna a kurz z hlavičky:
{
"type": "info-grid",
"element": "doklad",
"items": [
{ "label": "Variabilní symbol", "field": "vs" },
{ "label": "Měna", "template": "{header.mena} (kurz {header.kurz:N2})" }
]
}
Text-block — šablona bez vlastního elementu:
{
"type": "text-block",
"template": "Faktura {header.cislo} vystavena dne {header.datum:dd.MM.yyyy}"
}
Text-block — řádky s kombinací vlastního elementu a cross-element:
{
"type": "text-block",
"element": "dodavatel",
"lines": [
"Dodavatel: {nazev}",
"Měna: {header.mena}, kurz: {header.kurz:N2}"
]
}
Zde {nazev} se resolvuje z elementu dodavatel, {header.mena} z elementu header.
{pole} → hledá se v elementu bloku (specifikovaném v element){element.pole} → hledá se v zadaném XML elementu (přímý potomek root)"IČO: {ico} | Měna: {header.mena}"aliases)Pokud v šabloně opakovaně používáte dlouhé tečkové cesty, můžete si definovat zkratky:
{
"aliases": {
"dod": "faktura.dodavatel",
"odb": "faktura.odberatel"
},
"blocks": [
{
"type": "header-two-column",
"left": { "element": "dod", "fields": [...] },
"right": { "element": "odb", "fields": [...] }
}
]
}
element, visibleWhen, template, field, suffix a dalších místech{dod.ico} → {faktura.dodavatel.ico}repeatElement + filterBy)Pokud potřebujete z jedné šablony vygenerovat N dokumentů najednou (např. hromadné upomínky, dopisy zákazníkům, výzvy k úhradě), použijte repeatElement. Renderer vezme jeden XML kontejner a pro každý jeho child element vygeneruje kompletní dokument se všemi bloky.
XML data:
<upominky> ← repeatElement kontejner
<row organizace="1001" firma="Alfa" ... /> ← 1. iterace → dokument 1
<row organizace="1002" firma="Beta" ... /> ← 2. iterace → dokument 2
</upominky>
<pohledavky> ← sdílená plochá tabulka
<row organizace="1001" faktura="FV001" ... />
<row organizace="1001" faktura="FV002" ... />
<row organizace="1002" faktura="FV003" ... />
</pohledavky>
JSON šablona:
repeatElement: "upominky" ← iteruj přes child elementy
bloky: záhlaví, text, tabulka s filterBy, podpis
Výstup:
Dokument 1 (Alfa): záhlaví Alfa + tabulka FV001, FV002 + podpis
--- page break ---
Dokument 2 (Beta): záhlaví Beta + tabulka FV003 + podpis
document{
"document": {
"repeatElement": "upominky",
"pageBreakBetween": true,
"overflow": "flow"
}
}
| Vlastnost | Typ | Výchozí | Popis |
|---|---|---|---|
repeatElement |
string | — | Název XML kontejneru. Renderer iteruje přes jeho child elementy |
pageBreakBetween |
bool | true |
Vložit page-break mezi dokumenty. Při false se dokumenty řadí za sebe |
resetPageNumbers |
bool | false |
Resetovat číslování stránek pro každý opakovaný dokument. {page} začíná od 1 a {pages} odpovídá počtu stránek daného dokumentu |
title |
string | — | Podporuje {element.field} placeholdery. Při repeatElement se resolvuje pro každý dokument — použije se v HTML <title> i PDF titulku |
V blocích můžete přistupovat k atributům aktuálního repeat prvku stejně jako k jakémukoli jinému XML elementu:
{
"type": "header-two-column",
"right": {
"title": "ODBĚRATEL",
"element": "upominky",
"bordered": true,
"fields": [
{ "field": "firma", "style": "title" },
{ "field": "ulice" },
{ "template": "{psc} {mesto}" }
]
}
}
"element": "upominky" — v repeat režimu automaticky vrátí aktuální child element (ne celý kontejner){firma}, {ulice} — čte se z aktuálního repeat prvkudodavatel, parametr) jsou sdílené a přístupné normálněfilterBy — filtrování tabulky podle repeat prvkuBez filterBy by tabulka zobrazila všechny řádky XML elementu. S filterBy zobrazí jen řádky odpovídající aktuálnímu záznamu:
{
"type": "table",
"element": "pohledavky",
"filterBy": ["organizace"],
"columns": {
"faktura": { "label": "Faktura" },
"castka": { "label": "Částka", "format": "N2", "align": "right" }
},
"sumExpressions": [
{ "field": "castka", "expr": "SUM(castka)", "format": "N2" }
]
}
filterBy: ["organizace"] znamená: zobraz jen řádky kde pohledavky.row.organizace == upominky.row.organizace.
1. String — stejný název pole v obou tabulkách (nejčastější):
"filterBy": ["organizace", "mena"]
2. Objekt — různé názvy polí v tabulce a v repeat prvku:
"filterBy": [
{ "field": "org_id", "sourceField": "organizace" }
]
3. Objekt se sourceElement — zdrojová hodnota z jiného XML elementu:
"filterBy": [
{ "field": "stredisko", "sourceField": "stredisko", "sourceElement": "parametr" }
]
| Vlastnost | Typ | Povinný | Popis |
|---|---|---|---|
| (string) | string | — | Zkrácený zápis: název pole stejný v tabulce i v repeat prvku |
field |
string | ano | Název pole v datové tabulce |
sourceField |
string | ne | Název pole v repeat prvku. Pokud neuvedeno, použije se field |
sourceElement |
string | ne | XML element pro zdrojovou hodnotu (místo repeat prvku) |
Důležité:
- Porovnání je case-insensitive a trimuje mezery na obou stranách (kompatibilita s FoxPro CHAR poli)
- Více položek v
filterBy= AND logika (řádek musí splnit všechny podmínky)sumExpressionsse počítají jen z filtrovaných řádkůfilterBybezrepeatElementnemá efekt
V kontextu repeatElement jsou pole z první filtrované věty každé tabulky dostupná v ostatních blocích (text-block, info-grid, total-amount, signature atd.) přes tečkovou notaci {element.field}:
{
"document": { "repeatElement": "upominky" },
"blocks": [
{
"type": "table",
"element": "pohledavky",
"filterBy": ["organizace"],
"columns": { ... }
},
{
"type": "text-block",
"text": "Pohledávky v měně {pohledavky.mena}. Bankovní spojení: {pohledavky.banka}."
}
]
}
Placeholdery {pohledavky.mena} a {pohledavky.banka} se resolvují z prvního <row> prvku tabulky pohledavky po aplikaci filterBy — tedy z první věty patřící aktuálnímu odběrateli.
Typické použití:
Poznámka: Pokud
filterBynevrátí žádný řádek pro daný repeat prvek, placeholder vrátí prázdný řetězec. Pole jsou dostupná z prvního filtrovaného řádku — pokud se v tabulce hodnota pole mění řádek od řádku, používejte jen ta pole, která jsou pro celou skupinu konstantní.
JSON šablona:
{
"document": {
"repeatElement": "upominky",
"pageBreakBetween": true,
"overflow": "flow"
},
"blocks": [
{
"type": "header-two-column",
"left": {
"title": "DODAVATEL",
"element": "dodavatel",
"fields": [
{ "field": "nazev", "style": "title" },
{ "field": "ulice" },
{ "template": "{psc} {mesto}" }
]
},
"right": {
"title": "ODBĚRATEL",
"element": "upominky",
"bordered": true,
"fields": [
{ "field": "firma", "style": "title" },
{ "field": "ulice" },
{ "template": "{psc} {mesto}" }
]
}
},
{
"type": "text-block",
"element": "upominky",
"field": "vec",
"style": "title"
},
{
"type": "table",
"element": "pohledavky",
"filterBy": ["organizace"],
"columns": {
"faktura": { "label": "Číslo dokladu" },
"splatna": { "label": "Splatnost", "format": "dd.MM.yyyy" },
"rozdil": { "label": "K úhradě", "format": "N2", "align": "right" }
},
"sumExpressions": [
{ "field": "rozdil", "expr": "SUM(rozdil)", "format": "N2" }
],
"sumLabel": "Celkem"
},
{
"type": "signature",
"left": "{parametr.sidlo} dne {date}",
"right": "{upominky.podepsal}"
}
]
}
XML data:
<root>
<dodavatel nazev="EFES spol. s r.o." ulice="Neklanova 18" psc="128 00" mesto="Praha" />
<parametr sidlo="Praha" />
<upominky>
<row organizace="1001" firma="Alfa s.r.o." ulice="Hlavní 1" psc="110 00"
mesto="Praha" vec="Upomínka č. 1" podepsal="Jan Novák" />
<row organizace="1002" firma="Beta a.s." ulice="Vedlejší 5" psc="602 00"
mesto="Brno" vec="Upomínka č. 2" podepsal="Jan Novák" />
</upominky>
<pohledavky>
<row organizace="1001" faktura="FV001" splatna="2026-01-15" rozdil="15000" />
<row organizace="1001" faktura="FV002" splatna="2026-02-01" rozdil="8500" />
<row organizace="1002" faktura="FV003" splatna="2026-01-20" rozdil="42000" />
</pohledavky>
</root>
Výstup: 2 dokumenty oddělené page-breakem:
ShowProgress)Při generování velkých dokumentů (batch tisk faktur) lze zobrazit dialog s průběhem:
loBuilder.ShowProgress = .T.
loBuilder.Render("faktura.pdf", "sablona.json") && dialog s průběhem
loBuilder.ShowProgress = .F. && zpět bez dialogu
Dialog zobrazuje číslo řádku, fázi PDF generování a tlačítko Storno pro přerušení. Property přežívá Reset() i EndBatch().
Existující FoxPro FRX reporty (faktury, dodací listy) lze konvertovat na JSON šablony:
*--- Auto-detekce typu ---
loBuilder.ConvertFrxToAllFiles("C:\frx\VYDANA1A.xml", "C:\output\")
*--- Vynuceně jako dokument (pokud auto-detekce selže) ---
loBuilder.ConvertFrxToDocumentAllFiles("C:\frx\INVUCKC.xml", "C:\output\")
loBuilder.ConvertFrxToDocumentJsonFile("C:\frx\INVUCKC.xml", "C:\output\invuckc.json")
Tip: Auto-detekce rozpozná dokumenty podle výšky PageHeader a Title bandu. Pokud FRX s fakturou klasifikuje jako tabulku, použijte variantu
Documentv názvu metody.
Inventarizační protokoly (INVUCKC, INVUCSUM2): Automatická konverze FRX inventarizačních protokolů je podporována. Detekce rozpozná typický vzor — PageBreak, groupExpression, nízký Detail band (< 10mm) a GroupFooter s mnoha poli (≥ 10). FRX se konvertuje metodou
BuildInventoryDocument(), která generuje: logo, header-two-column, tabulku s filterBy, rekapitulaci, podmíněné texty a podpisy. Více viz sekce 22.
FRX konvertor automaticky rozpozná inventarizační protokoly (INVUCKC, INVUCSUM2 apod.) a konvertuje je jako dokumenty s repeatElement.
FRX je klasifikován jako inventarizační protokol pokud splňuje:
PageBreak = true a neprázdným groupExpr1. image (logo)
2. header-two-column (adresa + nadpis + podnadpis)
3. separator (thick + thin)
4. table (s filterBy z groupExpression)
5. total-amount (celková částka)
6. rekapitulace (columns s info-gridy: Účetní stav, Zjištěný stav, Rozdíl)
7. podmíněné texty (visibleWhen: shoda/neshoda)
8. signature (datum + vyhotovil/schválil)
*--- Automatická konverze ---
loBuilder.ConvertFrxToAllFiles("C:\frx\INVUCKC.xml", "C:\output\")
*--- Vynuceně jako dokument ---
loBuilder.ConvertFrxToDocumentAllFiles("C:\frx\INVUCKC.xml", "C:\output\")
repeatElement: generováno z groupExpression — pro každý účet se opakuje celý dokumentfilterBy: detailní tabulka filtruje řádky podle účtu (z groupExpression)resetPageNumbers: true — každý účet má vlastní číslování stránektitle s placeholdery: např. "Inventura účtu {ucty.ucet}" — HTML <title> se mění pro každý účetpadr(ucet,6) se správně parsují — funkce jako padr, padl, substr, str, left, right se ignorují a extrahuje se vnitřní název polegroups + detailBorders)Vlastnost groups umožňuje seskupit řádky plochých XML dat v tabulce dokumentu podle hodnoty atributu — podobně jako skupiny v tabulkové sestavě. Každá skupina dostane záhlaví a volitelný sum řádek. Typické použití: rozvaha rozepsaná po účtech, přehled pohybů po střediscích.
Alternativa: Pro velké sestavy s mnoha skupinami zvažte tabulkovou sestavu ("renderer": "table") se skupinami — ta má více možností (tableBreak, reprintHeader, XLSX, víceúrovňové skupiny).
{
"type": "table",
"element": "data",
"detailBorders": "h-dashed",
"groups": [{
"groupExpression": "ucet",
"label": "Účet {ucet} — {ucty.nazev}",
"headerBackground": "#e8f4fc",
"detailBorders": "h-dashed",
"sumExpressions": [
{ "field": "castka", "expr": "SUM(castka)", "format": "N2" }
],
"sumLabel": "Celkem {ucet}",
"sumBackground": "#f0f0f0"
}],
"columns": {
"text": { "label": "Popis" },
"castka": { "label": "Částka", "align": "right", "format": "N2" }
},
"sumExpressions": [
{ "field": "castka", "expr": "SUM(castka)", "format": "N2" }
],
"sumLabel": "Celkem za všechny účty"
}
FoxPro příprava dat:
*--- Data musí být setříděna podle groupExpression ---
SELECT ucet, text, castka FROM ucetni_data ORDER BY ucet INTO CURSOR tmpData
CURSORTOXML("tmpData", "lcXml", 3, 16)
loBuilder.AddElementWithXmlContent("data", lcXml)
| Vlastnost | Typ | Výchozí | Popis |
|---|---|---|---|
groupExpression |
string nebo array | — | Atribut pro detekci změny skupiny. Pro compound klíč: ["ucet", "stredisko"] |
label |
string | — | Šablona záhlaví skupiny. {ucet} = z prvního řádku skupiny |
headerBackground |
string | "#e8f4fc" |
Barva pozadí záhlaví skupiny |
detailBorders |
string | — | Styl čar uvnitř skupiny (viz níže) |
sumExpressions |
array | — | Výrazy pro sum řádek skupiny |
sumLabel |
string | — | Popisek sum řádku skupiny |
sumBackground |
string | "#f0f0f0" |
Barva pozadí sum řádku skupiny |
Vlastnost detailBorders řídí čáry mezi datovými řádky. Nastavuje se na bloku ("type": "table") nebo na skupině (přepíše blokové nastavení):
| Hodnota | Popis |
|---|---|
"all" |
Všechny čáry — výchozí |
"horizontal" |
Jen vodorovné čáry (bez svislých) |
"vertical" |
Jen svislé oddělovače (bez vodorovných) |
"none" |
Žádné vnitřní čáry |
"inner-none" |
Žádné čáry ani vnější rám |
"h-dashed" |
Přerušované vodorovné čáry |
"h-dashed-only" |
Přerušované vodorovné, žádné svislé |
Příklad — různé styly pro různé skupiny:
{
"type": "table",
"element": "polozky",
"detailBorders": "all",
"groups": [
{
"groupExpression": "kategorie",
"label": "Kategorie: {kategorie}",
"detailBorders": "h-dashed"
}
],
"columns": { ... }
}
Data musí být předem setříděná podle
groupExpression. Renderer pouze detekuje změny — netřídí data sám. V FoxPro použijteORDER BY ucet(nebo více polí pro compound klíč).
Grand total se vykreslí z
block.sumExpressionspo všech skupinách. Pokud nechcete grand total, nevyplňteblock.sumExpressions.
Skupiny v dokumentu vs. tabulkové sestavě: Skupiny v document rendereru jsou jednoduchá plochá grupování (jedna úroveň). Pro víceúrovňové skupiny, XLSX export, page break po skupině nebo headerMode external/inline použijte tabulkovou sestavu (
"renderer": "table").
sumRows)Pro zobrazení více sum řádků za skupinou (celkem, splatné, po splatnosti) použijte sumRows místo jednoduchého sumExpressions + sumLabel:
{
"groups": [{
"groupExpression": "mena",
"label": "Měna: {mena}",
"sumRows": [
{
"sumLabel": "Celkem {mena}",
"sumExpressions": [{ "field": "castka", "expr": "SUM(castka)", "format": "N2" }],
"sumBorder": "solid"
},
{
"sumLabel": "Splatné",
"where": "stav=S",
"sumBorder": "none",
"style": "light"
},
{
"sumLabel": "Po splatnosti",
"where": "stav=P",
"sumBorder": "none",
"hideIfZero": true
}
]
}]
}
where — filtruje řádky skupiny (jen stav=S se počítá do „Splatné")hideIfZero — řádek se přeskočí pokud jsou všechny součty nulovéstyle: "light" — menší, šedý font (ne tučný)sumBorder — styl čáry: "solid" (výchozí pro první), "dashed", "light", "none"sumRow dědí sumExpressions z prvního, pokud je neuvede{
"version": "1.0",
"document": {
"title": "FAKTURA – daňový doklad",
"culture": "cs-CZ",
"overflow": "auto",
"pageMarginMm": 8
},
"pageHeader": {
"left": "EFES spol. s r.o.",
"right": "Strana {page} z {pages}",
"fromPage": 2
},
"blocks": [
{
"type": "columns",
"ratio": "30:70",
"verticalAlign": "center",
"columns": [
{ "blocks": [{ "type": "image", "file": "logo.jpg", "maxWidthMm": 35 }] },
{ "blocks": [{ "type": "text-block", "lines": ["F A K T U R A - daňový doklad"], "style": "title" }] }
]
},
{ "type": "separator", "style": "thick" },
{
"type": "header-two-column",
"left": {
"title": "DODAVATEL",
"element": "dodavatel",
"fields": [
{ "field": "nazev", "style": "title" },
{ "field": "ulice" },
{ "template": "{psc} {mesto}" },
{ "separator": true },
{ "label": "IČO", "field": "ico" },
{ "label": "DIČ", "field": "dic" }
]
},
"right": {
"title": "ODBĚRATEL",
"element": "odberatel",
"bordered": true,
"fields": [
{ "field": "nazev", "style": "title" },
{ "field": "ulice" },
{ "template": "{psc} {mesto}" },
{ "separator": true },
{ "label": "IČO", "field": "ico" },
{ "label": "DIČ", "field": "dic" }
]
}
},
{
"type": "info-grid",
"element": "doklad",
"columns": 2,
"borderless": true,
"items": [
{ "label": "Číslo faktury", "field": "cislo", "style": "title" },
{ "label": "Variabilní symbol", "field": "vs" },
{ "separator": true },
{ "label": "Způsob úhrady", "template": "Příkazem k úhradě" },
{ "label": "Den splatnosti", "field": "splatnost", "format": "dd.MM.yyyy", "style": "bold" }
]
},
{
"type": "table",
"element": "polozky",
"primary": true,
"showRowNumbers": true,
"columns": {
"nazev": { "label": "Název" },
"pocet": { "label": "Množství", "align": "right", "format": "N2", "width": "60px" },
"mj": { "label": "MJ", "align": "center", "width": "30px" },
"jc": { "label": "Cena/ks", "align": "right", "format": "N2", "width": "80px" },
"cena": { "label": "Celkem", "align": "right", "format": "N2", "width": "90px" }
},
"sumExpressions": [
{ "field": "cena", "expr": "SUM(cena)", "format": "N2" }
],
"sumLabel": "Celkem"
},
{
"type": "total-amount",
"element": "doklad",
"field": "celkem_s_dph",
"label": "Celkem k úhradě",
"format": "N2",
"suffix": "Kč",
"style": "large"
},
{
"type": "text-block",
"element": "dodavatel",
"lines": ["{rejstrik}"],
"style": "small"
},
{ "type": "separator" },
{
"type": "signature",
"left": "Vystavil: {doklad.vystavil}",
"right": "Razítko a podpis dodavatele:\nPřevzal: _______________"
}
]
}
element v blocích odpovídá názvům XML elementů (case-sensitive)blocks je pole (hranatá závorka [...])element v bloku table ukazuje na XML element s <row> potomkyprimary: true, ověřte, že element opravdu existuje (jinak attachment mode selže)template místo field (template se nezakrývá)field odpovídá přesně názvu XML atributu"overflow": "auto" v sekci document — automaticky rozhodne o stránkovánípageMarginMm — velké okraje zmenšují obsah{} nebo []label: Faktura → "label": "Faktura"blocks = pořadí vykreslování shora dolů| Co chci | Kde to nastavit | Příklad |
|---|---|---|
| Přidat/ubrat pole v adrese | header-two-column → fields |
přidat/smazat objekt |
| Změnit popisek v info-grid | info-grid → items → label |
"label": "Nový text" |
| Přidat sloupec do tabulky | table → columns |
přidat klíč + objekt |
| Skrýt sloupec | table → columns → pole |
"hide": true |
| Formát čísla | format na sloupci/položce |
"N2", "dd.MM.yyyy" |
| Přeuspořádat bloky | Přesunout blok v poli blocks |
vyříznout + vložit |
| Přidat mezeru | Vložit spacer blok | { "type": "spacer", "heightMm": 10 } |
| Přidat čáru | Vložit separator blok | { "type": "separator" } |
| Podmíněně skrýt blok | visibleWhen na bloku |
"visibleWhen": "header.pole" |
| Změnit okraje stránky | document → pageMarginMm |
"pageMarginMm": 10 |
| Na šířku | document → orientation |
"orientation": "landscape" |
| QR platba | Přidat qr-code blok | viz příklad QR kódu výše |
| Rámeček kolem odběratele | bordered na pravém sloupci |
"bordered": true |
| Zobrazit i prázdná pole | fieldStyle: "form" na info-grid |
Prázdná pole se zobrazí jako orámované boxy |
Vložte nový objekt do pole blocks na požadované místo:
"blocks": [
{ "type": "header-two-column", ... },
{ "type": "separator" },
{ "type": "info-grid", ... },
{ "type": "spacer", "heightMm": 5 },
{ "type": "table", ... }
]
{
"type": "info-grid",
"visibleWhen": "header.je_cizi_mena",
"element": "doklad",
"items": [
{ "label": "Měna", "template": "{header.mena}" },
{ "label": "Kurz", "field": "kurz", "format": "N3" }
]
}
Celý blok se zobrazí jen pokud header.je_cizi_mena má neprázdnou hodnotu.
Pozor: Za poslední položkou v
{}nebo[]nesmí být čárka. Toto je nejčastější chyba při editaci JSON.