Keine Zentrierung für Tätigkeiten. Doppeltes Datum anzeigen.
This commit is contained in:
1 parent
87f8150bd3
commit
8fde588b8f
3 files changed
+68
-73
No files matched your search
+68
-73
@@ -102,10 +102,10 @@ def _scan_template_fields(
|
||||
template_path: Path,
|
||||
mapping: list[OutputMapping],
|
||||
fontsize: float,
|
||||
) -> dict[str, dict]:
|
||||
) -> dict[str, list[dict]]:
|
||||
"""
|
||||
Scannt ALLE Seiten des PDF-Templates nach _Field-Platzhaltern.
|
||||
Rückgabe: dict[pdf_field] → {source_field, page_num, rect, fontsize, fontname, ...}
|
||||
Rückgabe: dict[pdf_field] → Liste von {source_field, page_num, rect, fontsize, fontname, ...}
|
||||
Felder mit pdf_field=None werden übersprungen.
|
||||
"""
|
||||
doc = fitz.open(template_path)
|
||||
@@ -116,26 +116,23 @@ def _scan_template_fields(
|
||||
if m.pdf_field is not None:
|
||||
pdf_to_source[m.pdf_field] = m.source_field
|
||||
|
||||
field_info: dict[str, dict] = {}
|
||||
field_info: dict[str, list[dict]] = {}
|
||||
|
||||
# Per search_for die Rechtecke aller PDF-Feld-Marker finden (alle Seiten)
|
||||
# Alle Vorkommen aller PDF-Feld-Marker finden (alle Seiten)
|
||||
for pdf_field, source_field in pdf_to_source.items():
|
||||
found_any = False
|
||||
occurrences: list[dict] = []
|
||||
for page_num in range(doc.page_count):
|
||||
page = doc[page_num]
|
||||
found = page.search_for(pdf_field)
|
||||
if found:
|
||||
field_info[pdf_field] = {
|
||||
for rect in found:
|
||||
occurrences.append({
|
||||
"source_field": source_field,
|
||||
"page_num": page_num,
|
||||
"rect": found[0],
|
||||
"rect": rect,
|
||||
"fontsize": fontsize,
|
||||
"fontname": "helv",
|
||||
}
|
||||
found_any = True
|
||||
break # erstes Vorkommen (seitenübergreifend)
|
||||
if not found_any:
|
||||
field_info[pdf_field] = None # nicht gefunden
|
||||
})
|
||||
field_info[pdf_field] = occurrences
|
||||
|
||||
doc.close()
|
||||
return field_info
|
||||
@@ -150,7 +147,7 @@ def _fill_pdf_pages(
|
||||
record: EmployeeRecord,
|
||||
employee_name: str,
|
||||
mapping: list[OutputMapping],
|
||||
field_info: dict[str, dict],
|
||||
field_info: dict[str, list[dict]],
|
||||
fontsize: float,
|
||||
) -> None:
|
||||
"""Befüllt alle Template-Seiten: redacted _Field-Platzhalter und fügt echte Daten ein."""
|
||||
@@ -162,76 +159,74 @@ def _fill_pdf_pages(
|
||||
if m.pdf_field is None:
|
||||
continue
|
||||
|
||||
info = field_info.get(m.pdf_field)
|
||||
if info is None:
|
||||
occurrences = field_info.get(m.pdf_field, [])
|
||||
if not occurrences:
|
||||
continue # Feld nicht im Template gefunden
|
||||
|
||||
page_num = info["page_num"]
|
||||
if page_num >= len(pages):
|
||||
continue
|
||||
|
||||
page = pages[page_num]
|
||||
rect = info["rect"]
|
||||
|
||||
value = _get_field_value(record, employee_name, m.source_field)
|
||||
formatted = _format_value(value, m.format)
|
||||
|
||||
# Platzhalter immer redacten, auch wenn kein Wert zum Einsetzen da ist
|
||||
page.add_redact_annot(rect)
|
||||
page.apply_redactions()
|
||||
|
||||
if not formatted:
|
||||
continue
|
||||
|
||||
# Mehrzeilige Felder: Zeilenweise per insert_text schreiben
|
||||
if m.pdf_field in MULTILINE_FIELDS:
|
||||
# Doppelte Leerzeilen entfernen
|
||||
clean_text = "\n".join(
|
||||
line for line in formatted.split("\n") if line.strip()
|
||||
)
|
||||
if not clean_text:
|
||||
# Jedes Vorkommen des Feldes im PDF befüllen
|
||||
for info in occurrences:
|
||||
page_num = info["page_num"]
|
||||
if page_num >= len(pages):
|
||||
continue
|
||||
|
||||
# Zeilenweise mit automatischem Umbruch schreiben
|
||||
lines = clean_text.split("\n")
|
||||
line_spacing = fontsize * 1.2 # Zeilenabstand
|
||||
page = pages[page_num]
|
||||
rect = info["rect"]
|
||||
|
||||
# Zuerst alle Ausgabezeilen sammeln, um Gesamthöhe zu berechnen
|
||||
output_lines: list[str] = []
|
||||
for line in lines:
|
||||
max_width = TEXTBOX_WIDTH_PT
|
||||
words = line.split(" ")
|
||||
current_line = ""
|
||||
for word in words:
|
||||
test_line = current_line + (" " if current_line else "") + word
|
||||
text_width = fitz.get_text_length(test_line, fontname="helv", fontsize=fontsize)
|
||||
if text_width <= max_width or not current_line:
|
||||
current_line = test_line
|
||||
else:
|
||||
output_lines.append(current_line)
|
||||
current_line = word
|
||||
if current_line:
|
||||
output_lines.append(current_line)
|
||||
# Platzhalter redacten
|
||||
page.add_redact_annot(rect)
|
||||
page.apply_redactions()
|
||||
|
||||
# Textblock oben beginnend schreiben
|
||||
y = rect.y0 + fontsize
|
||||
if not formatted:
|
||||
continue
|
||||
|
||||
for current_line in output_lines:
|
||||
page.insert_text(
|
||||
(rect.x0, y), current_line,
|
||||
fontname="helv", fontsize=fontsize,
|
||||
# Mehrzeilige Felder: Zeilenweise per insert_text schreiben
|
||||
if m.pdf_field in MULTILINE_FIELDS:
|
||||
# ... (unverändert)
|
||||
clean_text = "\n".join(
|
||||
line for line in formatted.split("\n") if line.strip()
|
||||
)
|
||||
if not clean_text:
|
||||
continue
|
||||
|
||||
lines = clean_text.split("\n")
|
||||
line_spacing = fontsize * 1.2
|
||||
|
||||
output_lines: list[str] = []
|
||||
for line in lines:
|
||||
max_width = TEXTBOX_WIDTH_PT
|
||||
words = line.split(" ")
|
||||
current_line = ""
|
||||
for word in words:
|
||||
test_line = current_line + (" " if current_line else "") + word
|
||||
text_width = fitz.get_text_length(test_line, fontname="helv", fontsize=fontsize)
|
||||
if text_width <= max_width or not current_line:
|
||||
current_line = test_line
|
||||
else:
|
||||
output_lines.append(current_line)
|
||||
current_line = word
|
||||
if current_line:
|
||||
output_lines.append(current_line)
|
||||
|
||||
y = rect.y0 + fontsize
|
||||
for current_line in output_lines:
|
||||
page.insert_text(
|
||||
(rect.x0, y), current_line,
|
||||
fontname="helv", fontsize=fontsize,
|
||||
)
|
||||
y += line_spacing
|
||||
else:
|
||||
# Einzeilige Felder: vertikal zentriert platzieren
|
||||
mid_y = (rect.y0 + rect.y1) / 2
|
||||
baseline_y = mid_y + fontsize * 0.35
|
||||
page.insert_text(
|
||||
(rect.x0, baseline_y),
|
||||
formatted,
|
||||
fontname="helv",
|
||||
fontsize=fontsize,
|
||||
)
|
||||
y += line_spacing
|
||||
else:
|
||||
# Einzeilige Felder: vertikal zentriert platzieren
|
||||
mid_y = (rect.y0 + rect.y1) / 2
|
||||
baseline_y = mid_y + fontsize * 0.35
|
||||
page.insert_text(
|
||||
(rect.x0, baseline_y),
|
||||
formatted,
|
||||
fontname="helv",
|
||||
fontsize=fontsize,
|
||||
)
|
||||
|
||||
|
||||
# ─────────────────────────────────────────────
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Reference in new issue
Block a user