use static font size over all document texts

This commit is contained in:
Rob committed 2026-06-30 09:43:25 +02:00
1 parent 23cb3c35b3
commit 2247c42e81
6 files changed
+16 -36

No files matched your search

+2
View File
@@ -21,6 +21,7 @@ def load_settings(config_dir: Path, project_root: Path) -> AppConfig:
paths = parser["paths"] if "paths" in parser else {}
output = parser["output"] if "output" in parser else {}
parsing = parser["parsing"] if "parsing" in parser else {}
font = parser["font"] if "font" in parser else {}
return AppConfig(
input_dir=str(project_root / paths.get("input_dir", "input")),
@@ -30,6 +31,7 @@ def load_settings(config_dir: Path, project_root: Path) -> AppConfig:
month_sheet_pattern=parsing.get("month_sheet_pattern", "* 20??"),
skip_empty_name=parsing.getboolean("skip_empty_name", True),
skip_empty_antragsnummer=parsing.getboolean("skip_empty_antragsnummer", True),
fontsize=font.getfloat("fontsize", 11.0),
)
+1
View File
@@ -63,6 +63,7 @@ class AppConfig:
month_sheet_pattern: str = "* 20??"
skip_empty_name: bool = True
skip_empty_antragsnummer: bool = True
fontsize: float = 11.0
@dataclass
+7 -36
View File
@@ -101,6 +101,7 @@ def _get_field_value(record: EmployeeRecord, employee_name: str, source_field: s
def _scan_template_fields(
template_path: Path,
mapping: list[OutputMapping],
fontsize: float,
) -> dict[str, dict]:
"""
Scannt ALLE Seiten des PDF-Templates nach _Field-Platzhaltern.
@@ -117,7 +118,7 @@ def _scan_template_fields(
field_info: dict[str, dict] = {}
# 1. Per search_for die Rechtecke aller PDF-Feld-Marker finden (alle Seiten)
# Per search_for die Rechtecke aller PDF-Feld-Marker finden (alle Seiten)
for pdf_field, source_field in pdf_to_source.items():
found_any = False
for page_num in range(doc.page_count):
@@ -128,7 +129,7 @@ def _scan_template_fields(
"source_field": source_field,
"page_num": page_num,
"rect": found[0],
"fontsize": 11, # Fallback
"fontsize": fontsize,
"fontname": "helv",
}
found_any = True
@@ -136,23 +137,6 @@ def _scan_template_fields(
if not found_any:
field_info[pdf_field] = None # nicht gefunden
# 2. Schriftgrößen aus den Text-Details extrahieren (alle Seiten)
for page_num in range(doc.page_count):
page = doc[page_num]
text_dict = page.get_text("dict")
for block in text_dict.get("blocks", []):
if "lines" not in block:
continue
for line in block["lines"]:
for span in line["spans"]:
text = span["text"].strip()
if text.endswith("_Field") and text in field_info:
info = field_info[text]
if info is not None:
info["fontsize"] = span["size"]
info["fontname"] = span.get("font", "helv")
info["rect"] = fitz.Rect(span["bbox"])
doc.close()
return field_info
@@ -167,17 +151,13 @@ def _fill_pdf_pages(
employee_name: str,
mapping: list[OutputMapping],
field_info: dict[str, dict],
fontsize: float,
) -> None:
"""Befüllt alle Template-Seiten: redacted _Field-Platzhalter und fügt echte Daten ein."""
# Mehrzeilige Felder, die als Textbox (mit Zeilenumbruch) behandelt werden
MULTILINE_FIELDS = {"Tätigkeiten_Field", "Dienstreisen_Field"}
TEXTBOX_WIDTH_PT = 400 # Breite der Textbox in Punkt
# Felder mit automatischer Schriftgrößen-Anpassung bei langem Text
AUTOSCALE_FIELDS = {"Qualifikation_Field", "Funktion_Field"}
AUTOSCALE_MAX_CHARS = 35 # ab dieser Länge wird verkleinert
AUTOSCALE_MIN_FACTOR = 0.75 # minimale Schriftgröße relativ zum Original
for m in mapping:
if m.pdf_field is None:
continue
@@ -192,7 +172,6 @@ def _fill_pdf_pages(
page = pages[page_num]
rect = info["rect"]
fontsize = info.get("fontsize", 11)
value = _get_field_value(record, employee_name, m.source_field)
formatted = _format_value(value, m.format)
@@ -204,15 +183,6 @@ def _fill_pdf_pages(
if not formatted:
continue
# Automatische Schriftgrößen-Anpassung für lange Texte
if m.pdf_field in AUTOSCALE_FIELDS and len(formatted) > AUTOSCALE_MAX_CHARS:
text_width = fitz.get_text_length(formatted, fontname="helv", fontsize=fontsize)
available_width = rect.width
if text_width > available_width:
factor = available_width / text_width
factor = max(factor, AUTOSCALE_MIN_FACTOR)
fontsize = fontsize * factor
# Mehrzeilige Felder: Zeilenweise per insert_text schreiben
if m.pdf_field in MULTILINE_FIELDS:
# Doppelte Leerzeilen entfernen
@@ -269,6 +239,7 @@ def generate_activity_reports(
mapping: list[OutputMapping],
output_dir: Path,
filename_pattern: str,
fontsize: float = 11.0,
) -> list[Path]:
"""
Erzeugt für jeden Mitarbeiter ein PDF.
@@ -278,7 +249,7 @@ def generate_activity_reports(
generated_files: list[Path] = []
# Pre-Scan: Feld-Positionen auf allen Template-Seiten ermitteln
field_info = _scan_template_fields(template_path, mapping)
field_info = _scan_template_fields(template_path, mapping, fontsize)
for employee_name, records in employee_records.items():
if not records:
@@ -301,7 +272,7 @@ def generate_activity_reports(
temp_doc = fitz.open(template_path)
pages = [temp_doc[i] for i in range(temp_doc.page_count)]
_fill_pdf_pages(pages, record, employee_name, mapping, field_info)
_fill_pdf_pages(pages, record, employee_name, mapping, field_info, fontsize)
# Alle modifizierten Seiten ins Ergebnis-PDF einfügen
result_doc.insert_pdf(temp_doc)