Leitfaden · REST-API

Ein PDF aus JSON und einer Word-Vorlage generieren

Ihre Daten sind JSON, das Layout ist eine Word-Vorlage mit Standard-Seriendruckfeldern. Ein Aufruf befüllt die Felder, erweitert die wiederholten Tabellen, platziert die Bilder und liefert das fertige PDF oder DOCX.

Warum das PDF nicht im Code bauen

  • Eine PDF-Bibliothek macht das Layout zur Programmieraufgabe; wer das Dokument verantwortet, kann es nicht ändern.
  • Seriendruck braucht Word auf einem Arbeitsplatz und erzeugt eine Datei pro Lauf, nicht eine pro Datensatz aus einer API.
  • Jedes Vorlagenformat mit eigener Syntax bedeutet Umschulung und gebundene Vorlagen.

Die Anfrage

Die Daten reisen als Fields-Envelope: skalare Felder als Name/Wert-Paare, wiederholte Bereiche unter lists, jede Zeile mit eigenen Feldern. Die Namen entsprechen den MERGEFIELD-Codes und der TableStart-Markierung in der Vorlage.

TOKEN=$(curl -sS https://auth.xgenerate.io/realms/xgenerate/protocol/openid-connect/token \
  -d grant_type=client_credentials \
  -d client_id="$XGENERATE_CLIENT_ID" \
  -d client_secret="$XGENERATE_CLIENT_SECRET" | jq -r .access_token)

cat > fields.json <<'JSON'
{
  "fields": [
    { "name": "recipient.name", "value": "Camille Durand" },
    { "name": "invoice.number", "value": "2026-0042" },
    { "name": "invoice.date",   "value": "25.10.2026" }
  ],
  "lists": [
    { "name": "invoice.lines", "value": [
      { "fields": [ { "name": "description", "value": "Consulting, October" },
                    { "name": "amount",      "value": "CHF 4'800.00" } ] },
      { "fields": [ { "name": "description", "value": "Travel expenses" },
                    { "name": "amount",      "value": "CHF 312.40" } ] }
    ] }
  ]
}
JSON

# The Word template carries MERGEFIELD placeholders and a TableStart:invoice.lines region.
curl -sS https://api.xgenerate.io/v2/documents/generate \
  -H "Authorization: Bearer $TOKEN" \
  -F "file=@invoice.docx" \
  -F "fields=@fields.json;type=application/json" \
  -F "format=PDF" \
  -o invoice.pdf

Aus .NET

using System.Net.Http.Json;

using var http = new HttpClient();
http.DefaultRequestHeaders.Authorization = new("Bearer", token);

var request = new
{
    filename = "invoice.docx",
    content = Convert.ToBase64String(await File.ReadAllBytesAsync("invoice.docx")),
    format = "PDF",
    fields = new
    {
        fields = new[]
        {
            new { name = "recipient.name", value = "Camille Durand" },
            new { name = "invoice.number", value = "2026-0042" }
        },
        lists = new[]
        {
            new
            {
                name = "invoice.lines",
                value = new[]
                {
                    new
                    {
                        fields = new[]
                        {
                            new { name = "description", value = "Consulting, October" },
                            new { name = "amount", value = "CHF 4'800.00" }
                        }
                    }
                }
            }
        }
    }
};
var response = await http.PostAsJsonAsync(
    "https://api.xgenerate.io/v2/documents/generate", request);
response.EnsureSuccessStatusCode();

var result = await response.Content.ReadFromJsonAsync<GenerateResult>();
await File.WriteAllBytesAsync(result!.Filename, Convert.FromBase64String(result.Content));

record GenerateResult(string Filename, string Content, string Format);

Die Antwort

Der Multipart-Aufruf streamt das PDF als Rohbytes zurück; der JSON-Transport liefert filename, content, format und warnings. Eine Warnung nennt einen Bild-, QR- oder Briefkopf-Platzhalter ohne Wert, nie eine fehlgeschlagene Anfrage; Seriendruckfelder ohne Daten werden ohne Warnung entfernt.

Das Ergebnis

Erste Seite der gerenderten Referenzrechnung: Briefkopf, Adressblock, Positionstabelle und Summen
Die Referenzrechnung, gerendert aus einer Word-Vorlage mit Standard-Seriendruckfeldern. Vorlage, Anfrage und erwartetes PDF: bereitgestelltes Beispiel

Was XGenerate nicht tut

Daten kommen als Fields-Envelope an (Name/Wert-Paare, Listen, Bilder), nicht als beliebiges JSON. Bedingte Blöcke in Abhängigkeit von einem Datenwert werden nicht unterstützt; Word-IF-Felder um Text schon.

Testen Sie es mit Ihrer eigenen Vorlage

Schicken Sie uns eine Word-Datei, die Sie heute verwenden. Wir rendern sie mit Ihren Daten und senden das PDF zusammen mit der angepassten Vorlage zurück — Ihre Evaluation muss nicht auf uns warten.

Demo anfragen

Verwandte Leitfäden