Die Textseiten laufen durch Platypus: Inhalt fließt in einen Frame, und wenn der Frame voll ist, öffnet sich eine neue Seite mit demselben Header und Footer. Grundrisse und Galerien fließen nicht; sie bekommen einen eigenen Layout-Durchgang mit festen Positionen. Beide Wege enden auf demselben Canvas, also zählen die Fußzeilen weiterhin richtig.
Leistungen
Backend Engineering, Dokumentenautomatisierung
Branche
Immobilien
Jahr
2022-2024
Das 45-Minuten-Exposé
Ein Immobilien-Exposé kostete das Marketing-Team 45 Minuten in InDesign. Die Plattform hatte über 200 aktive Inserate, und jede Änderung an einem Inserat hieß: Dokument von Hand neu bauen. Nach wenigen Wochen hing das Team hinterher, und der Rückstand wuchs nur noch. Die Inserate waren online. Die Dokumente dazu nicht.
DIE HERAUSFORDERUNG
Manuelles Layout, 200 Inserate, keine Vorlage
Jedes Exposé bestand aus denselben Teilen: eine Titelseite mit Hero-Bild und einem Titelblock, der Titel von 10 bis 90 Zeichen aushalten musste, ein Factsheet mit konfigurierbaren Feldern und bis zu acht weitere Seiten mit Beschreibungen, Grundrissen und Galerien. Das Marketing-Team baute all das in InDesign nach, Inserat für Inserat, 45 Minuten pro Stück. Ein neuer Preis oder ein neues Foto bedeutete das ganze Dokument noch einmal. Nichts war als Vorlage angelegt, nichts versioniert. Keine zwei Leute lieferten exakt dasselbe Layout, und mit jeder neuen Kollegin und jedem neuen Kollegen entfernte sich das Ergebnis ein Stück weiter von der Marke.
DIE LÖSUNG
Ein Generator statt eines Konverters
Der schnelle Weg wäre HTML zu PDF mit wkhtmltopdf oder WeasyPrint gewesen: das Exposé als Webseite schreiben und eine Browser-Engine das Layout rechnen lassen. Das funktioniert für einfache Dokumente und scheitert genau an diesem: Bilder auf Zehntelmillimeter gegen die A4-Spezifikation platzieren, SVG-Logos an festen Koordinaten, und Fußzeilen, die eine Gesamtseitenzahl brauchen, die die Engine noch nicht kennt. Ich habe stattdessen ReportLab gewählt und eine CompanyPDF-Klasse geschrieben, rund 1.700 Zeilen Python, die das Dokument prozedural zeichnet. Platypus lässt den Text fließen und paginiert, die Titelseite misst ihren Titel und verkleinert die Schrift, bis er in seine Box passt, und eine kleine Canvas-Unterklasse hält jede Seite zurück, bis die letzte existiert. Der Preis: mehr Code und kein CSS. Der Gewinn: eine Ausgabe, die auf jedem Server identisch ausfällt, ohne Browser-Engine, die installiert, gepatcht und synchron gehalten werden muss.
Die Titelschleife der Titelseite: messen, um einen halben Punkt verkleinern, wieder messen, bis der String in die Box passt oder 16 pt erreicht:
Python
def _draw_title(self, canvas, title, box_width, box_y):
font_size = 42 # Start large
min_size = 16
while font_size > min_size:
w = canvas.stringWidth(title, self.font_bold, font_size)
if w <= box_width:
break
font_size -= 0.5
canvas.setFont(self.font_bold, font_size)
canvas.drawString(self.margin_left, box_y, title)Einen Titel einpassen, dann die Seiten nummerieren
Tipp einen Immobilientitel ein oder wähle ein Beispiel. Das Blatt ist eine skalierte A4-Seite und läuft dieselbe Schleife wie der Generator: von 42 pt in 0,5-pt-Schritten nach unten, bis der Text in die 515 pt breite Box passt, nie unter 16 pt. Darunter: Achte auf die Fußzeilen. Jede Seite sagt 'von ?', bis save() läuft.
Penthouse mit Panoramablick über die Stadt
Berlin · 4 Zimmer · 142 m²- Schriftgröße
- 21.5 pt
- Verkleinerungsschritte
- 41
- Textbreite
- 506 / 515 pt
- Ergebnis
- Passt in eine Zeile
Verzögerte Seitennummerierung7 Seiten bei save() nummeriert
- Seite 1 von 7
- Seite 2 von 7
- Seite 3 von 7
- Seite 4 von 7
- Seite 5 von 7
- Seite 6 von 7
- Seite 7 von 7
Die Canvas-Unterklasse hinter 'Seite X von Y'. showPage() puffert, save() nummeriert und schreibt:
Python
class NumberedCanvas(canvas.Canvas):
"""Defers page numbering until save()."""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._saved_pages = []
def showPage(self):
# Buffer the page instead of emitting it
self._saved_pages.append(dict(self.__dict__))
self._startPage()
def save(self):
total = len(self._saved_pages)
for i, state in enumerate(self._saved_pages, 1):
self.__dict__.update(state)
self.setFont("Helvetica", 9)
self.drawRightString(
self._pagesize[0] - 30,
20,
f"Page {i} of {total}"
)
super().showPage()
super().save()DAS ERGEBNIS
Das Marketing-Team macht keine PDFs mehr
Der Generator hat jedes Exposé übernommen. Inserat ändern, und die nächste Anfrage liefert ein neues Dokument. Niemand öffnet InDesign, niemand prüft, ob die Fußzeile noch die richtige Seitenzahl zeigt. Die Person, deren Woche aus Immobilien-PDFs bestand, arbeitet heute an anderen Themen, und die Marke sieht auf jedem Dokument gleich aus, weil genau eine Stelle ihr Aussehen definiert. Aus einer knappen Stunde pro Dokument wurden ein paar Sekunden, und die Warteschlange, die wochenlang gewachsen war, war einfach weg.
WICHTIGE KENNZAHLEN
<3sPro Exposé, generiert
6.000+Dokumente in 18 Monaten
1.700Zeilen Python
KUNDENSTIMME
Wir hatten eine Person, deren Woche aus Immobilien-PDFs bestand: neue Inserate, Preisänderungen, neue Fotos. Diese Arbeit ist weg. Die Dokumente kommen aus der Plattform, sehen alle gleich aus, und die Stelle macht heute etwas anderes.
Geschäftsführer
Immobilienplattform, Betrieb
FÜR DEIN PROJEKT
- Wann das passt
Du erzeugst immer wieder dasselbe gebrandete Dokument aus strukturierten Daten, und ein Mensch baut es nach jeder Änderung von Hand neu. Hier waren es Exposés; Angebote, Reports und Zertifikate haben dieselbe Form.
- Was du prüfen solltest
Ob alles, was das Dokument braucht, schon in einem Datensatz liegt: Titel, Preis, Felder, Bilder, der Link für den QR-Code. Wenn Teile davon nur in der Datei einer Designerin existieren, hat der Generator nichts zu lesen. Dann zähle Dokumente pro Monat und Minuten pro Dokument.
- Was es braucht
Eine Python-Backend-Entwicklerin oder einen -Entwickler, ReportLab, Markenelemente als SVG und einen Testsatz echter Titel von 10 bis 90 Zeichen. Keine Browser-Engine auf dem Server. Dieser Generator hat rund 1.700 Zeilen für Titelseite, Factsheet und bis zu acht Inhaltsseiten.
FAQ
TECHNOLOGIE-STACK
Django
Python
Dietmar Eglhofer - Geschäftsführer, Solvster & VIARESDaniel hat bei der Gründung und Umsetzung der Unternehmen Solvster und VIARES einen entscheidenden Beitrag geleistet. Er war verantwortlich für den gesamten technischen Aufbau der Onlinepräsenz, inklusive der Serversetups, der Entwicklung und Optimierung der Website sowie der Sicherstellung der Funktionalität. Besonders beeindruckt hat mich, wie proaktiv und lösungsorientiert er immer an Verbesserungen gearbeitet hat. Daniel war stets sehr responsiv und zuverlässig - es war eine Freude, mit ihm zusammenzuarbeiten. Seine Expertise und sein Engagement haben maßgeblich zum Erfolg beider Projekte beigetragen!
Tritt in die Fußstapfen von Dietmar und erwecke deine Vision zum Leben.
Frei für neue ProjekteSchreibe mir