2026-03-27 13:18:07 +01:00
2026-04-28 22:17:11 +02:00
2026-05-08 08:35:50 +02:00
2026-05-08 08:35:50 +02:00

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:

  1. config.json vorhanden und vollständig
  2. Excel-Datei existiert und ist eine .xlsx/.xlsm-Datei
  3. Jahr aus Dateiname extrahierbar (z. B. Anwesenheitsliste 2026.xlsx)
  4. Sheet-Name bekannt (in month_mapping der config.json)
  5. Sheet existiert in der Arbeitsmappe
  6. Spalte A (lfd. Nummer) enthält Daten
  7. Headerzeile mit Name, Vorname gefunden
  8. Tagesspalten ab Spaltenindex 9 vorhanden
  9. PDF-Template unter template/sab.pdf erreichbar

Windows-Installer erstellen

Der Build-Prozess erzeugt neben dem Programm auch einen Windows-Installer (.exe), der vom SMB-Netzlaufwerk gestartet werden kann.

Voraussetzung: Inno Setup 6

Inno Setup 6 muss auf der Build-Maschine installiert sein. Installation über winget:

winget install --id JRSoftware.InnoSetup -e -s winget -i

Alternativ manueller Download: https://jrsoftware.org/isinfo.php

Installer bauen

build.bat

build.bat führt alle vier Schritte automatisch aus:

  1. Abhängigkeiten installieren (pip install)
  2. Version aktualisieren (update_version.py)
  3. Programm packen (PyInstaller → dist\AnwesenheitPDF\)
  4. Installer kompilieren (ISCC.exe → dist\AnwesenheitPDF-Setup-x.y.z.exe)

Ist Inno Setup nicht installiert, wird Schritt 4 mit einer Warnung übersprungen — der PyInstaller-Output in dist\AnwesenheitPDF\ ist trotzdem nutzbar.

Installer verteilen

Die fertige Datei dist\AnwesenheitPDF-Setup-x.y.z.exe auf das SMB-Netzlaufwerk kopieren. Von dort kann sie direkt gestartet werden — ohne vorherige lokale Kopie.

Was der Installer macht

Aktion Details
Installationspfad %ProgramFiles%\AnwesenheitPDF\ (Admin erforderlich)
Startmenü-Eintrag AnwesenheitPDF
Desktop-Verknüpfung Optional (Checkbox im Wizard, Standard: deaktiviert)
Uninstaller Registriert unter Programme und Features
Windows-Version Windows 10 oder höher
S
Description
No description provided
Readme
890 KiB
0 Stars 1 Watchers 0 Forks
Languages
Python 93.8%
Batchfile 4.1%
Inno Setup 2.1%