Haiku.lt

Invoice Markup Language (InML)

2026-05-24
Dieser Artikel wurde mit KI übersetzt

InML (Invoice Markup Language) ist eine XML-basierte Vorlagensprache, mit der Sie das PDF-Layout Ihrer Rechnungen in Haiku.lt definieren. Sie haben damit volle Kontrolle über Struktur, Stil und Inhalt Ihrer Rechnungen.

Als Ausgangspunkt können Sie einen der fünf integrierten Stile auswählen und anpassen oder eine Vorlage von Grund auf neu schreiben.

Grundstruktur

Jede InML-Vorlage beginnt mit einem <inml>-Wurzelelement:

<inml version="1.0" page-size="A4" margin="20mm"
      font-regular="Roboto-Light" font-bold="Roboto-Medium">
  <page>
    <!-- Elemente, die auf jeder Seite gezeichnet werden -->
  </page>
  <layout>
    <!-- Inhaltsbereiche -->
  </layout>
</inml>

Wurzel-Attribute

AttributBeschreibung
versionInML-Version. Aktuell 1.0.
page-sizeSeitenformat. Aktuell wird nur A4 unterstützt.
marginStandard-Seitenrand (z. B. 20mm).
font-regularSchriftart für normalen Text (z. B. Roboto-Light).
font-boldSchriftart für fetten Text (z. B. Roboto-Medium).

Einheiten

Alle Maße verwenden Millimeter (mm) oder Punkte. Schreiben Sie Werte wie 20mm, 5mm, 210mm. Schriftgrößen werden als reine Zahlen in Punkten angegeben (z. B. font-size="12").

Seitenelemente

Der Abschnitt <page> definiert Elemente, die auf jeder Seite des PDFs hinter dem Hauptinhalt gezeichnet werden. Verwenden Sie ihn für Hintergrundbilder, dekorative Rechtecke oder Linien.

<page>
  <image src="{{background}}" x="0mm" y="0mm" width="210mm" height="297mm" />
  <rect x="0mm" y="0mm" width="210mm" height="30mm" fill="#f1f5f9" />
  <line x1="20mm" y1="50mm" x2="190mm" y2="50mm" color="#cccccc" width="0.5mm" />
</page>

Verfügbare Seitenelemente

  • <image> — Hintergrundbild. Attribute: src, x, y, width, height.
  • <rect> — Rechteck. Attribute: x, y, width, height, fill, stroke, stroke-width.
  • <line> — Linie. Attribute: x1, y1, x2, y2, color, width.

Layout und Bereiche

Der Abschnitt <layout> enthält ein oder mehrere <region>-Elemente. Jeder Bereich ist eine unabhängige Inhaltszone mit eigenem Positionierungsmodus.

<layout>
  <region id="header" flow="fixed" margin-top="5mm"
          margin-left="20mm" content-width="170mm">
    <!-- Inhalt -->
  </region>
  <region id="body" flow="sequential" margin-top="20mm">
    <!-- Inhalt -->
  </region>
</layout>

Region-Attribute

AttributBeschreibung
idEindeutige Kennung des Bereichs.
flowPositionierungsmodus: sequential, absolute oder fixed.
margin-leftHorizontaler Abstand vom Seitenrand.
content-widthÜberschreibt die Inhaltsbreite für diesen Bereich.
margin-topVertikaler Abstand. Bei sequential-Bereichen fügt er Platz darüber ein.
min-heightMindesthöhe, die für den Bereich reserviert wird, auch bei kürzerem Inhalt.

Flow-Modi

  • sequential — Bereiche fließen nacheinander von oben nach unten. Dies ist der gängigste Modus für den Hauptinhalt.
  • absolute — wird an einer bestimmten Stelle positioniert, berechnet aus der aktuellen vertikalen Position. Nachfolgende sequential-Bereiche folgen danach.
  • fixed — wird an einer festen Position auf der Seite platziert, unabhängig von anderen Bereichen. Nützlich für Kopfzeilen oder Overlays.

Layout-Spalten

Um Bereiche nebeneinander anzuordnen, wickeln Sie sie auf Layout-Ebene in ein <columns>-Element ein:

<layout>
  <columns>
    <column margin-left="20mm" content-width="80mm">
      <region id="left" flow="sequential">
        <!-- linker Inhalt -->
      </region>
    </column>
    <column content-width="80mm">
      <region id="right" flow="sequential">
        <!-- rechter Inhalt -->
      </region>
    </column>
  </columns>
</layout>

Jedes <column> kann die Attribute margin-left und content-width haben und enthält ein oder mehrere <region>-Elemente.

Inhaltselemente

Inhaltselemente werden innerhalb von Bereichen platziert. Alle Inhaltselemente teilen sich diese optionalen Attribute:

AttributBeschreibung
fontregular oder bold.
font-sizeSchriftgröße in Punkten (z. B. 12).
colorText- oder Füllfarbe (z. B. #333333).
alignTextausrichtung: left, right oder center.
margin-topAbstand über dem Element.
margin-bottomAbstand unter dem Element.

Zeigt das Firmenlogo unter Beibehaltung des Seitenverhältnisses.

<logo src="{{logo}}" width="50mm" ratio="{{logoRatio}}" />
AttributBeschreibung
srcBilddaten ({{logo}}-Vorlagenvariable verwenden).
widthAnzeigebreite.
heightOptionale feste Höhe.
ratioSeitenverhältnis ({{logoRatio}}-Variable verwenden).

<title>

Überschriftentext, typischerweise für den Rechnungstitel.

<title font="bold" font-size="14" align="center">{{invoiceTitle}}</title>

<text>

Normaler Textinhalt.

<text font="regular" font-size="12">{{seller}}</text>

<columns> und <column>

Ordnen Inhalt innerhalb eines Bereichs nebeneinander an.

<columns>
  <column width="50%" align="left">
    <text font="bold" font-size="12">{{t.invoice.seller}}</text>
    <text font="regular" font-size="12" margin-top="5mm">{{seller}}</text>
  </column>
  <column width="50%" align="right">
    <text font="bold" font-size="12">{{t.invoice.buyer}}</text>
    <text font="regular" font-size="12" margin-top="5mm">{{buyer}}</text>
  </column>
</columns>

Jedes <column> hat ein width-Attribut als Prozentwert (z. B. 50%) und ein optionales align-Attribut.

<stack> und <group>

Vertikal gestapelte Inhaltsgruppen mit konfigurierbarem Abstand dazwischen.

<stack spacing="10mm">
  <group>
    <text font="bold" font-size="12">Erster Abschnitt</text>
    <text font="regular" font-size="12">Inhalt hier</text>
  </group>
  <group>
    <text font="bold" font-size="12">Zweiter Abschnitt</text>
    <text font="regular" font-size="12">Weiterer Inhalt</text>
  </group>
</stack>

Das Attribut spacing steuert den vertikalen Abstand zwischen den Gruppen.

<box>

Ein umrandeter/gepolsterter Container für Inhalt.

<box stroke="#cccccc" padding="5mm">
  <text font="regular" font-size="12">Eingerahmter Inhalt</text>
</box>
AttributBeschreibung
strokeRahmenfarbe.
paddingInnenabstand.
heightOptionale feste Höhe.

<rect>

Eine Rechtecksform im Inhaltsfluss.

<rect width="170mm" height="1mm" fill="#238c83" />
AttributBeschreibung
widthRechteckbreite.
heightRechteckhöhe.
fillFüllfarbe.
strokeRahmenfarbe.

<image>

Ein eingebettetes Bild im Inhaltsfluss.

<image src="{{logo}}" width="50mm" height="20mm" />

<spacer>

Fügt vertikalen Abstand zwischen Elementen ein.

<spacer height="10mm" />

<invoice-table>

Die Tabelle der Rechnungspositionen. Dies ist das zentrale Element zur Darstellung der Rechnungspositionen mit Spalten und einer Zusammenfassung.

<invoice-table row-style="minimal" cell-padding="0mm"
       separator-after-header="true" separator-after-items="true"
       separator-color="#aaaaaa" separator-width="0.5mm">
  <col name="id"     label="{{t.invoice.lineItemNo}}"     width="10mm" align="left" />
  <col name="name"   label="{{t.invoice.lineItemName}}"   width="80mm" align="left" />
  <col name="unit"   label="{{t.invoice.lineItemUnit}}"   width="20mm" align="right" />
  <col name="amount" label="{{t.invoice.lineItemAmount}}" width="20mm" align="right" />
  <col name="price"  label="{{priceColumnLabel}}"         width="20mm" align="right" />
  <col name="total"  label="{{t.invoice.lineItemSum}}"    width="20mm" align="right" />

  <summary>
    <row label="{{t.invoice.total}}" value="{{total}}" />
  </summary>
</invoice-table>

Tabellen-Attribute

AttributBeschreibung
row-styleZeilenstil: minimal, striped, bordered oder colored-header.
cell-paddingInnenabstand in jeder Zelle.
separator-after-headerLinie nach der Kopfzeile anzeigen (true/false).
separator-after-itemsLinie nach allen Positionen anzeigen (true/false).
separator-colorFarbe der Trennlinien.
separator-widthDicke der Trennlinien.
stripe-colorHintergrundfarbe für abwechselnde Zeilen (im Stil striped).
header-bg-colorHintergrundfarbe der Kopfzeile (im Stil colored-header).
header-text-colorTextfarbe der Kopfzeile (im Stil colored-header).
header-extra-paddingZusätzlicher Innenabstand der Kopfzeile.

Spaltendefinitionen

Jedes <col> definiert eine Tabellenspalte:

AttributBeschreibung
nameSpaltenkennung: id, name, unit, amount, price, vat, vat_sum, total.
labelSpaltenüberschrift (Vorlagenvariablen für Übersetzungen verwenden).
widthSpaltenbreite.
alignTextausrichtung: left, right oder center.

Für umsatzsteuerpflichtige Verkäufer fügen Sie üblicherweise die zusätzlichen Spalten vat und vat_sum ein. Verwenden Sie {{#if vatpayer}}, um sie bedingt anzuzeigen.

Zusammenfassungszeilen

Der Abschnitt <summary> definiert die Summen, die unter der Tabelle angezeigt werden:

<summary>
  {{#if vatpayer}}
    <row label="{{t.invoice.total_without_vat}}" value="{{totalWithoutVat}}" />
    <row label="{{t.invoice.vat}}" value="{{vatTotal}}" />
  {{/if}}
  <row label="{{t.invoice.total}}" value="{{total}}" />
  {{#if alreadyPaid}}
    <row label="{{t.invoice.alreadyPaid}}" value="{{alreadyPaidFormatted}}" />
    <row label="{{t.invoice.sumToPay}}" value="{{sumToPay}}" />
  {{/if}}
</summary>

Vorlagenvariablen

InML verwendet die Handlebars-Syntax für dynamische Inhalte. Variablen werden mit {{variableName}} eingefügt, bedingte Blöcke mit {{#if variableName}}...{{/if}}.

Verfügbare Variablen

Rechnungsdaten

VariableBeschreibung
invoiceTitleAufgelöster Rechnungstitel nach Typ und Umsatzsteuerstatus.
seriesNameName der Rechnungsserie.
seriesIdRechnungsnummer innerhalb der Serie.
formattedDateFormatiertes Rechnungsdatum.
sellerVerkäuferinformationen.
buyerKäuferinformationen.
issuerPerson, die die Rechnung ausgestellt hat.
extraZusätzlicher Informationstext.

Preisfelder

VariableBeschreibung
totalGesamtbetrag der Rechnung (formatiert).
totalWithoutVatGesamtbetrag ohne USt. (formatiert).
vatTotalUSt.-Betrag (formatiert).
alreadyPaidBereits gezahlter Betrag (Zahl, zur Verwendung in {{#if}}).
alreadyPaidFormattedBereits gezahlter Betrag (formatierter String).
sumToPayVerbleibender Zahlbetrag (formatiert).
priceInWordsGesamtpreis in Worten (falls verfügbar).
priceColumnLabelBeschriftung der Preisspalte (ändert sich bei USt.-Pflicht).

Flags

VariableBeschreibung
vatpayertrue, wenn der Verkäufer USt.-pflichtig ist. Mit {{#if vatpayer}}.

Farben

VariableBeschreibung
colors.headerBackgroundHintergrundfarbe der Kopfzeile (Standard #f1f5f9).
colors.primaryAccentPrimäre Akzentfarbe (Standard #238c83).

Bilder

VariableBeschreibung
logoFirmenlogo-Bilddaten. Mit {{#if logo}} verwenden.
logoRatioLogo-Seitenverhältnis (in <logo ratio="...">).
backgroundHintergrundbilddaten. Mit {{#if background}} verwenden.

Übersetzungs-Strings

Alle Oberflächenbeschriftungen sind über das t-Objekt verfügbar. Gängige sind:

VariableBeschreibung
t.invoice.seller„Verkäufer”-Beschriftung
t.invoice.buyer„Käufer”-Beschriftung
t.invoice.no„Nr.”-Beschriftung
t.invoice.total„Gesamt”-Beschriftung
t.invoice.total_without_vat„Gesamt ohne USt.”
t.invoice.vat„USt.”-Beschriftung
t.invoice.lineItemNo„Nr.”-Spaltenkopf
t.invoice.lineItemName„Name”-Spaltenkopf
t.invoice.lineItemUnit„Einheit”-Spaltenkopf
t.invoice.lineItemAmount„Menge”-Spaltenkopf
t.invoice.lineItemPrice„Preis”-Spaltenkopf
t.invoice.lineItemPriceWithoutVAT„Preis (ohne USt.)”
t.invoice.lineItemVat„USt. %“-Spaltenkopf
t.invoice.lineItemVatSum„USt.-Betrag”-Spaltenkopf
t.invoice.lineItemSum„Summe”-Spaltenkopf
t.invoice.alreadyPaid„Bereits gezahlt”
t.invoice.sumToPay„Zu zahlende Summe”
t.invoice.sumInWords„Summe in Worten”
t.invoice.invoiceIssuedBy„Rechnung ausgestellt von”
t.metadata.series„Serie”-Beschriftung

Integrierte Stile

Haiku.lt enthält fünf integrierte Stile, die Sie als Ausgangspunkt verwenden können:

  • minimalist — klares Design mit zentriertem Titel und minimalen Trennern
  • modern-accent — farbige Kopfleiste mit Akzentfarben
  • left-aligned — linksbündiges Layout mit einfacher Struktur
  • bordered — umrandete Tabellenzeilen und -abschnitte
  • split-column — zweispaltiges Layout mit getrennten Verkäufer- und Käuferinformationen

Wählen Sie in den Rechnungseinstellungen einen integrierten Stil aus und wechseln Sie dann zu benutzerdefinierter InML, um ihn als Basis für Ihre Anpassungen zu verwenden.

Vollständiges Beispiel

Hier ist eine vereinfachte Vorlage, die die wichtigsten InML-Konzepte zeigt:

<inml version="1.0" page-size="A4" margin="20mm"
      font-regular="Roboto-Light" font-bold="Roboto-Medium">
  <page>
    {{#if background}}
      <image src="{{background}}" x="0mm" y="0mm" width="210mm" height="297mm" />
    {{/if}}
  </page>
  <layout>
    {{#if logo}}
      <region id="logo" flow="absolute">
        <logo src="{{logo}}" width="50mm" ratio="{{logoRatio}}" />
        <spacer height="10mm" />
      </region>
    {{/if}}

    <region id="title-block" flow="absolute" min-height="40mm">
      <title font="bold" font-size="14" align="center">{{invoiceTitle}}</title>
      <text font="bold" font-size="12" align="center" margin-top="8mm">
        {{t.metadata.series}} {{seriesName}} {{t.invoice.no}} {{seriesId}}
      </text>
      <text font="regular" font-size="12" align="center" margin-top="16mm">
        {{formattedDate}}
      </text>
    </region>

    <region id="parties" flow="sequential" min-height="30mm">
      <columns>
        <column width="50%" align="left">
          <text font="bold" font-size="12">{{t.invoice.seller}}</text>
          <text font="regular" font-size="12" margin-top="5mm">{{seller}}</text>
        </column>
        <column width="50%" align="right">
          <text font="bold" font-size="12">{{t.invoice.buyer}}</text>
          <text font="regular" font-size="12" margin-top="5mm">{{buyer}}</text>
        </column>
      </columns>
    </region>

    <region id="table" flow="sequential" margin-top="20mm">
      <invoice-table row-style="minimal" cell-padding="0mm"
             separator-after-header="true" separator-after-items="true"
             separator-color="#aaaaaa" separator-width="0.5mm">
        <col name="id"     label="{{t.invoice.lineItemNo}}"     width="10mm" align="left" />
        <col name="name"   label="{{t.invoice.lineItemName}}"   width="80mm" align="left" />
        <col name="unit"   label="{{t.invoice.lineItemUnit}}"   width="20mm" align="right" />
        <col name="amount" label="{{t.invoice.lineItemAmount}}" width="20mm" align="right" />
        <col name="price"  label="{{priceColumnLabel}}"         width="20mm" align="right" />
        <col name="total"  label="{{t.invoice.lineItemSum}}"    width="20mm" align="right" />

        <summary>
          <row label="{{t.invoice.total}}" value="{{total}}" />
        </summary>
      </invoice-table>
    </region>

    <region id="footer" flow="sequential">
      {{#if extra}}
        <text font="regular" font-size="12">{{extra}}</text>
        <spacer height="10mm" />
      {{/if}}
      <text font="regular" font-size="12">
        {{t.invoice.invoiceIssuedBy}} {{issuer}}
      </text>
    </region>
  </layout>
</inml>