add shared render_pdf_pages helper for consistent rasterization reuse the same renderer in regression test and CLI flow add new render-image CLI command to export PDF pages as PNG support single-page render (--page) and full export (--all-pages) add configurable output path and DPI options document the new rendering command and options in README
4.6 KiB
Anwesenheit PDF Generator
Liest Anwesenheitsdaten aus einer Excel-Datei (.xlsx) und erzeugt für jeden Teilnehmer eine ausgefüllte PDF-Datei (SAB-Formular).
Voraussetzungen
- Python 3.10 oder höher
- pip
Installation
# Abhängigkeiten installieren
pip install -r requirements.txt
Für Entwicklung inkl. Tests:
pip install -r requirements-dev.txt
Konfiguration
Vor dem ersten Start müssen zwei Werte in config.json eingetragen werden:
| Feld | Beschreibung |
|---|---|
antragsnummer |
SAB-Antragsnummer der Einrichtung |
ort |
Ort für die Unterschriftszeile im PDF |
Alle anderen Felder sind vorbelegt und müssen nur bei abweichender Excel-Struktur angepasst werden.
Verzeichnisstruktur
generate.py ← Einstiegspunkt
config.json ← Konfiguration
input/ ← Excel-Dateien ablegen
template/
sab.pdf ← PDF-Vorlage (muss vorhanden sein)
output/ ← Generierte PDFs (werden hier abgelegt)
Verwendung
Generierung starten
python generate.py generate --file "input/Anwesenheitsliste 2026.xlsx" --month Feb
Das Programm zeigt vor der Generierung eine Vorschau und fragt zur Bestätigung:
=== Vorschau der ermittelten Werte ===
Excel-Datei : Anwesenheitsliste 2026.xlsx
Jahr : 2026
Monat : Feb (02)
Antragsnummer : 12345
Ort : Leipzig
Erstelldatum : 27.03.2026
Teilnehmer : 49
Fehler : 0
Möchten Sie die PDF-Generierung starten? [j/N]
Nur bei Eingabe von j werden PDFs geschrieben.
Nur Validierung (keine PDFs erzeugen)
python generate.py validate --file "input/Anwesenheitsliste 2026.xlsx" --month Feb
Führt alle Prüfungen durch und zeigt die Vorschau — ohne Dateien zu schreiben.
PDF als Bild rendern
python generate.py render-image --pdf "output/(1) Mustermann, Max.pdf" --page 1 --out "preview.png"
Dieser Befehl rendert eine PDF-Seite als PNG-Bild. Er nutzt dieselbe Render-Funktion wie der Regressionstest, damit CLI-Vorschau und Testvergleich technisch identisch arbeiten.
Alle Seiten auf einmal rendern:
python generate.py render-image --pdf "output/(1) Mustermann, Max.pdf" --all-pages --out "render_out"
Optionen
generate
| Option | Pflicht | Beschreibung |
|---|---|---|
--file |
ja | Pfad zur Excel-Datei |
--month |
ja | Name des Monats-Sheets (z. B. Jan, Feb, Mrz, Apr …) |
--out |
nein | Ausgabeverzeichnis (Standard: output/ aus config.json) |
validate
| Option | Pflicht | Beschreibung |
|---|---|---|
--file |
ja | Pfad zur Excel-Datei |
--month |
ja | Name des Monats-Sheets |
render-image
| Option | Pflicht | Beschreibung |
|---|---|---|
--pdf |
ja | Pfad zur PDF-Datei |
--out |
nein | Zieldatei (Einzelseite) oder Zielordner (--all-pages) |
--dpi |
nein | Render-Auflösung in DPI (Standard: 150) |
--page |
nein | 1-basierte Seitennummer (Standard: 1) |
--all-pages |
nein | Rendert alle Seiten statt nur --page |
Sheet-Namen
Die deutschen Monatsabkürzungen entsprechen den Tabellenblatt-Namen in der Excel-Datei:
| Sheet | Monat |
|---|---|
Jan |
Januar |
Feb |
Februar |
Mrz |
März |
Apr |
April |
Mai |
Mai |
Jun |
Juni |
Jul |
Juli |
Aug |
August |
Sep |
September |
Okt |
Oktober |
Nov |
November |
Dez |
Dezember |
Ausgabe
Für jeden Teilnehmer wird eine PDF-Datei erstellt:
output/
(1) Mustermann, Max.pdf
(2) Beispiel, Anna.pdf
...
Die laufende Nummer entspricht der Nummerierung in Spalte A der Excel-Datei.
Tests ausführen
Alle Tests starten
pytest tests/ -v
Nur den Regression-Test. Der Test erwartet, dass im Ordner 2026_Feb die Excel-Datei und in reference/ die Ground-Truth-PDFs liegen. Er generiert PDFs in ein Temp-Verzeichnis und vergleicht sie pixelweise. Bei Abweichungen werden Diff-Bilder nach diff geschrieben.
python -m pytest tests/test_regression.py -v
Validierungsprüfungen
Das Programm prüft vor jeder Generierung:
config.jsonvorhanden und vollständig- Excel-Datei existiert und ist eine
.xlsx/.xlsm-Datei - Jahr aus Dateiname extrahierbar (z. B.
Anwesenheitsliste 2026.xlsx) - Sheet-Name bekannt (in
month_mappingderconfig.json) - Sheet existiert in der Arbeitsmappe
- Spalte A (lfd. Nummer) enthält Daten
- Headerzeile mit
Name, Vornamegefunden - Tagesspalten ab Spaltenindex 9 vorhanden
- PDF-Template unter
template/sab.pdferreichbar