8.5 KiB
8.5 KiB
Ziel
Eine Python + Streamlit App für Windows, die aus einer Input-Excel-Datei (ein Sheet pro Monat mit Mitarbeiterdaten) und einem Excel-Template pro Mitarbeiter eine Excel-Datei generiert (ein Sheet pro Monat, befüllt mit dessen Daten).
Ansatz: Verwendung von openpyxl für Single-Input-File + Streamlit-UI.
Aufgabe
Erstelle eine Windows App in dessen Oberfläche aus folgenden Bestandteilen aufgebaut ist:
- mittels einem DropDown-Menü kann eine Datei aus dem inputfolder gewählt werden
- mittels einem DropDown-Menü kann ein Template aus dem Templatefolder gewählt werden
- ein Button um den Vorgang zu starten
Die Funktion der App besteht darin, das Templatefile mit Daten aus dem Input-File zu befüllen. Im Inputfile ist für alle Monate eines Jahres eine Liste aller Mitarbeitenden und in den Spalten alle Daten zur Befüllung des Template files.
Aufbau Input Datei
- In der Input Datei ist für jeden Monat eines Jahres ein Sheet gespeichert.
- In jedem Sheet befindet sich eine Tabelle (felder speichern in Input Schema json) mit Mitarbeitenden.
- Für jeden Mitarbeitenden soll aus dem Template eine neue ExcelDatei erzeugt werden, welche auch wieder für jeden Monat ein Sheet des Templates enthält und alle Daten des Mitarbeiters für dieses Monat aus der Inputliste enthält.
README
In der README.md ist ein kleine Doku wie das Programm zu benutzen ist und welche Konfigurationsparameter es gibt.
Phasen-Plan
Phase 1: Projekt-Grundgerüst & Konfiguration
requirements.txtbefüllen —streamlit,openpyxlconfig/settings.inibefüllen — Pfade, Standardwerte- Abschnitte:
[paths](input_dir, template_dir, output_dir),[output](filename_pattern)
- Abschnitte:
config/input-fields.jsonSchema definieren — Spalten der Input-Tabelle mit ihren exakten Überschriften- Wird durch Analyse der Datei
input/2025 JM.xlsxermittelt: Spaltenposition (A, B, C…) und die exakte Spaltenüberschrift aus Zeile 1 der jeweiligen Sheets - JSON-Array mit
column(Spaltenbuchstabe),field_name(exakte Überschrift aus der Excel-Tabelle),type(string|number|date),required(true|false)
- Wird durch Analyse der Datei
config/output-fields.jsonMapping definieren — Welche Input-Felder (exakte Spaltenüberschrift) in welche Template-Zellen geschrieben werden- JSON-Array mit
source_field(exakte Spaltenüberschrift aus der Input-Tabelle, wie in input-fields.json definiert),target_cell(Zelladresse im Template, z.B. "A17"),format(optional, z.B. "dd.mm.yyyy") - Muss durch Analyse des Templates
template/Tätigkeitsnachweise Stellenförderung.xlsxermittelt werden (welche Zellen sind zu befüllen?)
- JSON-Array mit
Phase 2: Core-Module (src/)
src/__init__.py+src/models.py— DatenklassenEmployeeRecord: name, vorname, nachname, antragsnummer, qualifikation, funktion, taetigkeit, stellenanteil, monat, jahr, … (Felder aus input-fields.json)AppConfig: geladene settings.ini + input/output-schemas
src/config.py— Konfigurations-Loaderload_settings(): liestconfig/settings.inimitconfigparserload_input_schema(): liestconfig/input-fields.jsonload_output_mapping(): liestconfig/output-fields.jsonget_available_input_files(): listet.xlsx-Dateien ininput/get_available_templates(): listet.xlsx-Dateien intemplate/
src/parser.py— Input-Datei einlesenparse_input_file(filepath, schema): öffnet Workbook, iteriert über alle Sheets (Monate)- Extrahiert Monat/Jahr aus Sheet-Namen oder Sheet-Inhalt
- Für jedes Sheet: liest Zeilen anhand des Schemas, erzeugt
EmployeeRecord-Liste - Rückgabe:
dict[str, list[EmployeeRecord]](key = Mitarbeiter-Name)
Phase 3: Writer & Validierung
src/writer.py— Output generierengenerate_activity_reports(employee_records, template_path, mapping, config):- Gruppiert Records nach Mitarbeiter
- Für jeden Mitarbeiter: lädt Template, erstellt für jeden Monat ein Sheet (kopiert Template-Sheet)
- Befüllt Zielzellen gemäß output-fields.json Mapping
- Benennt Sheets nach Monat (z.B. "01_Januar", "02_Februar", …)
- Speichert als
{nachname}_{vorname}_{YYYY}_Tätigkeitsnachweis.xlsxinoutput/
src/validator.py— Eingabevalidierungvalidate_input_file(filepath, schema): prüft Datei-Existenz, Sheet-Anzahl, Spalten laut Schemavalidate_template(template_path, mapping): prüft ob alle target_cells im Template existieren
Phase 4: Streamlit UI
app.py— Streamlit-Oberfläche- Layout:
- Titel + Beschreibung
st.selectboxfür Input-Datei (ausinput/-Folder)- Sofort bei Auswahl: Validierung + Parsing der Datei
- Anzeige: Anzahl gefundener Mitarbeiter, Auflistung aller enthaltenen Antragsnummern
- Bei Fehlern:
st.errormit Details
st.selectboxfür Template (austemplate/-Folder)- Sofort bei Auswahl: Validierung des Templates gegen
output-fields.json - Anzeige: Anzahl gefundener Zielfelder (target_cells), fehlende/fehlerhafte Zellen
- Bei Fehlern:
st.warningmit Details
- Sofort bei Auswahl: Validierung des Templates gegen
- Mitarbeiter-Liste (erscheint nach erfolgreicher Input-Validierung)
st.multiselectmit allen gefundenen Mitarbeiternamen, standardmäßig alle vorselektiert- Nicht selektierte Mitarbeiter werden bei der Generierung übersprungen
- Zeigt: „X von Y Mitarbeitern ausgewählt"
st.button("Tätigkeitsnachweise generieren")
- Bei Button-Click:
- Filtere Employee Records auf selektierte Mitarbeiter
- Generiere Activity Reports nur für selektierte Mitarbeiter und speichere in
output/ - Zeige Erfolgsmeldung mit Liste der erstellten Dateien via
st.success
- Status-Anzeige mit
st.spinnerundst.progress
- Layout:
Phase 5: Start-Skript & Doku
start.bat— Windows Batch-Startdatei- Prüft ob Python verfügbar ist
- Installiert Requirements (falls nötig)
- Startet
streamlit run app.py
README.mdaktualisieren — Vollständige Doku- Setup-Anleitung (Python, venv, pip install)
- Konfiguration (settings.ini, input-fields.json, output-fields.json)
- Bedienung (Datei auswählen, Template wählen, Button klicken)
- Erwartetes Input-Format (Spalten, monatliche Sheets)
- Output-Beschreibung (Dateiname, Struktur)
Relevante Dateien (zu erstellen/ändern)
| Datei | Aktion |
|---|---|
requirements.txt |
Neu befüllen |
config/settings.ini |
Neu befüllen |
config/input-fields.json |
Neu befüllen (nach Analyse Input-Datei) |
config/output-fields.json |
Neu befüllen (nach Analyse Template) |
src/__init__.py |
Neu (leer) |
src/models.py |
Neu |
src/config.py |
Neu |
src/parser.py |
Neu |
src/writer.py |
Neu |
src/validator.py |
Neu |
app.py |
Neu |
start.bat |
Neu |
README.md |
Überschreiben mit vollständiger Doku |
Projektstruktur
/
├── .copilot/
│ ├── PLAN.md ← diese Datei
│ └── TASKS.md ← Aufgabenliste
├── input/
│ └── *.xlsx ← Tabelle mit den Input-daten
├── config/
│ ├── settings.ini ← Einstellungen der App
│ ├── input-fields.json ← Schema der Inputdaten-Tabelle
│ └── output-fields.json ← Schema der Outputdaten-Tabelle
├── output/ ← Zielordner für generierte Dateien
├── src/
│ ├── __init__.py
│ ├── models.py
│ ├── config.py
│ ├── parser.py
│ ├── writer.py
│ └── validator.py
├── app.py ← Streamlit-App
├── start.bat ← Windows batch zum Start der App
├── README.md ← README für Programmbenutzer
└── requirements.txt ← streamlit, openpyxl
Verifikation
- Input-Datei-Analyse:
2025 JM.xlsxmit openpyxl öffnen, Sheet-Namen prüfen, exakte Spaltenüberschriften aus Zeile 1 jedes Sheets auslesen →input-fields.jsonableiten (Spaltenbuchstabe + original Feldname) - Template-Analyse:
Tätigkeitsnachweise Stellenförderung.xlsxöffnen, belegte/freie Zellen inspizieren, die befüllt werden sollen →output-fields.jsonableiten (Mapping: Input-Spaltenüberschrift → Template-Zelladresse) - Unit-Test: App mit vorhandener Input-Datei und Template ausführen, prüfen ob Output-Dateien korrekt befüllt sind
- Edge Cases: Leere Input-Zeilen, fehlende Monate, Mitarbeiter ohne Vorname, Sonderzeichen in Namen