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:
parent
8821bee816
commit
b9d8e7094b
6 changed files with 534 additions and 270 deletions
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
250
src/calculate.py
250
src/calculate.py
|
|
@ -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__":
|
||||
|
|
|
|||
|
|
@ -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__":
|
||||
|
|
|
|||
111
src/main.py
111
src/main.py
|
|
@ -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__":
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
|||
Reference in a new issue