Add comprehensive error handling to Python and JavaScript files

This commit enhances error handling across the codebase with clear, user-friendly error messages:

Python Files:
- main.py: Added error handling for directory creation and file operations
- read_excel.py: Added error handling for file loading, JSON parsing, and data output
- fill_plan_dates.py: Added input validation and error handling for file operations and date calculations
- calculate.py: Improved error handling in load_holidays() and process_file() with detailed warnings for invalid data
- build_template.py: Added error handling for directory creation, workbook creation, and file saving

JavaScript Files:
- storage.js: Added comprehensive error handling for:
  - JSON parsing in getEmployees() and getAllDuties()
  - Type validation in save operations
  - Date conversion in getDutiesForMonth()
  - Data validation in saveDutiesForMonth()
  - Export/import operations

Benefits:
- Clear error messages in German for better user experience
- Graceful degradation when data is corrupted
- Type checking to prevent invalid data from being stored
- Row-level error reporting for Excel processing
- Invalid data filtering to prevent application crashes
This commit is contained in:
Claude 2025-12-13 13:31:18 +00:00
parent 8821bee816
commit b9d8e7094b
No known key found for this signature in database
6 changed files with 534 additions and 270 deletions

View file

@ -284,33 +284,71 @@ def _populate_checks(ws):
def build_template():
TEMPLATE_PATH.parent.mkdir(parents=True, exist_ok=True)
wb = Workbook()
"""Builds the complete Excel template with all sheets and formulas."""
try:
# Create output directory
try:
TEMPLATE_PATH.parent.mkdir(parents=True, exist_ok=True)
except PermissionError:
print(f"❌ Fehler: Keine Berechtigung zum Erstellen des Verzeichnisses '{TEMPLATE_PATH.parent}'")
raise
except OSError as e:
print(f"❌ Fehler beim Erstellen des Verzeichnisses '{TEMPLATE_PATH.parent}': {e}")
raise
readme_ws = wb.active
readme_ws.title = "README"
_populate_readme(readme_ws)
# Create workbook
try:
wb = Workbook()
except Exception as e:
print(f"❌ Fehler beim Erstellen des Workbooks: {e}")
raise
rules_ws = wb.create_sheet("Regeln")
_populate_rules(rules_ws)
try:
readme_ws = wb.active
readme_ws.title = "README"
_populate_readme(readme_ws)
holiday_ws = wb.create_sheet("Feiertage")
_populate_holidays(holiday_ws)
rules_ws = wb.create_sheet("Regeln")
_populate_rules(rules_ws)
plan_ws = wb.create_sheet("Plan")
_populate_plan(plan_ws)
holiday_ws = wb.create_sheet("Feiertage")
_populate_holidays(holiday_ws)
auswertung_ws = wb.create_sheet("Auswertung")
_populate_auswertung(auswertung_ws)
plan_ws = wb.create_sheet("Plan")
_populate_plan(plan_ws)
checks_ws = wb.create_sheet("Checks")
_populate_checks(checks_ws)
auswertung_ws = wb.create_sheet("Auswertung")
_populate_auswertung(auswertung_ws)
wb.save(TEMPLATE_PATH)
return TEMPLATE_PATH
checks_ws = wb.create_sheet("Checks")
_populate_checks(checks_ws)
except Exception as e:
print(f"❌ Fehler beim Erstellen der Arbeitsblätter: {e}")
raise
# Save template
try:
wb.save(TEMPLATE_PATH)
except PermissionError:
print(f"❌ Fehler: Keine Berechtigung zum Speichern der Datei '{TEMPLATE_PATH}'")
raise
except OSError as e:
print(f"❌ Fehler beim Speichern der Datei '{TEMPLATE_PATH}': {e}")
raise
return TEMPLATE_PATH
except Exception as e:
print(f"❌ Unerwarteter Fehler beim Erstellen der Vorlage: {e}")
raise
if __name__ == "__main__":
path = build_template()
print(f"✅ Vorlage (Variante 2 streng) erstellt: {path}")
try:
path = build_template()
print(f"✅ Vorlage (Variante 2 streng) erstellt: {path}")
except Exception:
# Error already printed in build_template
import sys
sys.exit(1)

View file

@ -20,25 +20,39 @@ ABZUG = 2.0 # Abzug nach Erreichen der Schwelle
def load_holidays(wb):
"""Lädt Feiertage aus dem Feiertage-Blatt."""
if "Feiertage" not in wb.sheetnames:
print("⚠️ Warnung: Blatt 'Feiertage' nicht gefunden. Keine Feiertage geladen")
return set()
holidays = set()
ws = wb["Feiertage"]
for row in ws.iter_rows(min_row=2, values_only=True):
if row[0] and row[2] == "NRW": # Datum und BL prüfen
date_raw = row[0]
if isinstance(date_raw, str):
try:
parsed_date = datetime.strptime(date_raw, '%d.%m.%Y').date()
holidays.add(parsed_date)
except:
pass
elif isinstance(date_raw, datetime):
holidays.add(date_raw.date())
elif isinstance(date_raw, date):
holidays.add(date_raw)
try:
ws = wb["Feiertage"]
for row_num, row in enumerate(ws.iter_rows(min_row=2, values_only=True), start=2):
try:
if row[0] and len(row) > 2 and row[2] == "NRW": # Datum und BL prüfen
date_raw = row[0]
if isinstance(date_raw, str):
try:
parsed_date = datetime.strptime(date_raw, '%d.%m.%Y').date()
holidays.add(parsed_date)
except ValueError as e:
print(f"⚠️ Warnung: Ungültiges Datumsformat in Zeile {row_num}: '{date_raw}' - {e}")
continue
elif isinstance(date_raw, datetime):
holidays.add(date_raw.date())
elif isinstance(date_raw, date):
holidays.add(date_raw)
except IndexError:
print(f"⚠️ Warnung: Unvollständige Zeile {row_num} im Feiertage-Blatt übersprungen")
continue
except Exception as e:
print(f"⚠️ Warnung: Fehler beim Verarbeiten von Zeile {row_num}: {e}")
continue
except Exception as e:
print(f"❌ Fehler beim Laden der Feiertage: {e}")
return set()
return holidays
@ -154,89 +168,131 @@ def calculate_verguetung(plan_data, holidays):
def process_file(filepath):
"""Verarbeitet die Excel-Datei und schreibt Auswertung."""
wb = load_workbook(filepath)
# Lade Feiertage
holidays = load_holidays(wb)
print(f"📅 {len(holidays)} Feiertage geladen")
# Lade Plan-Daten
if "Plan" not in wb.sheetnames:
print("❌ Blatt 'Plan' nicht gefunden!")
# Load workbook
try:
wb = load_workbook(filepath)
except FileNotFoundError:
print(f"❌ Fehler: Datei '{filepath}' nicht gefunden")
return
plan_ws = wb["Plan"]
plan_data = []
for row in plan_ws.iter_rows(min_row=2, values_only=True):
if row[0]: # Wenn Datum vorhanden
datum_raw = row[0]
mitarbeiter = row[1] if len(row) > 1 else None
# Parse Datum (kann String oder date sein)
if isinstance(datum_raw, str):
try:
datum = datetime.strptime(datum_raw, '%d.%m.%Y').date()
except:
continue
elif isinstance(datum_raw, datetime):
datum = datum_raw.date()
elif isinstance(datum_raw, date):
datum = datum_raw
else:
except PermissionError:
print(f"❌ Fehler: Keine Berechtigung zum Lesen der Datei '{filepath}'")
return
except Exception as e:
print(f"❌ Fehler beim Laden der Datei '{filepath}': {e}")
return
try:
# Lade Feiertage
holidays = load_holidays(wb)
print(f"📅 {len(holidays)} Feiertage geladen")
# Lade Plan-Daten
if "Plan" not in wb.sheetnames:
print("❌ Blatt 'Plan' nicht gefunden!")
return
plan_ws = wb["Plan"]
plan_data = []
for row_num, row in enumerate(plan_ws.iter_rows(min_row=2, values_only=True), start=2):
try:
if row[0]: # Wenn Datum vorhanden
datum_raw = row[0]
mitarbeiter = row[1] if len(row) > 1 else None
# Parse Datum (kann String oder date sein)
if isinstance(datum_raw, str):
try:
datum = datetime.strptime(datum_raw, '%d.%m.%Y').date()
except ValueError as e:
print(f"⚠️ Warnung: Ungültiges Datumsformat in Zeile {row_num}: '{datum_raw}' - übersprungen")
continue
elif isinstance(datum_raw, datetime):
datum = datum_raw.date()
elif isinstance(datum_raw, date):
datum = datum_raw
else:
print(f"⚠️ Warnung: Unbekannter Datumstyp in Zeile {row_num}: {type(datum_raw)} - übersprungen")
continue
if mitarbeiter:
plan_data.append((datum, mitarbeiter))
except Exception as e:
print(f"⚠️ Warnung: Fehler beim Verarbeiten von Plan-Zeile {row_num}: {e}")
continue
if mitarbeiter:
plan_data.append((datum, mitarbeiter))
print(f"📋 {len(plan_data)} Einträge im Plan")
# Berechne Vergütung
results = calculate_verguetung(plan_data, holidays)
# Schreibe Auswertung
if "Auswertung" not in wb.sheetnames:
print("❌ Blatt 'Auswertung' nicht gefunden!")
print(f"📋 {len(plan_data)} Einträge im Plan")
if not plan_data:
print("⚠️ Warnung: Keine gültigen Plan-Einträge gefunden")
# Berechne Vergütung
try:
results = calculate_verguetung(plan_data, holidays)
except Exception as e:
print(f"❌ Fehler bei der Vergütungsberechnung: {e}")
return
# Schreibe Auswertung
if "Auswertung" not in wb.sheetnames:
print("❌ Blatt 'Auswertung' nicht gefunden!")
return
try:
auswertung_ws = wb["Auswertung"]
# Lösche alte Daten (ab Zeile 2)
auswertung_ws.delete_rows(2, auswertung_ws.max_row)
# Schreibe neue Daten
for idx, result in enumerate(results, start=2):
auswertung_ws[f"A{idx}"] = result['mitarbeiter']
auswertung_ws[f"B{idx}"] = round(result['wt_einheiten'], 2)
auswertung_ws[f"C{idx}"] = round(result['we_freitag'], 2)
auswertung_ws[f"D{idx}"] = round(result['we_andere'], 2)
auswertung_ws[f"E{idx}"] = round(result['we_gesamt'], 2)
auswertung_ws[f"F{idx}"] = result['schwelle_erreicht']
auswertung_ws[f"G{idx}"] = round(result['abzug_freitag'], 2)
auswertung_ws[f"H{idx}"] = round(result['abzug_andere'], 2)
auswertung_ws[f"I{idx}"] = round(result['we_bezahlt'], 2)
auswertung_ws[f"J{idx}"] = round(result['auszahlung_wt'], 2)
auswertung_ws[f"K{idx}"] = round(result['auszahlung_we'], 2)
auswertung_ws[f"L{idx}"] = round(result['auszahlung_gesamt'], 2)
# Formatierung für Schwelle
if result['schwelle_erreicht'] == 'JA':
auswertung_ws[f"F{idx}"].fill = PatternFill(start_color="C6EFCE", end_color="C6EFCE", fill_type="solid")
else:
auswertung_ws[f"F{idx}"].fill = PatternFill(start_color="FFC7CE", end_color="FFC7CE", fill_type="solid")
except Exception as e:
print(f"❌ Fehler beim Schreiben der Auswertung: {e}")
return
# Save file
try:
wb.save(filepath)
except PermissionError:
print(f"❌ Fehler: Keine Berechtigung zum Speichern der Datei '{filepath}'")
return
except OSError as e:
print(f"❌ Fehler beim Speichern der Datei '{filepath}': {e}")
return
print(f"\n✅ Auswertung geschrieben: {len(results)} Mitarbeiter")
print(f" Datei: {filepath}")
# Zeige Zusammenfassung
print(f"\n{'='*70}")
print(f"{'Mitarbeiter':<20} {'WT':<8} {'WE':<8} {'Schwelle':<10} {'Gesamt':>10}")
print(f"{'='*70}")
for r in results:
print(f"{r['mitarbeiter']:<20} {r['wt_einheiten']:>6.1f} {r['we_gesamt']:>6.1f} {r['schwelle_erreicht']:<10} {r['auszahlung_gesamt']:>9.2f}")
print(f"{'='*70}")
except Exception as e:
print(f"❌ Unerwarteter Fehler beim Verarbeiten der Datei: {e}")
return
auswertung_ws = wb["Auswertung"]
# Lösche alte Daten (ab Zeile 2)
auswertung_ws.delete_rows(2, auswertung_ws.max_row)
# Schreibe neue Daten
for idx, result in enumerate(results, start=2):
auswertung_ws[f"A{idx}"] = result['mitarbeiter']
auswertung_ws[f"B{idx}"] = round(result['wt_einheiten'], 2)
auswertung_ws[f"C{idx}"] = round(result['we_freitag'], 2)
auswertung_ws[f"D{idx}"] = round(result['we_andere'], 2)
auswertung_ws[f"E{idx}"] = round(result['we_gesamt'], 2)
auswertung_ws[f"F{idx}"] = result['schwelle_erreicht']
auswertung_ws[f"G{idx}"] = round(result['abzug_freitag'], 2)
auswertung_ws[f"H{idx}"] = round(result['abzug_andere'], 2)
auswertung_ws[f"I{idx}"] = round(result['we_bezahlt'], 2)
auswertung_ws[f"J{idx}"] = round(result['auszahlung_wt'], 2)
auswertung_ws[f"K{idx}"] = round(result['auszahlung_we'], 2)
auswertung_ws[f"L{idx}"] = round(result['auszahlung_gesamt'], 2)
# Formatierung für Schwelle
if result['schwelle_erreicht'] == 'JA':
auswertung_ws[f"F{idx}"].fill = PatternFill(start_color="C6EFCE", end_color="C6EFCE", fill_type="solid")
else:
auswertung_ws[f"F{idx}"].fill = PatternFill(start_color="FFC7CE", end_color="FFC7CE", fill_type="solid")
wb.save(filepath)
print(f"\n✅ Auswertung geschrieben: {len(results)} Mitarbeiter")
print(f" Datei: {filepath}")
# Zeige Zusammenfassung
print(f"\n{'='*70}")
print(f"{'Mitarbeiter':<20} {'WT':<8} {'WE':<8} {'Schwelle':<10} {'Gesamt':>10}")
print(f"{'='*70}")
for r in results:
print(f"{r['mitarbeiter']:<20} {r['wt_einheiten']:>6.1f} {r['we_gesamt']:>6.1f} {r['schwelle_erreicht']:<10} {r['auszahlung_gesamt']:>9.2f}")
print(f"{'='*70}")
if __name__ == "__main__":

View file

@ -15,46 +15,88 @@ def fill_plan_with_dates(template_path, output_path, year, month):
Lädt die Vorlage und füllt Spalte A (Datum) im Plan-Blatt
mit allen Tagen des angegebenen Monats.
"""
wb = load_workbook(template_path)
# Regeln-Blatt: Monat_Auswahl setzen
if "Regeln" in wb.sheetnames:
regeln_ws = wb["Regeln"]
# Zeile 7, Spalte B = Monat_Auswahl
regeln_ws["B7"] = date(year, month, 1)
# Plan-Blatt füllen
if "Plan" not in wb.sheetnames:
print("❌ Blatt 'Plan' nicht gefunden!")
# Validate input parameters
if not (1 <= month <= 12):
print(f"❌ Fehler: Ungültiger Monat '{month}'. Monat muss zwischen 1 und 12 liegen")
return
if year < 1900 or year > 2100:
print(f"❌ Fehler: Ungültiges Jahr '{year}'. Jahr muss zwischen 1900 und 2100 liegen")
return
# Load template workbook
try:
wb = load_workbook(template_path)
except FileNotFoundError:
print(f"❌ Fehler: Vorlagendatei '{template_path}' nicht gefunden")
return
except PermissionError:
print(f"❌ Fehler: Keine Berechtigung zum Lesen der Datei '{template_path}'")
return
except Exception as e:
print(f"❌ Fehler beim Laden der Vorlagendatei '{template_path}': {e}")
return
try:
# Regeln-Blatt: Monat_Auswahl setzen
if "Regeln" in wb.sheetnames:
regeln_ws = wb["Regeln"]
# Zeile 7, Spalte B = Monat_Auswahl
regeln_ws["B7"] = date(year, month, 1)
# Plan-Blatt füllen
if "Plan" not in wb.sheetnames:
print("❌ Blatt 'Plan' nicht gefunden!")
return
plan_ws = wb["Plan"]
# Startdatum
try:
start_date = date(year, month, 1)
except ValueError as e:
print(f"❌ Fehler: Ungültiges Datum für Jahr {year}, Monat {month}: {e}")
return
# Letzter Tag des Monats
try:
if month == 12:
end_date = date(year + 1, 1, 1) - timedelta(days=1)
else:
end_date = date(year, month + 1, 1) - timedelta(days=1)
except ValueError as e:
print(f"❌ Fehler beim Berechnen des Enddatums: {e}")
return
# Alle Tage durchgehen
current_date = start_date
row = 2 # Zeile 2 = erste Datenzeile nach Header
while current_date <= end_date:
cell = plan_ws[f"A{row}"]
cell.value = current_date
cell.number_format = 'DD.MM.YYYY' # Deutsches Datumsformat
# Spalten B (Mitarbeiter) und C (Anteil) bleiben leer zum Ausfüllen
current_date += timedelta(days=1)
row += 1
# Save output file
try:
wb.save(output_path)
except PermissionError:
print(f"❌ Fehler: Keine Berechtigung zum Speichern der Datei '{output_path}'")
return
except OSError as e:
print(f"❌ Fehler beim Speichern der Datei '{output_path}': {e}")
return
print(f"✅ Plan-Blatt vorbefüllt für {month:02d}/{year}")
print(f" Ausgabe: {output_path}")
print(f" Trage jetzt nur noch in Spalte B (Mitarbeiter) und C (Anteil) die Namen ein!")
except Exception as e:
print(f"❌ Unerwarteter Fehler beim Füllen des Plan-Blatts: {e}")
return
plan_ws = wb["Plan"]
# Startdatum
start_date = date(year, month, 1)
# Letzter Tag des Monats
if month == 12:
end_date = date(year + 1, 1, 1) - timedelta(days=1)
else:
end_date = date(year, month + 1, 1) - timedelta(days=1)
# Alle Tage durchgehen
current_date = start_date
row = 2 # Zeile 2 = erste Datenzeile nach Header
while current_date <= end_date:
cell = plan_ws[f"A{row}"]
cell.value = current_date
cell.number_format = 'DD.MM.YYYY' # Deutsches Datumsformat
# Spalten B (Mitarbeiter) und C (Anteil) bleiben leer zum Ausfüllen
current_date += timedelta(days=1)
row += 1
wb.save(output_path)
print(f"✅ Plan-Blatt vorbefüllt für {month:02d}/{year}")
print(f" Ausgabe: {output_path}")
print(f" Trage jetzt nur noch in Spalte B (Mitarbeiter) und C (Anteil) die Namen ein!")
if __name__ == "__main__":

View file

@ -11,52 +11,71 @@ from datetime import datetime
def create_example_excel():
"""Erstellt eine Beispiel-Excel-Datei mit formatierten Daten."""
# Neues Workbook erstellen
wb = Workbook()
ws = wb.active
ws.title = "Beispiel"
# Überschriften hinzufügen
headers = ["Name", "Alter", "Stadt", "Beruf"]
ws.append(headers)
# Überschriften formatieren
header_fill = PatternFill(start_color="4472C4", end_color="4472C4", fill_type="solid")
header_font = Font(bold=True, color="FFFFFF", size=12)
for cell in ws[1]:
cell.fill = header_fill
cell.font = header_font
cell.alignment = Alignment(horizontal="center", vertical="center")
# Beispieldaten hinzufügen
data = [
["Max Mustermann", 30, "Berlin", "Entwickler"],
["Erika Musterfrau", 28, "München", "Designerin"],
["Hans Schmidt", 35, "Hamburg", "Manager"],
["Anna Weber", 27, "Köln", "Analyst"],
]
for row in data:
ws.append(row)
# Spaltenbreiten anpassen
ws.column_dimensions['A'].width = 20
ws.column_dimensions['B'].width = 10
ws.column_dimensions['C'].width = 15
ws.column_dimensions['D'].width = 15
# Ausgabeverzeichnis erstellen
output_dir = Path("output")
output_dir.mkdir(exist_ok=True)
# Datei speichern
output_file = output_dir / f"example_{datetime.now().strftime('%Y%m%d_%H%M%S')}.xlsx"
wb.save(output_file)
print(f"Excel-Datei erfolgreich erstellt: {output_file}")
return output_file
try:
# Neues Workbook erstellen
wb = Workbook()
ws = wb.active
ws.title = "Beispiel"
# Überschriften hinzufügen
headers = ["Name", "Alter", "Stadt", "Beruf"]
ws.append(headers)
# Überschriften formatieren
header_fill = PatternFill(start_color="4472C4", end_color="4472C4", fill_type="solid")
header_font = Font(bold=True, color="FFFFFF", size=12)
for cell in ws[1]:
cell.fill = header_fill
cell.font = header_font
cell.alignment = Alignment(horizontal="center", vertical="center")
# Beispieldaten hinzufügen
data = [
["Max Mustermann", 30, "Berlin", "Entwickler"],
["Erika Musterfrau", 28, "München", "Designerin"],
["Hans Schmidt", 35, "Hamburg", "Manager"],
["Anna Weber", 27, "Köln", "Analyst"],
]
for row in data:
ws.append(row)
# Spaltenbreiten anpassen
ws.column_dimensions['A'].width = 20
ws.column_dimensions['B'].width = 10
ws.column_dimensions['C'].width = 15
ws.column_dimensions['D'].width = 15
# Ausgabeverzeichnis erstellen
output_dir = Path("output")
try:
output_dir.mkdir(exist_ok=True)
except PermissionError:
print(f"❌ Fehler: Keine Berechtigung zum Erstellen des Verzeichnisses '{output_dir}'")
raise
except OSError as e:
print(f"❌ Fehler beim Erstellen des Verzeichnisses '{output_dir}': {e}")
raise
# Datei speichern
output_file = output_dir / f"example_{datetime.now().strftime('%Y%m%d_%H%M%S')}.xlsx"
try:
wb.save(output_file)
except PermissionError:
print(f"❌ Fehler: Keine Berechtigung zum Speichern der Datei '{output_file}'")
raise
except OSError as e:
print(f"❌ Fehler beim Speichern der Datei '{output_file}': {e}")
raise
print(f"Excel-Datei erfolgreich erstellt: {output_file}")
return output_file
except Exception as e:
print(f"❌ Unerwarteter Fehler beim Erstellen der Excel-Datei: {e}")
raise
if __name__ == "__main__":

View file

@ -9,53 +9,80 @@ from pathlib import Path
def read_excel_to_dict(filepath):
"""Liest eine Excel-Datei und gibt die Daten als Dictionary zurück."""
wb = load_workbook(filepath, data_only=True)
try:
wb = load_workbook(filepath, data_only=True)
except FileNotFoundError:
print(f"❌ Fehler: Datei '{filepath}' nicht gefunden")
raise
except PermissionError:
print(f"❌ Fehler: Keine Berechtigung zum Lesen der Datei '{filepath}'")
raise
except Exception as e:
print(f"❌ Fehler beim Laden der Excel-Datei '{filepath}': {e}")
raise
result = {}
for sheet_name in wb.sheetnames:
ws = wb[sheet_name]
# Daten aus dem Sheet lesen
data = []
for row in ws.iter_rows(values_only=True):
# Nur Zeilen mit Inhalt
if any(cell is not None for cell in row):
data.append(list(row))
result[sheet_name] = data
try:
for sheet_name in wb.sheetnames:
ws = wb[sheet_name]
# Daten aus dem Sheet lesen
data = []
for row in ws.iter_rows(values_only=True):
# Nur Zeilen mit Inhalt
if any(cell is not None for cell in row):
data.append(list(row))
result[sheet_name] = data
except Exception as e:
print(f"❌ Fehler beim Lesen der Daten aus der Excel-Datei: {e}")
raise
return result
def print_excel_content(filepath):
"""Gibt den Inhalt einer Excel-Datei formatiert aus."""
print(f"\n{'='*60}")
print(f"Excel-Datei: {filepath}")
print(f"{'='*60}\n")
data = read_excel_to_dict(filepath)
for sheet_name, rows in data.items():
print(f"\n📊 Sheet: {sheet_name}")
print(f"{'-'*60}")
if not rows:
print(" (leer)")
continue
# Tabelle ausgeben
for i, row in enumerate(rows, 1):
row_str = " | ".join(str(cell) if cell is not None else "" for cell in row)
print(f" {i:3d}: {row_str}")
print(f"\n{'='*60}\n")
# Als JSON ausgeben
print("📄 JSON-Format:")
print(json.dumps(data, indent=2, ensure_ascii=False))
try:
data = read_excel_to_dict(filepath)
except Exception:
# Error already printed in read_excel_to_dict
raise
try:
for sheet_name, rows in data.items():
print(f"\n📊 Sheet: {sheet_name}")
print(f"{'-'*60}")
if not rows:
print(" (leer)")
continue
# Tabelle ausgeben
for i, row in enumerate(rows, 1):
row_str = " | ".join(str(cell) if cell is not None else "" for cell in row)
print(f" {i:3d}: {row_str}")
print(f"\n{'='*60}\n")
# Als JSON ausgeben
print("📄 JSON-Format:")
try:
print(json.dumps(data, indent=2, ensure_ascii=False))
except (TypeError, ValueError) as e:
print(f"❌ Fehler beim Konvertieren zu JSON: {e}")
raise
except Exception as e:
print(f"❌ Fehler beim Ausgeben der Excel-Daten: {e}")
raise
return data