DOCX-Template-Beispiele¶
Diese Seite zeigt typische Muster, wie ein Word-Template für flexiDok aufgebaut wird. flexiDok nutzt intern die Bibliothek docx-templates — die Befehlssyntax dieser Seite folgt ihrer Konvention.
Die Referenz aller Hilfsfunktionen (getComponentListForAllSectionsByChapterName, createImage, formatDate, …) finden Sie unter DOCX-Template-Funktionen.
Befehle im Überblick¶
flexiDok verwendet +++ als Befehls-Trennzeichen. Jeder Befehl steht zwischen zwei +++.
| Befehl | Bedeutung |
|---|---|
+++INS ausdruck+++ |
Ergebnis eines Ausdrucks an der Stelle einfügen |
+++EXEC code+++ |
JavaScript ausführen, nichts einfügen (für Variablendefinitionen, Vorverarbeitung) |
+++FOR x IN liste+++ … +++END-FOR x+++ |
Über eine Liste iterieren |
+++IF bedingung+++ … +++END-IF+++ |
Abschnitt nur bei erfüllter Bedingung einfügen |
+++IMAGE bildobjekt+++ |
Bild einfügen |
+++LINK ({url, label})+++ |
Hyperlink einfügen |
Schleifenvariable mit $
Innerhalb einer FOR-Schleife muss der Name der Schleifenvariable mit $ präfixiert werden, z.B. +++INS $eintrag.name.value+++. Der zusätzliche Index des innersten Loops steht in $idx (0-basiert).
Typischer Aufbau eines Templates¶
Ein Report wird in der Regel so strukturiert:
- Vorbereitungsblock am Anfang: Listen aufbauen, Konstanten setzen, Hilfsfunktionen definieren (ein bis mehrere
EXEC-Befehle) - Inhaltsteil: Text mit
INS, Tabellen mitFOR, bedingte Passagen mitIF
1. Vorbereitungsblock — Listen und Kennzeichen aufbauen¶
Am Anfang des Dokuments werden oft mehrere EXEC-Blöcke platziert, in denen Listen aus den Dokumentdaten gefiltert und kombiniert werden. Die Ergebnisse stehen danach im gesamten Template zur Verfügung.
+++EXEC
LISTE_A = getListFromChapterAndChapterType(`eintraege`, `TypA`);
LISTE_B1 = getListFromChapterAndChapterType(`eintraege`, `TypB`);
LISTE_B2 = getListFromChapterAndChapterType(`eintraege`, `TypB Variante`);
LISTE_B3 = getListFromChapterAndChapterType(`eintraege`, `TypB Variante Kombi`);
GESAMT_OHNE_KOMBI = [].concat(LISTE_B1, LISTE_B2);
GESAMT_ALLE = [].concat(LISTE_B1, LISTE_B2, LISTE_B3);
IS_B1 = LISTE_B1.length > 0;
IS_B2 = LISTE_B2.length > 0;
IS_GESAMT = GESAMT_ALLE.length > 0;
SHOW_BLOCK = true;
if (LISTE_A.length == 0 && LISTE_B1.length == 0) {
SHOW_BLOCK = false;
}
+++
Benennung von Variablen
In unseren Templates nutzen wir für diese Template-weiten Variablen meist GROSSBUCHSTABEN — das macht sie im Text gut erkennbar und vermeidet Namenskollisionen mit Feldern aus dem Dokument.
2. Tabellendaten aus mehreren Listen zusammensetzen¶
Ein häufiges Muster: Aus mehreren gefilterten Listen wird eine gemeinsame Tabelle aufgebaut, in der jede Zeile zusätzlich ein Kürzel und eine Beschreibung bekommt.
+++EXEC
TABELLE = [];
A_COUNT = 1;
for (let eintrag of LISTE_A) {
let OBJ = {};
OBJ[`KUERZEL`] = ``;
OBJ[`BESCHREIBUNG`] = ``;
if (eintrag.ChapterTypes.length > 0 && eintrag.ChapterTypes[0] == `TypA`) {
OBJ[`KUERZEL`] = `A ` + A_COUNT;
OBJ[`BESCHREIBUNG`] = `Beschreibung Typ A`;
A_COUNT++;
OBJ[`NUMMER`] = eintrag.uebersicht.nummer.value + ` ` + eintrag.uebersicht.bezeichnung.value[0];
OBJ[`KENNUNG`] = eintrag.uebersicht.kennung.value;
OBJ[`ZUSATZ`] = eintrag.uebersicht.zusatz.value;
TABELLE.push(OBJ);
}
}
B_COUNT = 1;
for (let eintrag of LISTE_B1) {
let OBJ = {};
OBJ[`KUERZEL`] = `B ` + B_COUNT;
OBJ[`BESCHREIBUNG`] = `Beschreibung Typ B`;
B_COUNT++;
OBJ[`NUMMER`] = eintrag.uebersicht.nummer.value + ` ` + eintrag.uebersicht.bezeichnung.value[0];
OBJ[`KENNUNG`] = eintrag.uebersicht.kennung.value;
OBJ[`ZUSATZ`] = eintrag.uebersicht.zusatz.value;
TABELLE.push(OBJ);
}
+++
Diese TABELLE kann später im Template mit einer einzigen FOR-Schleife in eine Word-Tabelle geschrieben werden.
3. Hilfsfunktionen inline definieren¶
Für kleine, wiederverwendbare Logik lassen sich JavaScript-Funktionen direkt im Template definieren:
+++EXEC
ABSCHNITTE = getComponentListForAllSectionsByChapterName(`kapitelname`);
getAbschnittsbezeichnung = (arr) => {
for (let tmp of arr) {
if (tmp.Name === `uebersicht`) {
return tmp.nummer.value + ` ` + tmp.bezeichnung.value;
}
}
}
+++
Die Funktion getAbschnittsbezeichnung(...) kann anschließend überall im Template aufgerufen werden.
4. Konstanten und Textbausteine¶
Feste Texte, die an mehreren Stellen vorkommen, werden einmal definiert und wiederverwendet:
+++EXEC
OK_TEXT = `bestanden`;
NOK_TEXT = `nicht bestanden (siehe Punkt 2)`;
IO_TEXT = `in Ordnung`;
NIO_TEXT = `nicht in Ordnung (siehe Punkt 2)`;
MINUS_TEXT = `-`;
HINWEIS_TEXT = `nach Herstellerangaben`;
+++
5. Statusflag anhand einer Liste setzen¶
EXEC lässt sich auch in einer FOR-Schleife verwenden, um z.B. ein einziges Statusflag zu setzen, wenn in einer Liste mindestens ein bestimmtes Kriterium zutrifft:
+++EXEC
NOTIZEN = getComponentListForAllSectionsByChapterName(`notizen`);
ZEIGE_ERFOLG = true;
+++
+++FOR notiz IN NOTIZEN+++
+++EXEC
if ($notiz.anzeigen.value) {
ZEIGE_ERFOLG = false;
}
+++
+++END-FOR notiz+++
Nach diesem Block steht ZEIGE_ERFOLG für den Rest des Templates als Flag zur Verfügung.
Inhaltsmuster im Fließtext¶
Bedingter Text mit IF¶
Typischer Aufbau für "Alles ok" vs. "Abweichungen":
+++IF ZEIGE_ERFOLG+++
Die +++INS allgemein.prozessdaten.dokumenttyp.value+++ war erfolgreich, es wurden keine Abweichungen festgestellt.
+++END-IF+++
+++IF !ZEIGE_ERFOLG+++
Die +++INS allgemein.prozessdaten.dokumenttyp.value+++ war erfolgreich, es wurden aber Abweichungen festgestellt. Die Prüfung gilt erst als abgeschlossen, wenn dokumentierte Nachweise zu deren Behebung vorliegen. Folgende Abweichungen wurden festgestellt:
+++FOR notiz IN NOTIZEN+++
+++IF $notiz.anzeigen.value+++
• +++INS $notiz.titel.value+++
+++END-IF+++
+++END-FOR notiz+++
Detaillierte Beschreibungen befinden sich unter Punkt 2.
+++END-IF+++
! vor dem Ausdruck
+++IF !ZEIGE_ERFOLG+++ funktioniert wie in JavaScript: der Block wird eingeschlossen, wenn ZEIGE_ERFOLG falsch/leer ist.
Varianten nach Feldwert¶
Unterschiedlicher Text je nach Wert eines Dokumentfelds:
+++IF allgemein.prozessdaten.dokumenttyp.value === `Variante1`+++
Erläuterungstext für Variante 1.
+++END-IF+++
+++IF allgemein.prozessdaten.dokumenttyp.value !== `Variante1`+++
Erläuterungstext für alle anderen Varianten.
+++END-IF+++
Vergleichsstrings in Backticks
Wir verwenden in Template-Ausdrücken durchgehend Backticks (`) für Strings statt einfache oder doppelte Anführungszeichen. Grund: Word ersetzt normale Anführungszeichen gerne durch typografische Smart Quotes („ "), die dann zu Syntaxfehlern führen. Backticks werden von Word nicht autokorrigiert.
Einfache Wertausgabe¶
Auftragsnummer: +++INS allgemein.kopf.auftragsnummer.value+++
Kunde: +++INS allgemein.kunde.name.value+++
Erstellt am: +++INS formatDate(allgemein.dokumentation.datum.value, `dd.MM.yyyy`)+++
Geprüft durch: +++INS getValidator(true)+++
Tabellenzeile per Schleife¶
Die FOR-Schleife funktioniert auch über Tabellenzeilen: Der FOR-Befehl steht in der ersten Zeile (als Kommentarzeile), die eigentliche Inhaltszeile folgt, und END-FOR steht in einer abschließenden Zeile.
| Kürzel | Nummer | Kennung |
|---------------------------|-------------------------|------------------------|
| +++FOR z IN TABELLE+++ | | |
| +++INS $z.KUERZEL+++ | +++INS $z.NUMMER+++ | +++INS $z.KENNUNG+++ |
| +++END-FOR z+++ | | |
Word löscht die Zeilen mit FOR und END-FOR automatisch — übrig bleibt nur die Inhaltszeile, einmal pro Listen-Eintrag.
Bilder einfügen¶
+++FOR bild IN allgemein.fotos.bilder+++
+++IMAGE createImage($bild, 10, 7, null, true, true)+++
+++END-FOR bild+++
Oder eine PDF-Anlage seitenweise:
+++FOR seite IN createPDFPages(allgemein.anhang.zertifikat)+++
+++IMAGE $seite+++
+++END-FOR seite+++
Vollständiges Miniatur-Beispiel¶
Ein knappes, komplettes Template mit Vorbereitung, bedingter Ausgabe und Tabelle:
+++EXEC
ABSCHNITTE = getComponentListForAllSectionsByChapterName(`notizen`);
HAT_ABWEICHUNG = false;
+++
+++FOR a IN ABSCHNITTE+++
+++EXEC
if ($a.anzeigen.value) { HAT_ABWEICHUNG = true; }
+++
+++END-FOR a+++
Prüfbericht für +++INS allgemein.kunde.name.value+++
Datum: +++INS formatDate(allgemein.kopf.datum.value, `dd.MM.yyyy`)+++
+++IF !HAT_ABWEICHUNG+++
Keine Abweichungen festgestellt.
+++END-IF+++
+++IF HAT_ABWEICHUNG+++
Folgende Abweichungen wurden festgestellt:
+++FOR a IN ABSCHNITTE+++
+++IF $a.anzeigen.value+++
• +++INS $a.titel.value+++
+++END-IF+++
+++END-FOR a+++
+++END-IF+++
Geprüft durch: +++INS getValidator(true)+++
Tipps aus der Praxis¶
- Backticks statt Anführungszeichen in allen JavaScript-Ausdrücken (siehe Hinweis oben).
- Template-Variablen in GROSSBUCHSTABEN — leichter lesbar und kollidieren nicht mit Feldnamen.
- Vorbereitungsblöcke ganz an den Anfang setzen; Inhaltsblöcke sollten sich auf fertige Variablen stützen, nicht mehrere
getListFromChapter…-Aufrufe mit denselben Argumenten wiederholen. EXEC-Blöcke erzeugen keine Leerzeilen — aber der umgebende Absatz im Word bleibt. Platzieren SieEXEC-Blöcke daher in eigenen Absätzen, die später gelöscht werden können, oder inline in bestehende Absätze.- Fehlt ein Feld im Dokument, ist der Ausdruck
kapitel.abschnitt.feld.valueundefined. Wenn das ein Problem ist, prüfen Sie vorher perIF:
+++IF allgemein.kunde.name && allgemein.kunde.name.value+++
Kunde: +++INS allgemein.kunde.name.value+++
+++END-IF+++
- Smart Quotes in Word deaktivieren für Template-Dateien: Datei → Optionen → Dokumentprüfung → AutoKorrektur-Optionen → AutoFormat während der Eingabe → "Gerade Anführungszeichen" deaktivieren. Andernfalls wandelt Word
"foo"in„foo"um — und JavaScript-Ausdrücke brechen.