3 Commits
2 changed files with 44 additions and 19 deletions

No files matched your search

+1 -1
View File
@@ -239,7 +239,7 @@ if st.session_state.input_validated and st.session_state.parsed_records:
key = f"sel_{emp}" key = f"sel_{emp}"
if key not in st.session_state: if key not in st.session_state:
st.session_state[key] = True st.session_state[key] = True
if st.checkbox(emp, value=st.session_state[key], key=key): if st.checkbox(emp, key=key):
selected_employees.append(emp) selected_employees.append(emp)
st.caption(f"{len(selected_employees)} von {len(employees)} Mitarbeitern ausgewählt") st.caption(f"{len(selected_employees)} von {len(employees)} Mitarbeitern ausgewählt")
+43 -18
View File
@@ -171,9 +171,12 @@ def _fill_pdf_pages(
"""Befüllt alle Template-Seiten: redacted _Field-Platzhalter und fügt echte Daten ein.""" """Befüllt alle Template-Seiten: redacted _Field-Platzhalter und fügt echte Daten ein."""
# Mehrzeilige Felder, die als Textbox (mit Zeilenumbruch) behandelt werden # Mehrzeilige Felder, die als Textbox (mit Zeilenumbruch) behandelt werden
MULTILINE_FIELDS = {"Tätigkeiten_Field", "Dienstreisen_Field"} MULTILINE_FIELDS = {"Tätigkeiten_Field", "Dienstreisen_Field"}
TEXTBOX_FONT_SCALE = 1 # Schriftgrößen-Faktor für Textboxen
TEXTBOX_WIDTH_PT = 400 # Breite der Textbox in Punkt TEXTBOX_WIDTH_PT = 400 # Breite der Textbox in Punkt
TEXTBOX_HEIGHT_PT = 120 # Höhe 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: for m in mapping:
if m.pdf_field is None: if m.pdf_field is None:
@@ -201,7 +204,16 @@ def _fill_pdf_pages(
if not formatted: if not formatted:
continue continue
# Mehrzeilige Felder: insert_textbox mit Zeilenumbruch # 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: if m.pdf_field in MULTILINE_FIELDS:
# Doppelte Leerzeilen entfernen # Doppelte Leerzeilen entfernen
clean_text = "\n".join( clean_text = "\n".join(
@@ -210,21 +222,34 @@ def _fill_pdf_pages(
if not clean_text: if not clean_text:
continue continue
# Rechteck für die Textbox: ausgehend vom Marker, nach rechts & unten erweitert # Zeilenweise mit automatischem Umbruch schreiben
textbox_rect = fitz.Rect( lines = clean_text.split("\n")
rect.x0, # links line_spacing = fontsize * 1.2 # Zeilenabstand
rect.y0, # oben y = rect.y0 + fontsize # Startposition (unterhalb Marker-Oberkante)
rect.x0 + TEXTBOX_WIDTH_PT, # rechts
rect.y0 + TEXTBOX_HEIGHT_PT, # unten for line in lines:
) # Wort-Umbruch: Zeile in Stücke passend zur Textbox-Breite aufteilen
page.insert_textbox( max_width = TEXTBOX_WIDTH_PT
textbox_rect, words = line.split(" ")
clean_text, current_line = ""
fontname="helv", for word in words:
fontsize=fontsize * TEXTBOX_FONT_SCALE, test_line = current_line + (" " if current_line else "") + word
lineheight=1.5, text_width = fitz.get_text_length(test_line, fontname="helv", fontsize=fontsize)
align=fitz.TEXT_ALIGN_LEFT, if text_width <= max_width or not current_line:
) current_line = test_line
else:
page.insert_text(
(rect.x0, y), current_line,
fontname="helv", fontsize=fontsize,
)
y += line_spacing
current_line = word
if current_line:
page.insert_text(
(rect.x0, y), current_line,
fontname="helv", fontsize=fontsize,
)
y += line_spacing
else: else:
page.insert_text( page.insert_text(
rect.bl, rect.bl,