Exporte
Du exportierst Einträge einer Sammlung im tibi-admin (Verwaltungs-Backend, Release Nova) direkt aus der Liste: als Datei für Tabellenkalkulation, Datenaustausch oder eigene Berichte. Exportiert wird, was du siehst — Filter und Suche der Liste gelten auch für den Export.
Listen-Export
Abschnitt betitelt „Listen-Export“- Liste filtern und sortieren, bis sie zeigt, was du brauchst.
- Export-Knopf über der Liste klicken.
- Format wählen:
JSON,CSVoderXLSX. - Spalten per Checkbox anhaken (Vorauswahl: sichtbare Tabellenspalten;
object[]-Felder erscheinen einmal und werden beim Schreiben aufgefächert). - Herunterladen — der Dateiname enthält Sammlung und Datum.

| Format | Technik | Wofür |
|---|---|---|
JSON |
Rohdatensätze als Datei | Weiterverarbeitung, Sicherung, Import anderswo |
CSV |
Tabellenzeilen aus der xlsx-js-style-Bibliothek |
Excel-, Numbers- oder Skript-Import |
XLSX |
Arbeitsmappe aus derselben Bibliothek (Zell-Stile möglich) | Formatierte Weitergabe an Menschen |
- Große Mengen: Vor dem Laden schätzt der Admin die Trefferzahl über
GET …/<sammlung>/_count(gleicher Filter wie die Liste, Suche als Obergrenze) und warnt dich vor sehr großen Exporten. - Dynamische Spalten: Wachsen Arrays unterschiedlich lang, fragt der Dialog nach, ob er die Spalten auffächern soll — brichst du ab, bleibt der Dialog offen.
Vordefinierte Skript-Exporte
Abschnitt betitelt „Vordefinierte Skript-Exporte“Stehen im Export-Dialog eigene Reiter vor dem Standard-Tab, hat das Projekt fertige Berichte in collection.meta.exports hinterlegt (Name, Datei, optional Dateiname mit {date}-Platzhalter). Ein Klick führt das Skript mit dem aktuellen Listenfilter aus — inklusive Fortschrittsbalken.
# Beispiel-Eintrag in der Sammlungs-Configexports: - name: bestellreport label: { de: "Bestellreport", en: "Order report" } file: "_/exports/reports.mjs" filename: "bestellreport-{date}.xlsx"Eigenes Skript
Abschnitt betitelt „Eigenes Skript“Projekt-Entwickler legen eigene Exporte als ES-Modul unter meta.exports[].file ab (Pfad mit _/…-Präfix = projekt-relativ, empfohlen; daneben /_/…-Alias, /… host-absolut, https://…, data:, blob: und { eval } — gleiche Regeln wie bei der Block-Registry). Das Modul exportiert eine Standard-Funktion, die ctx bekommt und genau ein Ergebnis zurückgibt.
ctx vollständig
Abschnitt betitelt „ctx vollständig“Quelle: frontend/src/lib/utils/custom-export.types.ts:72-102 (einzige Typ-Wahrheit).
| Feld | Inhalt |
|---|---|
api, project, collection |
Config-Kopien in GetMap-Form (lesen ja, ändern sinnlos) |
namespace, $project, $namespace, $method ("export"), context (selbst) |
Wie Server-Hook-jsData — kein $auth (läuft als eingeloggte Admin-Sitzung, Server prüft Rechte) |
export, exportName |
Eigene meta.exports-Zeile bzw. deren name (ein Modul bedient N Exporte) |
view |
Listenzustand: search, searchMode, sortField, sortOrder, manualSort, fieldFilters, subNavFilter, filter (gemischt) |
db.find(coll, opts) |
{ filter, select, selector, sort, offset, limit, lookup } — select exklusiv mit selector (nur 1-Werte, 0 → Fehler); nur sort[0] wird genutzt (REST-Grenze); kein projection |
db.count(coll, { filter }) |
Trefferzahl für Fortschritt und Batch-Planung |
db.loadAll(coll, opts, onProgress?) |
Zählt, lädt in 500er-Paketen (Retry-once pro Batch, Abbruch per signal), meldet pro Batch |
xlsx |
Gebündelte xlsx-js-style-Lib — kein Eigen-Import nötig |
helpers |
deepGet, formatValue, csvCell (Formel-Injektionsschutz: führende =+-@ → '…'), csvWithBom (UTF-8-BOM für Excel-Umlaute) |
lang, languageCodes, defaultLanguage |
i18n |
progress(done, total, label?) |
Schreibt auf die Dialog-Fortschrittsleiste |
signal |
AbortSignal des Abbrechen-Knopfs (fetch wirft AbortError) |
Nur lesend: kein create/update/delete über db.
Rückgabe und Grenzen
Abschnitt betitelt „Rückgabe und Grenzen“| Rückgabe | Inhalt |
|---|---|
workbook |
XLSX-Arbeitsmappe (wird als .xlsx gespeichert) |
blob |
Fertiger Blob (z. B. aus Fremd-Lib) |
text |
Text wie CSV oder HTML |
bytes |
Binärdaten wie PDF (Uint8Array/ArrayBuffer) |
Dazu Pflicht: filename und contentType (z. B. text/csv, application/pdf) — ohne contentType wirft der Admin einen Fehler. Genau ein Payload pro Ergebnis. Dateinamen werden sanitiert (/:*?"<>| → _, {date} → YYYY-MM-DD; custom-export-result.ts:14-18).
// _/exports/reports.mjsexport default async function (ctx) { const rows = await ctx.db.loadAll( "orders", { select: ["orderNo", "total"], filter: ctx.view.filter, sort: [`-${ctx.view.sortField || "orderNo"}`] }, (done, total) => ctx.progress(done, total, "Lade Bestellungen …") ); const lines = [["orderNo", "total"], ...rows.map((r) => [r.orderNo, r.total ?? ""])]; const csv = lines.map((cols) => cols.map((c) => ctx.helpers.csvCell(c)).join(";")).join("\n"); return { text: ctx.helpers.csvWithBom(csv), filename: "bestellreport-{date}.csv", contentType: "text/csv;charset=utf-8" };}Details für Entwickler (Styling per cell.s, Spaltenbreiten, Autofilter) stehen in der Admin-Repo-Doku custom-export-script.md — im Zweifel gilt der Code (utils/load-custom-export.ts, utils/custom-export-context.ts, utils/export.ts).
Häufige Fehler
Abschnitt betitelt „Häufige Fehler“| Fehlerbild | Ursache | Lösung |
|---|---|---|
| Export enthält „falsche“ Einträge | Listenfilter (Reiter, Feld-Filter, Suche) enger als gedacht | Filter in der Liste prüfen — der Export übernimmt sie eins zu eins |
| Spalten-Warnung erscheint | Arrays ungleicher Länge brauchen aufgefächerte Spalten | Auffächern bestätigen oder Spaltenauswahl verkleinern |
| Eigener Reiter fehlt | meta.exports-Eintrag ohne name oder file |
Projekt-Config ergänzen (beide Pflicht), Admin neu laden |
| Skript-Fehler im Dialog | Modul ohne Standard-Export oder Laufzeitfehler | Browser-Konsole lesen, Modul-Export und Rückgabeformat prüfen |
| Leere Datei trotz Treffern | Leserecht auf Zielfelder fehlt | Rechte unter Rechte und Tokens klären |
Verifiziert am 2b091d8 2026-10-17 (tibi-admin-nova); ctx-Tabelle und Beispiel verifiziert am 2b091d8 (custom-export.types.ts:17-102, custom-export-script.md, custom-export-result.ts:14-18)