Direkt zum Hauptinhalt

ExcelDataImporter - Anwendungsdokumentation

Anwendungsdokumentation

🎯 Übersicht

ExcelDataImporter ist ein automatisierter Importdienst für die Übernahme von Daten aus Excel-Dateien in Microsoft SQL Server Datenbanken. Der Dienst kann als Docker-Container oder als Windows-Service betrieben werden.

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öschungDynamische 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-AnwendungDocker-Container oder Docker-ContainerWindows-Service

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

MindestanforderungenDocker-Installation

    Docker: Docker Engine 20.10+ oder Docker Desktop Betriebssystem: Linux, Windows oder macOS mit Docker-Unterstützung Datenbank: Microsoft SQL Server 2016+ (erreichbar vom Container) Speicher: Mindestens 512 MB RAM für den Container Netzwerk: Zugriff auf SQL Server und Excel-Datei-Ordner

    Windows-Service-Installation

    • 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)
    • FestplatteNetzwerk: 100Zugriff 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: Microsoftauf 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 dieund zu überwachendenüberwachende Ordner (lokal oder Netzwerkfreigabe) Schreibrechte für Log-Verzeichnis

        📦 Installation

        OptionDocker-Installation 1:(Empfohlen)

        Windows-Service-

        Die Installation über Docker ist die empfohlene Methode für den Betrieb von ExcelDataImporter.

        Schritt 1: appsettings.jsonDocker konfigurierenImage herunterladen

        # Neueste Version von der GitHub Container Registry herunterladen
        docker pull ghcr.io/css-edv-support/exceldataimporter:latest
        

        Schritt 2: Konfigurationsdatei vorbereiten

        NavigierenErstellen Sie zum Programmverzeichnis und bearbeiten Sie dieeine appsettings.json Datei mit Ihrer Konfiguration (siehe Abschnitt Konfiguration).

        Schritt 3: Container starten

        # Mit Volume-Mapping für Konfiguration, Logs und Datenordner
        docker run -d \
          --name exceldataimporter \
          -v /pfad/zur/appsettings.json:/app/appsettings.json:ro \
          -v /pfad/zu/logs:/app/Logs \
          -v /pfad/zu/daten:/data \
          ghcr.io/css-edv-support/exceldataimporter:latest
        

        Hinweis: Passen Sie die Volume-Pfade an Ihre Umgebung an:

          /pfad/zur/appsettings.json: Pfad zu Ihrer Konfigurationsdatei /pfad/zu/logs: Verzeichnis für Log-Dateien /pfad/zu/daten: Verzeichnis mit Excel-Dateien (z.B. /data/Import in der Config verwenden)

          Schritt 4: Container-Status überprüfen

          # Container-Status prüfen
          docker ps | grep exceldataimporter
          
          # Logs überwachen
          docker logs -f exceldataimporter
          

          Docker Compose (Alternative)

          Erstellen Sie eine docker-compose.yml Datei:

          version: '3.8'
          
          services:
            exceldataimporter:
              image: ghcr.io/css-edv-support/exceldataimporter:latest
              container_name: exceldataimporter
              volumes:
                - ./appsettings.json:/app/appsettings.json:ro
                - ./logs:/app/Logs
                - ./data:/data
              environment:
                - ConnectionStrings__ConnectionString=Server=sqlserver;Database=ImportDB;User Id=sa;Password=YourPassword;TrustServerCertificate=True;
                # Optional: Umgebungsvariablen für einzelne Import-Jobs
              restart: unless-stopped
          

          Starten Sie den Service:

          docker-compose up -d
          

          Windows-Service-Installation (Alternative)

          Falls Docker nicht verfügbar ist, kann ExcelDataImporter auch als Windows-Service installiert werden. Die notwendigen Daten erhalten Sie auf Anfrage.

          Schritt 1: Anwendung herunterladen

          Schritt 2: Konfiguration anpassen

          Bearbeiten Sie die Datei C:\Services\ExcelDataImporter\appsettings.json entsprechend Ihrer Anforderungen (siehe Abschnitt Konfiguration).

          Schritt 3: 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 3:4: ServiceService-Status ü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 Datei appsettings.json-Datei:. Bei Docker können alternativ auch Umgebungsvariablen verwendet werden.

          Konfiguration über appsettings.json

          Basis-Struktur

          {
              "Serilog": {
                  "Using": [
                      "Serilog.Sinks.Console",
                      "Serilog.Sinks.File"
                  ],
                  "MinimumLevel": "Debug"Information",
                  "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,false,
                      "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

          Parameter

          Pflichtfelder

          Pflichtfelder:

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

          Optionale FelderFelder:

          Parameter Typ Standard Beschreibung
          CronExpression string "* * * * *" Cron-Ausdruck für ZeitplanungZeitplan (jedeFormat: Minute)Minute Stunde Tag Monat Wochentag)
          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 steuerndefinieren dieden AusführungszeitZeitplan derfür Import-Jobs. Format: Minute Stunde Tag Monat Wochentag

          Beispiele

          Häufige 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 06 * * 1-5 Werktags um 6:00 Uhr 30 14 1 * * Am ersten Tag des Monats um Mitternacht14:30 Uhr 300 60 * * 10 Jeden MontagSonntag um 6:30 UhrMitternacht

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

          Logging-Konfiguration

          Connection

          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-AusgabezieleStrings

          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

             (gilt für alle Jobs ohne eigenen Connection String):
            "connectionStrings": {
                "ConnectionString": "Server=localhost;Database=ImportDB;User Id=sa;Password=YourPassword;TrustServerCertificate=True;"
            }
            

            Job-spezifischer Connection String

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

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

            KonfigurationsbeispieleKonfiguration über Umgebungsvariablen (Docker)

            Bei Docker können Konfigurationswerte über Umgebungsvariablen gesetzt werden. Die Variablennamen verwenden dabei __ (doppelter Unterstrich) als Trennzeichen für die JSON-Hierarchie.

            Beispiel: Connection String setzen

            # Docker run
            docker run -d \
              --name exceldataimporter \
              -e ConnectionStrings__ConnectionString="Server=sqlserver;Database=ImportDB;User Id=sa;Password=YourPassword;TrustServerCertificate=True;" \
              -v /pfad/zur/appsettings.json:/app/appsettings.json:ro \
              -v /pfad/zu/logs:/app/Logs \
              -v /pfad/zu/daten:/data \
              ghcr.io/css-edv-support/exceldataimporter:latest
            

            Docker Compose mit Umgebungsvariablen

            version: '3.8'
            
            services:
              exceldataimporter:
                image: ghcr.io/css-edv-support/exceldataimporter:latest
                container_name: exceldataimporter
                volumes:
                  - ./appsettings.json:/app/appsettings.json:ro
                  - ./logs:/app/Logs
                  - ./data:/data
                environment:
                  # Connection String
                  - ConnectionStrings__ConnectionString=Server=sqlserver;Database=ImportDB;User Id=sa;Password=YourPassword;TrustServerCertificate=True;
                  
                  # Logging Level (Optional)
                  - Serilog__MinimumLevel=Information
                  
                restart: unless-stopped
            
              # Optional: SQL Server Container
              sqlserver:
                image: mcr.microsoft.com/mssql/server:2022-latest
                environment:
                  - ACCEPT_EULA=Y
                  - SA_PASSWORD=YourStrongPassword123!
                  - MSSQL_PID=Express
                ports:
                  - "1433:1433"
                volumes:
                  - sqldata:/var/opt/mssql
            
            volumes:
              sqldata:
            

            Wichtige Umgebungsvariablen:

            Variable Beschreibung Beispiel ConnectionStrings__ConnectionString Datenbank-Verbindungszeichenfolge Server=...;Database=... Serilog__MinimumLevel Log-Level Information, Debug, Warning

            Hinweis: Die Konfiguration von Import-Jobs über Umgebungsvariablen ist komplex. Es wird empfohlen, die Jobs in der appsettings.json zu definieren und nur den Connection String über Umgebungsvariablen zu überschreiben.

            Konfigurations-Beispiele

            Beispiel 1: Einfacher täglicher Import

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

            Beispiel 2: Stündlicher Import mit Datenbereinigung

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

            Beispiel 3: Multi-Job-SetupMehrere Import-Jobs

            {
                "ImportJobs": [
                    {
                        "JobName": "MorningProductSync",
                        "CronExpression": "0 6 * * *",
                        "Pfad": "C:\\Import\\/data/Products",
                        "ExcelFilePattern": "*.xlsx",
                        "DestinationTable": "Products",
                        "TruncateDestinationTable": true
                    },
                    {
                        "JobName": "EveningCustomerSync",
                        "CronExpression": "0 18 * * *",
                        "Pfad": "C:\\Import\\/data/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

              Konfiguration erstellen: appsettings.json mit Import-Jobs konfigurieren Service starten: Windows-Service, Standalone oder Docker Dateien bereitstellen: Excel-Dateien in die konfigurierten Verzeichnisse legen Automatische Verarbeitung: Jobs werden gemäß Cron-Zeitplan ausgeführt 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äßigWird 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-InteraktionGrundlegender Workflow

                Konfiguration erstellen: appsettings.json mit Import-Jobs konfigurieren Service starten: Als Docker-Container oder Windows-Service Dateien bereitstellen: Excel-Dateien in die konfigurierten Verzeichnisse legen Automatische Verarbeitung: Jobs werden gemäß Cron-Zeitplan ausgeführt Ergebnisse prüfen: Daten in der Datenbank überprüfen und Logs kontrollieren

                Logs überwachen

                Automatische TabellenerstellungDocker

                Wenn die Zieltabelle nicht existiert, wird sie automatisch erstellt:

                //# DieContainer-Logs Tabelleanzeigen
                wirddocker basierendlogs auf-f derexceldataimporter
                
                Excel-Struktur# generiertLogs im Volume prüfen
                tail -f // Spaltentypen werden automatisch erkannt:
                // - Int32 → INT
                // - String → NVARCHAR(MAX)
                // - DateTime → DATETIME
                // - Float → FLOATpfad/zu/logs/log.txt
                

                Bulk-InsertWindows-Service

                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:

                  Konfigurationsfehler: MissingSettingException bei fehlenden Pflichtfeldern Dateisystemfehler: DirectoryNotFoundException, FileNotFoundException Excel-Verarbeitungsfehler: Detailliertes Logging mit Dateinamen Datenbankfehler: SQL-Exceptions werden geloggt, Service läuft weiter 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über PowerShell anzeigen
                      Get-Content C:\Services\ExcelDataImporter\Logs\log.txt -Tail 10050 -Wait
                      
                      # ManuelleEvent AusführungViewer zumverwenden
                      Debuggen
                      cd C:\Services\ExcelDataImporter
                      .\ExcelDataImporter.exe
                      
                      # .NET Runtime überprüfen
                      dotnetGet-EventLog --list-runtimesLogName 

                      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"Application -FilterSource "*.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-NetConnectionExcelImportService -ComputerNameNewest 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)}}20
                                    

                                    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 - FehlerDetails behebenim Log

                                    EventErweiterte ViewerFeatures

                                    Spaltenfüllung (Windows)FillEmptyColumns)

                                    DerFüllt Serviceleere schreibtZellen auchmit insdem Windowsletzten Eventnicht-leeren Log:Wert in der Spalte.

                                    Beispiel:

                                    #"FillEmptyColumns": Event[0, Log2]
                                    überprüfen
                                    Get-EventLog

                                    Dies -LogNamefüllt Applicationleere -SourceZellen ExcelImportServicein -Newestden 50Spalten #0 Fehlerund filtern2 Get-EventLogmit -LogNamedem Applicationjeweils -Sourcevorherigen ExcelImportServiceWert -EntryTypeauf.

                                    Error

                                    Bedingte -NewestZeilenentfernung 20(RemoveRowIfColumnIsEmpty)

                                    Entfernt Zeilen, bei denen eine bestimmte Spalte leer ist.

                                    Beispiel:

                                    "RemoveRowIfColumnIsEmpty": 1
                                    

                                    Entfernt alle Zeilen, bei denen die Spalte mit Index 1 leer ist.

                                    Subfolder-Suche (IncludeSubfolders)

                                    Durchsucht rekursiv alle Unterverzeichnisse nach Excel-Dateien.

                                    Beispiel:

                                    "IncludeSubfolders": true
                                    

                                    📚 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:

                                                      Verwenden Sie TruncateDestinationTable: true statt DELETE Deaktivieren Sie Indizes vor dem Import Erhöhen Sie SQL Server-Ressourcen 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:

                                                          Logs auf Fehler untersuchen Dateien im konfigurierten Pfad vorhanden? Cron-Zeitpunkt bereits erreicht? Datenbankverbindung funktioniert? 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:

                                                            User Secrets (Entwicklung):

                                                            dotnet user-secrets set "connectionStrings:ConnectionString" "Server=..."
                                                            

                                                            Umgebungsvariablen (Produktion):

                                                            [Environment]::SetEnvironmentVariable("ConnectionStrings__ConnectionString", "Server=...", "Machine")
                                                            

                                                            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:

                                                                Anpassung der ExcelImporter- oder Importer-Klasse Eigene Implementierung von IExcelImporter 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:

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

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

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

                                                                    📞 Support und Kontakt

                                                                    Dokumentation

                                                                    Interne NutzungKontakt

                                                                    Dieses Projekt ist für die interne Verwendung bei CSS EDV-Support konzipiert. Bei Fragen oder Problemen wenden Sie sich bitte 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