Direkt zum Hauptinhalt

Neue Seite

Hauptmerkmale

  • Automatisierte Datenübernahme: Cron-basierte Planung für wiederkehrende Importprozesse
  • Flexible Dateibeobachtung: Überwacht konfigurierbare Ordner mit Wildcard-Mustern
  • Intelligente Datenverarbeitung: Unterstützt Zeilenfilterung, Spaltenfüllung und bedingte Löschung
  • Dynamische Tabellenerstellung: Erstellt Datenbank-Tabellen und -Spalten automatisch
  • Multi-Format-Unterstützung: Verarbeitet Excel-Dateien in den Formaten .xlsx und .xls
  • Umfassendes Logging: Serilog-basierte Protokollierung mit konfigurierbaren Ausgabezielen
  • Subfolder-Unterstützung: Rekursive Verzeichnissuche bei Bedarf
  • Bulk-Import: Hochperformante Datenübernahme mittels SqlBulkCopy
  • Flexible Deployment-Optionen: Windows-Service, Standalone-Anwendung oder Docker-Container

🏗️ Architektur

Komponenten-Übersicht

ExcelDataImporter
├── Program.cs                    # Einstiegspunkt und Service-Konfiguration
├── ImportJobWorker.cs            # Job-Verwaltung und -Ausführung
├── TimedHostedService.cs         # Basis-Klasse für zeitgesteuerte Services
├── ImportSettings.cs             # Konfigurationsmodell für Import-Jobs
├── MissingSettingException.cs    # Exception für fehlende Konfigurationen
└── Daten/
    ├── Importer.cs               # SQL-Datenbank-Import-Logik
    └── ExcelImporter.cs          # Excel-Datei-Verarbeitung

Architektur-Diagramm

┌─────────────────────────────────────────────────────────────┐
│                      ExcelDataImporter                       │
├─────────────────────────────────────────────────────────────┤
│                                                               │
│  ┌──────────────┐    ┌─────────────────┐                    │
│  │  Program.cs  │───▶│ Configuration   │                    │
│  └──────────────┘    └─────────────────┘                    │
│         │                      │                             │
│         ▼                      ▼                             │
│  ┌───────────────────────────────────┐                      │
│  │     ImportJobWorker (n Jobs)      │                      │
│  │   extends TimedHostedService      │                      │
│  └───────────────────────────────────┘                      │
│         │                                                     │
│         ├────────────┬─────────────────┐                    │
│         ▼            ▼                 ▼                     │
│  ┌────────────┐ ┌──────────────┐ ┌──────────┐              │
│  │   Cron     │ │ExcelImporter │ │ Importer │              │
│  │  Scheduler │ │  (DevExpress)│ │ (SqlBulk)│              │
│  └────────────┘ └──────────────┘ └──────────┘              │
│                      │                  │                    │
│                      ▼                  ▼                    │
│              ┌──────────────┐    ┌───────────┐              │
│              │ Excel-Dateien│    │ SQL Server│              │
│              └──────────────┘    └───────────┘              │
└─────────────────────────────────────────────────────────────┘

Technologie-Stack

Komponente Technologie Version Zweck
Runtime .NET 10.0 Basis-Framework
Service-Host Microsoft.Extensions.Hosting 10.0.0 Background-Worker-Hosting
Windows-Service Microsoft.Extensions.Hosting.WindowsServices 10.0.0 Windows-Service-Integration
Logging Serilog 4.3.0 Strukturiertes Logging
Excel-Verarbeitung DevExpress.Document.Processor 25.1.7 Excel-Datei-Parsing
Datenbank Microsoft.Data.SqlClient 6.1.3 SQL Server-Verbindung
Scheduling NCrontab 3.4.0 Cron-basierte Zeitplanung
ORM DevExpress.Xpo 25.1.7 Object-Relational Mapping

💻 Systemvoraussetzungen

Mindestanforderungen

  • Betriebssystem: Windows Server 2016+ / Windows 10+ oder Linux mit .NET 10.0 Runtime
  • .NET Runtime: .NET 10.0 oder höher
  • Datenbank: Microsoft SQL Server 2016+ (Express, Standard, Enterprise)
  • Speicher: Mindestens 512 MB RAM (abhängig von der Dateigröße)
  • Festplatte: 100 MB für die Anwendung + Speicherplatz für Logs und temporäre Dateien

Empfohlene Anforderungen

  • Betriebssystem: Windows Server 2022 oder neuere Linux-Distribution
  • .NET Runtime: .NET 10.0
  • Datenbank: Microsoft SQL Server 2019+ mit ausreichender Speicherkapazität
  • Speicher: 2 GB RAM oder mehr
  • Festplatte: SSD mit mindestens 1 GB freiem Speicherplatz

Netzwerk

  • Zugriff auf den SQL Server (Standard-Port 1433 oder konfigurierter Port)
  • Zugriff auf die zu überwachenden Ordner (lokal oder Netzwerkfreigabe)
  • Schreibrechte für Log-Verzeichnis

📦 Installation

Option 1: Windows-Service-Installation

Schritt 1: Anwendung vorbereiten

# Repository klonen
git clone https://github.com/CSS-EDV-Support/ExcelDataImporter.git
cd ExcelDataImporter

# Projekt kompilieren
dotnet publish ExcelDataImporter/ExcelDataImporter.csproj -c Release -o C:\Services\ExcelDataImporter

Schritt 2: appsettings.json konfigurieren

Navigieren Sie zuzum C:\Services\ExcelDataImporterProgrammverzeichnis und bearbeiten Sie die appsettings.json (siehe Abschnitt Konfiguration).

Schritt 3:2: Windows-Service erstellen

# PowerShell als Administrator ausführen
sc.exe create ExcelDataImporter binPath="C:\Services\ExcelDataImporter\ExcelDataImporter.exe" start=auto
sc.exe description ExcelDataImporter "Automatisierter Excel-Datenimport-Service"
sc.exe start ExcelDataImporter

Schritt 4:3: Service überprüfen

# Service-Status prüfen
sc.exe query ExcelDataImporter

# Logs überprüfen
Get-Content C:\Services\ExcelDataImporter\Logs\log.txt -Tail 50 -Wait

Option 2: Standalone-Anwendung

# Anwendung starten
cd C:\Path\To\ExcelDataImporter
dotnet ExcelDataImporter.dll

Option 3: Docker-Container

Schritt 1: Docker-Image erstellen

# Im Repository-Verzeichnis
docker build -t exceldataimporter:latest -f ExcelDataImporter/Dockerfile .

Schritt 2: Container starten

# Mit Volume-Mapping für Konfiguration, Logs und Datenordner
docker run -d \
  --name exceldataimporter \
  -v /path/to/config:/app/config \
  -v /path/to/logs:/app/Logs \
  -v /path/to/data:/data \
  exceldataimporter:latest

Schritt 3: Container-Logs überwachen

docker logs -f exceldataimporter

Deinstallation

Windows-Service entfernen

# Service stoppen und entfernen
sc.exe stop ExcelDataImporter
sc.exe delete ExcelDataImporter

# Optional: Dateien löschen
Remove-Item -Recurse -Force C:\Services\ExcelDataImporter

⚙️ Konfiguration

appsettings.json - Struktur

Die Konfiguration erfolgt vollständig über die appsettings.json-Datei:

{
    "Serilog": {
        "Using": [
            "Serilog.Sinks.Console",
            "Serilog.Sinks.File"
        ],
        "MinimumLevel": "Debug",
        "WriteTo": [
            {
                "Name": "Console",
                "Args": {
                    "theme": "Serilog.Sinks.SystemConsole.Themes.AnsiConsoleTheme::Code, Serilog.Sinks.Console"
                }
            },
            {
                "Name": "File",
                "Args": {
                    "path": "Logs/log.txt",
                    "rollingInterval": "Day",
                    "retainedFileCountLimit": 7
                }
            }
        ],
        "Properties": {
            "Application": "ExcelDataImporter"
        }
    },
    "Logging": {
        "LogLevel": {
            "Default": "Information",
            "Microsoft.Hosting.Lifetime": "Information"
        },
        "EventLog": {
            "SourceName": "ExcelImportService",
            "LogName": "Application",
            "LogLevel": {
                "Microsoft": "Information",
                "Microsoft.Hosting.Lifetime": "Information"
            }
        }
    },
    "ImportJobs": [
        {
            "JobName": "DailyProductImport",
            "CronExpression": "0 2 * * *",
            "Pfad": "C:\\Import\\Products",
            "ExcelFilePattern": "Products_*.xlsx",
            "DestinationTable": "ProductData",
            "CreateDateOfImportColumn": true,
            "NameOfImportDateColumn": "ImportDate",
            "TruncateDestinationTable": true,
            "ExcelFormat": "xlsx",
            "RemoveRows": 1,
            "FillEmptyColumns": [0, 2],
            "RemoveRowIfColumnIsEmpty": 0,
            "IncludeSubfolders": true,
            "ConnectionString": "Server=localhost;Database=ImportDB;User Id=sa;Password=YourPassword;TrustServerCertificate=True;"
        }
    ],
    "connectionStrings": {
        "ConnectionString": "Server=localhost;Database=ImportDB;User Id=sa;Password=YourPassword;TrustServerCertificate=True;"
    }
}

Import-Job-Konfiguration

Pflichtfelder

Parameter Typ Beschreibung Beispiel
JobName string Eindeutiger Name des Import-Jobs "DailyProductImport"
Pfad string Quellverzeichnis für Excel-Dateien "C:\\Import\\Products"
ExcelFilePattern string Suchmuster für Dateien (Wildcards erlaubt) "Products_*.xlsx"
DestinationTable string Ziel-Tabelle in der Datenbank "ProductData"

Optionale Felder

Parameter Typ Standard Beschreibung
CronExpression string "* * * * *" Cron-Ausdruck für Zeitplanung (jede Minute)
CreateDateOfImportColumn bool false Erstellt eine Spalte für das Importdatum
NameOfImportDateColumn string null Name der Import-Datumsspalte
TruncateDestinationTable bool false Leert die Zieltabelle vor dem Import
ExcelFormat string "xlsx" Excel-Format: "xlsx" oder "xls"
RemoveRows int? null Anzahl der zu entfernenden Zeilen am Anfang
FillEmptyColumns int[]? null Spaltenindizes für Forward-Fill (0-basiert)
RemoveRowIfColumnIsEmpty int? null Entfernt Zeilen, wenn angegebene Spalte leer ist
IncludeSubfolders bool false Durchsucht Unterverzeichnisse
ConnectionString string? null Job-spezifischer Connection String (überschreibt global)

Cron-Ausdrücke

Cron-Ausdrücke steuern die Ausführungszeit der Import-Jobs. Format: Minute Stunde Tag Monat Wochentag

Beispiele

Cron-Ausdruck Beschreibung
* * * * * Jede Minute
0 * * * * Jede Stunde
0 2 * * * Täglich um 2:00 Uhr
0 2 * * 1-5 Werktags um 2:00 Uhr
0 */4 * * * Alle 4 Stunden
0 0 1 * * Am ersten Tag des Monats um Mitternacht
30 6 * * 1 Jeden Montag um 6:30 Uhr

Hinweis: Nutzen Sie Online-Tools wie crontab.guru zur Validierung.

Logging-Konfiguration

Log-Level

Level Verwendung
Trace Sehr detaillierte Informationen (Entwicklung)
Debug Detaillierte Ablauf-Informationen
Information Allgemeine Informationen über Systemverhalten
Warning Warnungen bei potenziellen Problemen
Error Fehler, die das System weiterhin betreiben lassen
Fatal Kritische Fehler, die das System zum Absturz bringen

Log-Ausgabeziele

Die Standardkonfiguration schreibt Logs in:

  • Konsole: Für interaktive Anwendungsausführung
  • Datei: Logs/log.txt mit täglichem Rollover und 7-Tage-Aufbewahrung

Weitere Serilog-Sinks können hinzugefügt werden (z. B. EventLog, SQL Server, Elasticsearch).

Connection Strings

Globaler Connection String

"connectionStrings": {
    "ConnectionString": "Server=localhost;Database=ImportDB;User Id=sa;Password=YourPassword;TrustServerCertificate=True;"
}

Job-spezifischer Connection String

Überschreibt den globalen Connection String für einen bestimmten Job:

{
    "JobName": "SpecialImport",
    "ConnectionString": "Server=server2;Database=SpecialDB;Integrated Security=True;",
    ...
}

Konfigurationsbeispiele

Beispiel 1: Einfacher täglicher Import

{
    "JobName": "DailySalesImport",
    "CronExpression": "0 6 * * *",
    "Pfad": "\\\\fileserver\\Import\\Sales",
    "ExcelFilePattern": "Sales_*.xlsx",
    "DestinationTable": "SalesData",
    "TruncateDestinationTable": true,
    "CreateDateOfImportColumn": true,
    "NameOfImportDateColumn": "ImportTimestamp"
}

Beispiel 2: Stündlicher Import mit Datenbereinigung

{
    "JobName": "HourlyInventoryUpdate",
    "CronExpression": "0 * * * *",
    "Pfad": "C:\\Data\\Inventory",
    "ExcelFilePattern": "inventory_*.xlsx",
    "DestinationTable": "Inventory",
    "TruncateDestinationTable": false,
    "RemoveRows": 2,
    "FillEmptyColumns": [0, 1, 3],
    "RemoveRowIfColumnIsEmpty": 0,
    "IncludeSubfolders": true
}

Beispiel 3: Multi-Job-Setup

{
    "ImportJobs": [
        {
            "JobName": "MorningProductSync",
            "CronExpression": "0 6 * * *",
            "Pfad": "C:\\Import\\Products",
            "ExcelFilePattern": "*.xlsx",
            "DestinationTable": "Products",
            "TruncateDestinationTable": true
        },
        {
            "JobName": "EveningCustomerSync",
            "CronExpression": "0 18 * * *",
            "Pfad": "C:\\Import\\Customers",
            "ExcelFilePattern": "*.xlsx",
            "DestinationTable": "Customers",
            "TruncateDestinationTable": true
        },
        {
            "JobName": "HourlyOrderCheck",
            "CronExpression": "0 * * * *",
            "Pfad": "C:\\Import\\Orders",
            "ExcelFilePattern": "orders_*.xlsx",
            "DestinationTable": "Orders",
            "TruncateDestinationTable": false,
            "CreateDateOfImportColumn": true,
            "NameOfImportDateColumn": "OrderImportDate"
        }
    ]
}

🚀 Verwendung

Grundlegender Workflow

  1. Konfiguration erstellen: appsettings.json mit Import-Jobs konfigurieren
  2. Service starten: Windows-Service, Standalone oder Docker
  3. Dateien bereitstellen: Excel-Dateien in die konfigurierten Verzeichnisse legen
  4. Automatische Verarbeitung: Jobs werden gemäß Cron-Zeitplan ausgeführt
  5. Monitoring: Logs überprüfen und Datenbank-Einträge validieren

Excel-Datei-Anforderungen

Unterstützte Formate

  • .xlsx (Office Open XML)
  • .xls (Excel 97-2003)

Dateistruktur

  • Erste Zeile: Standardmäßig als Spaltennamen verwendet
  • Datenzeilen: Ab der zweiten Zeile (anpassbar mit RemoveRows)
  • Mehrere Arbeitsblätter: Nur das erste Arbeitsblatt wird verarbeitet

Beispiel-Excel-Struktur

ProductID ProductName Category Price Stock
1001 Laptop Electronics 999.99 50
1002 Mouse Accessories 19.99 200
1003 Keyboard Accessories 49.99 150

Datenbank-Interaktion

Automatische Tabellenerstellung

Wenn die Zieltabelle nicht existiert, wird sie automatisch erstellt:

// Die Tabelle wird basierend auf der Excel-Struktur generiert
// Spaltentypen werden automatisch erkannt:
// - Int32 → INT
// - String → NVARCHAR(MAX)
// - DateTime → DATETIME
// - Float → FLOAT

Bulk-Insert

Daten werden mit SqlBulkCopy hochperformant importiert:

// Beispiel für einen Import von 10.000 Zeilen:
// - Durchschnittliche Dauer: < 5 Sekunden
// - Speicherverbrauch: Minimal durch Streaming

Erweiterte Features

1. Spaltenfüllung (FillEmptyColumns)

Füllt leere Zellen mit dem letzten nicht-leeren Wert in der Spalte:

Vor der Füllung:

Region Product Sales
North Product A 100
Product B 150
Product C 200
South Product D 120

Nach der Füllung (FillEmptyColumns: [0]):

Region Product Sales
North Product A 100
North Product B 150
North Product C 200
South Product D 120

2. Bedingte Zeilenentfernung (RemoveRowIfColumnIsEmpty)

Entfernt Zeilen, bei denen eine bestimmte Spalte leer ist:

Vor der Filterung:

ID Name Email
1 John [email protected]
2
3 Jane [email protected]

Nach der Filterung (RemoveRowIfColumnIsEmpty: 1):

ID Name Email
1 John [email protected]
3 Jane [email protected]

3. Zeilen entfernen (RemoveRows)

Entfernt die ersten n Zeilen (z. B. Überschriften oder Zusammenfassungen):

{
    "RemoveRows": 2  // Entfernt die ersten 2 Zeilen
}

4. Subfolder-Suche (IncludeSubfolders)

Durchsucht rekursiv alle Unterverzeichnisse:

Import/
├── 2024/
│   ├── January/
│   │   └── products_jan.xlsx  ✓ Wird gefunden
│   └── February/
│       └── products_feb.xlsx  ✓ Wird gefunden
└── Archive/
    └── products_old.xlsx      ✓ Wird gefunden

Bei IncludeSubfolders: false würden nur Dateien direkt in Import/ gefunden werden.

5. Importdatum-Spalte

Fügt automatisch eine Spalte mit dem Import-Zeitstempel hinzu:

-- Generierte Tabelle mit Importdatum
CREATE TABLE ProductData (
    ProductID INT,
    ProductName NVARCHAR(MAX),
    Price FLOAT,
    ImportDate DATETIME DEFAULT(GETDATE())
);

🔄 Import-Prozess

Detaillierter Ablauf

1. Job-Start (Cron-Trigger)
   │
   ├─▶ 2. Verzeichnis-Scan
   │    ├─ Pfad validieren
   │    ├─ Dateimuster anwenden
   │    └─ Neueste Datei pro Verzeichnis ermitteln
   │
   ├─▶ 3. Excel-Datei-Verarbeitung
   │    ├─ Temporäre Kopie erstellen
   │    ├─ Datei laden (DevExpress)
   │    ├─ Erstes Arbeitsblatt auswählen
   │    ├─ Optionale Zeilen entfernen (RemoveRows)
   │    ├─ Spaltenfüllung anwenden (FillEmptyColumns)
   │    ├─ Zeilenfilterung (RemoveRowIfColumnIsEmpty)
   │    └─ DataTable generieren
   │
   ├─▶ 4. Datenbank-Vorbereitung
   │    ├─ Connection-String abrufen
   │    ├─ Verbindung öffnen
   │    ├─ Tabelle erstellen (falls nicht vorhanden)
   │    ├─ Importdatum-Spalte hinzufügen (optional)
   │    └─ Tabelle leeren (optional, TruncateDestinationTable)
   │
   ├─▶ 5. Daten-Import
   │    ├─ SqlBulkCopy konfigurieren
   │    ├─ Spaltenmapping (automatisch)
   │    └─ Bulk-Insert ausführen
   │
   └─▶ 6. Abschluss
        ├─ Anzahl importierter Datensätze loggen
        ├─ Temporäre Dateien löschen
        ├─ Verbindung schließen
        └─ Nächste Ausführung planen

Fehlerbehandlung

Der Service implementiert umfassende Fehlerbehandlung auf allen Ebenen:

  1. Konfigurationsfehler: MissingSettingException bei fehlenden Pflichtfeldern
  2. Dateisystemfehler: DirectoryNotFoundException, FileNotFoundException
  3. Excel-Verarbeitungsfehler: Detailliertes Logging mit Dateinamen
  4. Datenbankfehler: SQL-Exceptions werden geloggt, Service läuft weiter
  5. Cron-Fehler: Ungültige Ausdrücke werden beim Start erkannt

Performance-Überlegungen

Szenario Dateigröße Zeilen Durchschnittliche Dauer
Klein < 1 MB < 1.000 < 1 Sekunde
Mittel 1-10 MB 1.000-10.000 1-5 Sekunden
Groß 10-50 MB 10.000-50.000 5-30 Sekunden
Sehr groß > 50 MB > 50.000 > 30 Sekunden

Optimierungen:

  • Bulk-Insert statt einzelner Inserts
  • Temporäre Dateikopie zur Vermeidung von Locking
  • Streaming-basierte Verarbeitung
  • Minimaler Memory-Footprint

🔧 Troubleshooting

Häufige Probleme und Lösungen

Problem 1: Service startet nicht

Symptom:

Der Dienst "ExcelDataImporter" auf dem lokalen Computer wurde gestartet und dann beendet.

Mögliche Ursachen:

  • Ungültige appsettings.json
  • Fehlende .NET 10.0 Runtime
  • Ungültige Cron-Ausdrücke

Lösung:

# Logs überprüfen
Get-Content C:\Services\ExcelDataImporter\Logs\log.txt -Tail 100

# Manuelle Ausführung zum Debuggen
cd C:\Services\ExcelDataImporter
.\ExcelDataImporter.exe

# .NET Runtime überprüfen
dotnet --list-runtimes

Problem 2: Keine Dateien gefunden

Symptom:

Keine Dateien mit dem Suchmuster *.xlsx in Pfad C:\Import gefunden.

Mögliche Ursachen:

  • Falscher Pfad
  • Falsches Dateimuster
  • Fehlende Dateiberechtigungen

Lösung:

# Pfad und Dateien überprüfen
Get-ChildItem "C:\Import" -Filter "*.xlsx"

# Berechtigungen prüfen
icacls "C:\Import"

# Service-Account benötigt Leserechte auf den Ordner
# Für Windows-Service: Meist "NT AUTHORITY\LOCAL SERVICE"

Problem 3: Datenbankverbindung schlägt fehl

Symptom:

Fehler beim Importieren aus Pfad C:\Import
Exception: A network-related or instance-specific error occurred...

Mögliche Ursachen:

  • SQL Server nicht erreichbar
  • Falscher Connection String
  • Firewall blockiert Port 1433

Lösung:

# SQL Server-Verbindung testen
Test-NetConnection -ComputerName localhost -Port 1433

# Connection String validieren
# Testen mit sqlcmd oder SQL Server Management Studio

Connection String debuggen:

// Beispiel mit detaillierten Optionen
{
    "ConnectionString": "Server=localhost,1433;Database=ImportDB;User Id=sa;Password=YourPassword;TrustServerCertificate=True;Connect Timeout=30;Encrypt=False;"
}

Problem 4: Excel-Datei kann nicht geöffnet werden

Symptom:

Fehler beim Importieren der Datei C:\Import\data.xlsx
Exception: File is corrupted or locked

Mögliche Ursachen:

  • Datei wird noch von Excel geöffnet
  • Datei ist beschädigt
  • Unzureichende Berechtigungen

Lösung:

# Prozesse prüfen, die die Datei sperren
$filePath = "C:\Import\data.xlsx"
$processes = Get-Process | Where-Object {$_.Modules.FileName -eq $filePath}
$processes | Stop-Process -Force

# Temporäres Verzeichnis überprüfen
$tempPath = [System.IO.Path]::GetTempPath()
Get-ChildItem $tempPath -Filter "*.xlsx" | Remove-Item -Force

Problem 5: Daten werden nicht importiert

Symptom:

  • Service läuft ohne Fehler
  • Keine Daten in der Zieltabelle

Mögliche Ursachen:

  • Cron-Ausdruck noch nicht ausgelöst
  • Falsches Datei-Muster
  • Alle Zeilen durch Filter entfernt

Lösung:

-- Tabelle überprüfen
SELECT COUNT(*) FROM DestinationTable;
SELECT TOP 10 * FROM DestinationTable ORDER BY ImportDate DESC;

-- Tabelle leeren und neu testen
TRUNCATE TABLE DestinationTable;

Cron-Ausdruck testen:

// Für Tests: Jede Minute ausführen
{
    "CronExpression": "* * * * *"
}

// Nach erfolgreichem Test: Produktiv-Zeitplan setzen
{
    "CronExpression": "0 6 * * *"
}

Problem 6: Speicherverbrauch zu hoch

Symptom:

  • Service verbraucht > 2 GB RAM
  • System wird langsam

Mögliche Ursachen:

  • Sehr große Excel-Dateien
  • Mehrere parallele Jobs
  • Memory Leak

Lösung:

// Jobs zeitlich staffeln
{
    "ImportJobs": [
        {"JobName": "Job1", "CronExpression": "0 1 * * *"},
        {"JobName": "Job2", "CronExpression": "0 2 * * *"},
        {"JobName": "Job3", "CronExpression": "0 3 * * *"}
    ]
}
# Service neu starten (setzt Speicher zurück)
Restart-Service ExcelDataImporter

# Prozess-Speicher überwachen
Get-Process ExcelDataImporter | Select-Object Name, @{Name="Memory (MB)";Expression={[Math]::Round($_.WorkingSet / 1MB, 2)}}

Logging-Analyse

Debug-Modus aktivieren

{
    "Serilog": {
        "MinimumLevel": "Debug"
    }
}

Wichtige Log-Meldungen

Log-Meldung Bedeutung Aktion
Started ExcelImportService Service erfolgreich gestartet ✓ Normal
Adding Job {JobName} Job wurde registriert ✓ Normal
{Job} starting with CRON schedule Job-Scheduler initialisiert ✓ Normal
{Job} is working. Execution Count: {Count} Job wird ausgeführt ✓ Normal
Keine Dateien mit dem Suchmuster {Pattern} Keine passenden Dateien ⚠️ Überprüfen
Importiere Datei {Datei} Datei wird verarbeitet ✓ Normal
Anzahl zu importierende Datensätze: {Anzahl} Daten geladen ✓ Normal
Daten wurden erfolgreich in {Tabelle} importiert Import erfolgreich ✓ Normal
Fehler beim Importieren aus Pfad {Pfad} Import fehlgeschlagen ❌ Fehler beheben

Event Viewer (Windows)

Der Service schreibt auch ins Windows Event Log:

# Event Log überprüfen
Get-EventLog -LogName Application -Source ExcelImportService -Newest 50

# Fehler filtern
Get-EventLog -LogName Application -Source ExcelImportService -EntryType Error -Newest 20

📚 Best Practices

1. Konfiguration

  • Verwenden Sie aussagekräftige Job-Namen: DailySalesImport statt Job1
  • Dokumentieren Sie Cron-Ausdrücke mit Kommentaren: Nicht in JSON möglich, aber in separater Dokumentation
  • Verwenden Sie spezifische Dateimuster: Sales_*.xlsx statt *.xlsx
  • Setzen Sie angemessene Log-Level: Information für Produktion, Debug nur bei Problemen
  • Verwenden Sie sichere Connection Strings: Windows-Authentifizierung bevorzugen

2. Dateiorganisation

  • Strukturierte Ordnerstruktur:

    Import/
    ├── Products/
    │   ├── Current/
    │   └── Archive/
    ├── Sales/
    │   ├── Current/
    │   └── Archive/
    └── Customers/
        ├── Current/
        └── Archive/
    
  • Automatisches Archivieren: Externe Skripte zum Verschieben verarbeiteter Dateien

  • Konsistente Dateinamen: [Kategorie]_[Datum]_[Version].xlsx

  • Nur neueste Datei verwenden: Service wählt automatisch die neueste Datei

3. Datenbank-Design

  • Staging-Tabellen verwenden:

    -- Import in Staging-Tabelle
    CREATE TABLE ProductData_Staging (...);
    
    -- Nach Validierung in Produktiv-Tabelle kopieren
    INSERT INTO ProductData SELECT * FROM ProductData_Staging WHERE ...;
    
  • Indexe für Performance:

    -- Index auf häufig gefilterte Spalten
    CREATE INDEX IX_ImportDate ON ProductData(ImportDate);
    
  • Importdatum-Spalte aktivieren: Für Nachverfolgbarkeit

  • Audit-Trails: Zusätzliche Spalten für Änderungsverfolgung

4. Monitoring

  • Regelmäßige Log-Überprüfung: Tägliche Kontrolle der Logs
  • Datenvalidierung: SQL-Queries zur Überprüfung importierter Daten
  • Alerts einrichten: z. B. bei fehlenden Dateien oder Fehlern
  • Performance-Metriken: Import-Dauer und Datensatzanzahl tracken

5. Sicherheit

  • Minimale Berechtigungen: Service-Account nur mit notwendigen Rechten
  • Connection Strings verschlüsseln: Windows DPAPI oder Azure Key Vault
  • SQL-Injection vermeiden: Service verwendet parametrisierte Queries
  • Netzwerkfreigaben: UNC-Pfade mit entsprechenden Credentials

6. Wartung

  • Regelmäßige Updates: .NET Runtime und NuGet-Pakete aktualisieren
  • Log-Rotation: Automatische Bereinigung alter Logs (konfiguriert: 7 Tage)
  • Backup-Strategie: Datenbank-Backups vor großen Imports
  • Test-Umgebung: Neue Konfigurationen zuerst testen

7. Fehlerbehandlung

  • Graceful Degradation: Service läuft weiter bei einzelnen Job-Fehlern
  • Retry-Mechanismen: Bei temporären Fehlern automatisch wiederholen
  • Benachrichtigungen: Email oder Teams-Notification bei kritischen Fehlern
  • Rollback-Plan: Strategie für fehlerhafte Imports

❓ FAQ

Allgemeine Fragen

F: Kann der Service mehrere Jobs parallel ausführen? A: Ja, jeder Job läuft als eigenständiger HostedService und kann parallel ausgeführt werden. Beachten Sie jedoch Ressourcen-Limits und potenzielle Datenbank-Locks.

F: Werden Excel-Dateien nach dem Import gelöscht? A: Nein, der Service löscht keine Quelldateien. Sie müssen externe Skripte oder Tools für Archivierung verwenden.

F: Kann ich den Service auf Linux betreiben? A: Ja, als eigenständige Anwendung oder Docker-Container. Windows-Service-Funktionalität ist nur auf Windows verfügbar.

F: Unterstützt der Service Excel-Dateien mit mehreren Arbeitsblättern? A: Nur das erste Arbeitsblatt wird verarbeitet. Für mehrere Arbeitsblätter benötigen Sie separate Jobs oder eine Anpassung des Codes.

F: Wie werden Excel-Formeln behandelt? A: Nur die berechneten Werte werden importiert, nicht die Formeln selbst.

Konfiguration

F: Kann ich denselben Job mehrmals mit verschiedenen Zeitplänen ausführen? A: Erstellen Sie separate Jobs mit unterschiedlichen Namen aber denselben Einstellungen:

{
    "ImportJobs": [
        {"JobName": "MorningImport", "CronExpression": "0 6 * * *", ...},
        {"JobName": "EveningImport", "CronExpression": "0 18 * * *", ...}
    ]
}

F: Kann ich verschiedene Connection Strings für verschiedene Jobs verwenden? A: Ja, mit dem ConnectionString-Parameter in der Job-Konfiguration.

F: Wie kann ich den Service im Test-Modus ausführen? A: Setzen Sie CronExpression: "* * * * *" für minutliche Ausführung und TruncateDestinationTable: false für sichere Tests.

Datenverarbeitung

F: Was passiert bei doppelten Daten? A: Abhängig von TruncateDestinationTable:

  • true: Tabelle wird geleert, keine Duplikate
  • false: Daten werden angehängt, Duplikate möglich (verwenden Sie UNIQUE-Constraints)

F: Wie gehe ich mit unterschiedlichen Excel-Strukturen um? A: Jeder Job benötigt eine konsistente Excel-Struktur. Für verschiedene Strukturen verwenden Sie separate Jobs mit eigenen Zieltabellen.

F: Können Spalten umbenannt werden? A: Nicht direkt. Verwenden Sie SQL-Views oder Stored Procedures für Transformationen:

CREATE VIEW ProductsView AS
SELECT 
    OldColumnName AS NewColumnName,
    ...
FROM ProductData;

Performance

F: Wie kann ich große Dateien schneller importieren? A:

  1. Verwenden Sie TruncateDestinationTable: true statt DELETE
  2. Deaktivieren Sie Indizes vor dem Import
  3. Erhöhen Sie SQL Server-Ressourcen
  4. Verwenden Sie SSD-Speicher

F: Wie viele Jobs kann ich gleichzeitig ausführen? A: Abhängig von:

  • Verfügbarem RAM (ca. 100-500 MB pro Job)
  • CPU-Kernen
  • Datenbank-Verbindungen
  • I/O-Performance

Empfehlung: Maximal 5-10 parallele Jobs auf Standard-Hardware.

Troubleshooting

F: Der Service läuft, aber Daten werden nicht importiert. Was nun? A: Prüfen Sie in dieser Reihenfolge:

  1. Logs auf Fehler untersuchen
  2. Dateien im konfigurierten Pfad vorhanden?
  3. Cron-Zeitpunkt bereits erreicht?
  4. Datenbankverbindung funktioniert?
  5. SQL-Berechtigungen ausreichend?

F: Wie kann ich die nächste Ausführungszeit eines Jobs ermitteln? A: Suchen Sie im Log nach:

{Job} next run: 06.12.2024 02:00:00

F: Was bedeutet "Anzahl Datensätze: System.Object in Tabelle"? A: Normalerweise ein Anzeichen für erfolgreichen Import. Die Anzahl wird geloggt, aber die Log-Ausgabe kann manchmal den Typ statt des Wertes anzeigen.

Sicherheit

F: Wie sichere ich den Connection String ab? A: Optionen:

  1. User Secrets (Entwicklung):

    dotnet user-secrets set "connectionStrings:ConnectionString" "Server=..."
    
  2. Umgebungsvariablen (Produktion):

    [Environment]::SetEnvironmentVariable("ConnectionStrings__ConnectionString", "Server=...", "Machine")
    
  3. Azure Key Vault (Cloud):

    builder.Configuration.AddAzureKeyVault(...);
    

F: Welche SQL-Berechtigungen werden benötigt? A: Mindestens:

  • CREATE TABLE (wenn Tabellen automatisch erstellt werden)
  • ALTER TABLE (für Spalten hinzufügen)
  • INSERT (für Datenimport)
  • TRUNCATE (wenn TruncateDestinationTable: true)
  • SELECT (für Datenvalidierung)

Erweiterte Nutzung

F: Kann ich den Import-Prozess anpassen? A: Ja, durch:

  1. Anpassung der ExcelImporter- oder Importer-Klasse
  2. Eigene Implementierung von IExcelImporter
  3. Erweiterung der ImportSettings mit zusätzlichen Parametern

F: Kann ich den Service programmgesteuert steuern? A: Der Service ist für autonomen Betrieb konzipiert. Für manuelle Steuerung:

  1. Service stoppen/starten via sc.exe oder PowerShell
  2. REST-API hinzufügen (erfordert Code-Änderung)
  3. Message Queue für Job-Trigger implementieren

F: Kann ich Benachrichtigungen bei Fehlern erhalten? A: Nicht out-of-the-box. Implementierungsmöglichkeiten:

  1. Serilog-Sink für Email/Teams/Slack
  2. Windows Event Log + Task Scheduler
  3. Monitoring-Tools wie Application Insights

📞 Support und Kontakt

Dokumentation

Interne Nutzung

Dieses Projekt ist für die interne Verwendung bei CSS EDV-Support konzipiert. Bei Fragen oder Problemen wenden Sie sich an das CSS EDV-Support Development Team.

Externe Nutzung

Für die externe Nutzung oder kommerzielle Lizenzen kontaktieren Sie bitte CSS EDV-Support.


📝 Lizenz

© CSS EDV-Support – Interne Nutzung oder nach Rücksprache.


📊 Anhang

Glossar

Begriff Beschreibung
Cron-Ausdruck Zeitplan-Format für wiederkehrende Aufgaben (5 Felder: Minute Stunde Tag Monat Wochentag)
Bulk-Insert Hochperformante Methode zum Einfügen vieler Datensätze auf einmal
SqlBulkCopy .NET-Klasse für effiziente Massen-Datenimporte in SQL Server
DevExpress Kommerzieller Anbieter von UI- und Dokumenten-Verarbeitungskomponenten
HostedService .NET-Konzept für lang laufende Background-Dienste
Serilog Strukturiertes Logging-Framework für .NET
NCrontab .NET-Bibliothek für Cron-Expression-Parsing
Forward-Fill Technik zum Füllen leerer Zellen mit vorherigen Werten
Truncate SQL-Befehl zum schnellen Leeren einer Tabelle

Änderungshistorie

Version Datum Änderungen
1.0.0 2024-12-05 Initiale ausführliche Dokumentation erstellt