Jetzt kostenlos testen!

FriTTo + Excel: Zeitdaten auf Knopfdruck mit Office Scripts exportieren

Erfahren Sie alles über moderne Zeiterfassung, Produktivität und die neuesten Trends in der Arbeitswelt.

Zurück zur Übersicht
Effizienz Excel

FriTTo + Excel: Zeitdaten auf Knopfdruck mit Office Scripts exportieren

Warum Excel nach wie vor unverzichtbar ist

Ihr Team erfasst die Arbeitszeit in FriTTo. Die Buchhaltung arbeitet mit Excel. Und Ihre Projektmanager bauen sich ihre Pivot-Tabellen zusammen. Kommt Ihnen das bekannt vor? Egal, wie leistungsfähig Ihre Zeiterfassungsplattform ist — die Daten müssen dort ankommen, wo Ihre Mitarbeiter tatsächlich arbeiten. Und für die meisten Unternehmen ist das nach wie vor Microsoft Excel.

Genau deshalb haben wir FriTTo von Anfang an API-first gebaut. Statt Sie in unser Berichtsformat zu zwingen, geben wir Ihnen die Werkzeuge, um Ihre Daten in jede beliebige Umgebung zu ziehen.

Heute zeigen wir Ihnen, wie Sie FriTTo direkt mit Excel verbinden — per Office Scripts, ohne technische Umwege, manuelle Exporte oder Copy-Paste-Marathons.

Was Sie erhalten

Wir haben eine fertige Excel-Vorlage mit integriertem Office Script vorbereitet, das die FriTTo-API aufruft und Ihre Tabelle automatisch befüllt. Das steckt drin:

  • Blatt — Einstellungen — tragen Sie Ihre API-URL, den Zeitraum und Ihren API-Schlüssel ein. Mehr Konfiguration brauchen Sie nicht.
  • Blatt — Daten — nach dem Ausführen des Scripts erscheinen hier Ihre Zeiteinträge mit allen Details: Datum, Kunde, Projekt, Beschreibung, erfasste Minuten, Abrechenbarkeit, Genehmigungsstatus, Mitarbeiterinformationen und Kostensätze.
  • Office Script (TypeScript) — ein schlankes Script, das Ihre Einstellungen liest, die FriTTo REST API aufruft und die Ergebnisse direkt in Excel schreibt. Automatisch formatierte Überschriften, optimierte Spaltenbreiten und aktivierter Autofilter.

So funktioniert’s: Schritt für Schritt

Schritt 1: Vorlage öffnen

Laden Sie die FriTTo Export Vorlage herunter und öffnen Sie Excel in der Web oder Desktop Version (Microsoft 365 erforderlich für Office Scripts).

Schritt 2: Einstellungen konfigurieren

Füllen Sie auf dem Einstellungen-Blatt vier Felder aus:

  • API-Basis-URL — die URL ist bereits vorausgefüllt: https://api.steinpilz-fritto.de. Hier müssen Sie nichts ändern.
  • VON Datum — Beginn des Exportzeitraums.
  • BIS Datum — Ende des Zeitraums.
  • API-Schlüssel — Ihr persönlicher API-Schlüssel aus FriTTo (siehe unten, wie Sie einen erstellen).

Schritt 3: API-Schlüssel in FriTTo erstellen

Melden Sie sich in FriTTo an und klicken Sie oben rechts auf Ihr Profilsymbol. Scrollen Sie nach unten zum Bereich Persönliche API Tokens und klicken Sie auf API Token hinzufügen. Vergeben Sie einen Namen (z.B. „excel“), legen Sie ein Ablaufdatum fest und kopieren Sie den generierten Schlüssel. Fügen Sie ihn auf dem Einstellungen-Blatt in das Feld API-Schlüssel ein — fertig.

Wichtig: Der Datenexport steht nur Benutzern mit einer der folgenden Rollen zur Verfügung: Administrator, Department Manager, Manager oder Reviewer. Ob Sie die nötige Berechtigung haben, erkennen Sie daran, dass im Menü der Punkt Berichte → Alle Zeitberichte sichtbar ist.

Schritt 4: Script hinzufügen

Gehen Sie zum Reiter Automatisieren im Excel-Menüband, klicken Sie auf Neues Skript und wählen Sie Im Code-Editor erstellen aus. Ersetzen Sie den angezeigten Code vollständig mit dem folgenden Script:

/**
 * Fritto Export — Office Script (TypeScript) — Deutsche Version
 *
 * Liest Einstellungen vom Blatt "Einstellungen", ruft die TimeTracker-API auf
 * und füllt das Blatt "Daten" mit den exportierten Zeiteinträgen.
 *
 * Verwendung:
 *   1. Öffnen Sie die Excel-Datei in Excel für das Web oder Excel Desktop (Microsoft 365)
 *   2. Gehen Sie zum Reiter "Automatisieren"
 *   3. Klicken Sie auf "Neues Skript", fügen Sie diesen Code ein und speichern Sie
 *   4. Füllen Sie das Blatt "Einstellungen" aus und klicken Sie im Skript-Editor auf "Ausführen"
 */

async function main(workbook: ExcelScript.Workbook): Promise<void> {
    const settingsSheet = workbook.getWorksheet("Einstellungen");
    if (!settingsSheet) {
        throw new Error("Blatt 'Einstellungen' nicht gefunden.");
    }

    // Eingaben lesen
    const apiUrl = toString(settingsSheet.getRange("B1").getValue()).trim();
    const fromDate = formatDateValue(settingsSheet.getRange("B2").getValue());
    const toDate = formatDateValue(settingsSheet.getRange("B3").getValue());
    const apiKey = toString(settingsSheet.getRange("B4").getValue()).trim();

    // Validierung
    if (!apiUrl) throw new Error("API-Basis-URL ist erforderlich.");
    if (!fromDate) throw new Error("VON Datum ist erforderlich.");
    if (!toDate) throw new Error("BIS Datum ist erforderlich.");
    if (fromDate > toDate) throw new Error("VON Datum muss vor oder gleich dem BIS Datum liegen.");
    if (!apiKey) throw new Error("API-Schlüssel fehlt.");

    // Anfrage-URL erstellen
    const baseUrl = apiUrl.replace(/\/+$/, "");
    const requestUrl = `${baseUrl}/api/app/export-to-excel?From=${fromDate}&To=${toDate}`;

    // Daten von API abrufen
    console.log(`Daten werden abgerufen von: ${requestUrl}`);

    const response = await fetch(requestUrl, {
        method: "GET",
        headers: {
            "X-Api-Key": apiKey,
            "Accept": "application/json",
        },
    });

    if (!response.ok) {
        const body = await response.text();
        switch (response.status) {
            case 400:
                throw new Error(`Ungültige Anfrage (HTTP 400). Details: ${body.substring(0, 300)}`);
            case 401:
                throw new Error("Authentifizierung fehlgeschlagen. Bitte überprüfen Sie Ihren API-Schlüssel.");
            case 403:
                throw new Error("Zugriff verweigert. Ihr API-Schlüssel hat keine Berechtigung für diese Daten.");
            case 404:
                throw new Error("API-Endpunkt nicht gefunden. Bitte überprüfen Sie die API-Basis-URL.");
            default:
                throw new Error(`Serverfehler (HTTP ${response.status}). Bitte versuchen Sie es später erneut.`);
        }
    }

    const result: { items: ExportEntry[] } = await response.json();
    const items = result.items;

    // Daten-Blatt befüllen
    const dataSheet = workbook.getWorksheet("Daten");
    if (!dataSheet) {
        throw new Error("Blatt 'Daten' nicht gefunden.");
    }

    // Vorhandene Daten löschen
    const usedRange = dataSheet.getUsedRange();
    if (usedRange) {
        usedRange.clear();
    }

    // Vorhandenen Auto-Filter entfernen
    const existingFilter = dataSheet.getAutoFilter();
    if (existingFilter.getIsDataFiltered()) {
        existingFilter.remove();
    }

    if (items.length === 0) {
        console.log("Keine Daten für den angegebenen Zeitraum gefunden.");
        return;
    }

    // Spaltenüberschriften
    const headers = [
        "Datum", "Kunde", "Projekt", "Beschreibung", "Aufgaben-URL",
        "Erfasste Minuten", "Abrechenbar?", "Genehmigt?",
        "Vorname", "Nachname", "Mitarbeitergruppen", "Kostensatz", "Währung",
    ];

    // Überschriften schreiben
    const headerRange = dataSheet.getRangeByIndexes(0, 0, 1, headers.length);
    headerRange.setValues([headers]);
    headerRange.getFormat().getFont().setBold(true);
    headerRange.getFormat().getFill().setColor("#4472C4");
    headerRange.getFormat().getFont().setColor("#FFFFFF");
    headerRange.getFormat().setRowHeight(30);

    // Datenzeilen erstellen
    const rows: (string | number)[][] = items.map((item) => [
        item.date ?? "",
        item.client ?? "",
        item.project ?? "",
        item.description ?? "",
        item.taskUrl ?? "",
        item.trackedMinutes ?? 0,
        item.isBillable ? "Ja" : "Nein",
        item.isApproved ? "Ja" : "Nein",
        item.firstName ?? "",
        item.lastName ?? "",
        item.employeeGroups ?? "",
        item.costRate ?? "",
        item.currency ?? "",
    ]);

    // Daten schreiben
    const dataRange = dataSheet.getRangeByIndexes(1, 0, rows.length, headers.length);
    dataRange.setValues(rows);

    // Spaltenbreite automatisch anpassen
    dataSheet.getUsedRange()?.getFormat().autofitColumns();

    // Auto-Filter anwenden
    dataSheet.getAutoFilter().apply(dataSheet.getUsedRange());

    console.log(`${items.length} Einträge erfolgreich exportiert.`);
}

/** Excel-Zellwert (String, Zahl oder Datumsseriennummer) in yyyy-mm-dd String umwandeln. */
function formatDateValue(value: string | number | boolean): string {
    if (value === null || value === undefined || value === "") return "";

    if (typeof value === "number") {
        // Excel-Datumsseriennummer -> yyyy-mm-dd
        const date = new Date(Math.round((value - 25569) * 86400 * 1000));
        const y = date.getUTCFullYear();
        const m = String(date.getUTCMonth() + 1).padStart(2, "0");
        const d = String(date.getUTCDate()).padStart(2, "0");
        return `${y}-${m}-${d}`;
    }

    return value.toString().trim();
}

/** Zellwert sicher in String umwandeln. */
function toString(value: string | number | boolean): string {
    if (value === null || value === undefined) return "";
    return value.toString();
}

interface ExportEntry {
    date: string;
    client: string;
    project: string;
    description: string;
    taskUrl: string;
    trackedMinutes: number;
    isBillable: boolean;
    isApproved: boolean;
    userId: string;
    firstName: string;
    lastName: string;
    employeeGroups: string;
    costRate: number | null;
    currency: string | null;
}

Tipp: Nach dem Speichern klicken Sie auf die drei Punkte und wählen Sie + In Arbeitsmappe hinzufügen aus, um einen praktischen Ausführen-Button direkt in Ihre Tabelle einzufügen.

Schritt 5: Ausführen

Klicken Sie auf Ausführen — entweder im Office Script-Editor auf dem Button Ausführen oder über den grünen Button Ausführen auf dem Datenblatt, das Sie im vorherigen Schritt hinzugefügt haben. Das Script ruft Ihre Zeiteinträge über die FriTTo-API ab und füllt das Daten-Blatt. Überschriften werden formatiert, Spalten automatisch angepasst und Filter aktiviert. Ihre Daten sind nun bereit zur Analyse.

Was Sie mit den Daten machen können

Sobald Ihre Zeiteinträge in Excel sind, stehen Ihnen alle Möglichkeiten offen:

  • Pivot-Tabellen — abrechenbare Stunden nach Kunde, Projekt oder Teammitglied in Sekunden aufschlüsseln.
  • Kostenanalyse — erfasste Minuten mit Kostensätzen kombinieren und die Projektrentabilität berechnen.
  • Kundenabrechnung — nach Kunde und Zeitraum filtern und in Ihren Billing-Workflow exportieren.
  • Genehmigungsverfolgung — auf einen Blick sehen, welche Einträge genehmigt sind und welche noch ausstehen.
  • Geplante Aktualisierung — das Office Script mit Power Automate kombinieren und den Export automatisch ausführen — täglich, wöchentlich oder monatlich.

Warum das wichtig ist

Die meisten Zeittracker bieten bestenfalls einen CSV-Export — einen einmaligen, manuellen Prozess, der nicht mehr funktioniert, sobald sich Ihre Daten ändern. Mit der FriTTo-API und Office Scripts erhalten Sie eine direkte Verbindung zwischen Ihren Zeiterfassungsdaten und Ihrer Tabelle. Zeitraum anpassen, Ausführen klicken — und Sie haben in Sekunden aktuelle Daten.

Das ist API-first in der Praxis: Ihre Daten, Ihr Format, Ihr Workflow — ohne Kompromisse.

Erfahren Sie mehr über Fritto – fundierte Einblicke, praxisnahe Tipps und moderne Lösungen für eine effiziente Zeiterfassung.

Bereits über 12.000+ aktive Nutzer setzen auf smarte Zeiterfassung – jetzt sind Sie dran!

Schöpfen Sie das volle Potenzial Ihrer Zeit mit unserem benutzerfreundlichen Zeiterfassungstool aus. Verfolgen Sie Ihre Projekte, überwachen Sie Ihre Arbeitszeit und steigern Sie Ihre Effizienz mit nur wenigen Klicks.
Probieren Sie Fritto kostenlos aus