Flask zur PDF Erstellung

Django, Flask, Bottle, WSGI, CGI…
Antworten
Deon
User
Beiträge: 3
Registriert: Donnerstag 16. April 2020, 16:31

Hallo hier in die Runde,

ich versuche gerade mit Hilfe von flask und flask_weasyprint CSV Dateien in PDFs umzuwandeln.
Es geht um Preislisten in drei Sprachen. Die CSV enthält Artikelbezeichnungen in deutsch, englisch und französisch.

Meine Herausforderung besteht aus mehreren Anforderungen:
1. Es müssen drei unterschiedliche PDFs aus einer CSV erstellt werden. Dieses habe ich soweit mit 3 Dictionaries gelöst, welche ich an 3 Templates verweise.
2. Die PDFs müssen auf einen Windows Server ausgespielt werden. Diese App wird in einem Docker Container laufen. Ich werde die PDFs ggf. auch mit einem Shell Skript an den Windows Server senden. Das weiß ich noch nicht.
3. Flask wird hier nie als Webserver verwendet werden müssen, sondern lediglich als Mittel die PDFs zu erstellen. Mit Hilfe der Template Engine konnte ich bereits manuell PDFs erstellen.

Hier meine Frage an die Community:
Ist Flask das richtige Werkzeug für diese Aufgabe? Und kann ich es so triggern, dass es sich lediglich die CSV greift, wenn sie ankommt, die 3 PDFs ausspielt und dann zurückfährt um auf die nächste CSV zu warten?

Wie würdet Ihr versuchen diese Aufgabe umzusetzen?

Ich freu mich auf eure Antworten!

Beste Grüße
Deon
einfachTobi
User
Beiträge: 491
Registriert: Mittwoch 13. November 2019, 08:38

Ich würde zunächst ein Modul verwenden, welches dafür gedacht ist. Zum Beispiel: https://www.reportlab.com/dev/opensource/rl-toolkit/.
Das Überwachen des Dateisystems kannst du mit Watchdog realisieren. Je nachdem wie die PDFs auf den anderen PC kommen sollen, gibt's da auch Lösungen (FTP, Shares, was auch immer)
Sirius3
User
Beiträge: 17751
Registriert: Sonntag 21. Oktober 2012, 17:20

Wenn Du Flask nicht brauchst, warum nimmst Du dann flask_weasyprint statt einfach nur weasyprint?
Was meinst Du mit ´ausspielen`? Normalerweise legt man pdf-Dateien einfach in ein Verzeichnis, da ist es egal, ob das ein Windows-Server ist, oder was ordentliches.
Und warum Docker-Container? Warum nicht gleich unter Windows?
Und woher kommen die csv-Dateien? Verzeichnisse kann man überwachen lassen.
Was meinst Du mit `zurückfahren`?
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

wenn du nur die Template Engine brauchst, dann nimm' doch nur Jinja2 und nicht komplett Flask.
Aber wie einfachTobi schon sagte: ReportLab ist eigentlich das Modul für Python zum bauen von PDFs.

Kurzes Beispiel:

CSV-Datei:
deutsch;englisch;preis
Auto;car;30000
Flugzeug;aircraft;5000000
Boot;boat;2500
Code:

Code: Alles auswählen

import csv
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.platypus import SimpleDocTemplate, Paragraph
from reportlab.platypus.tables import Table

story = {'de': [], 'en': []}
data = {'de': [], 'en': []}

with open('preise.csv', newline='') as csv_file:
    reader = csv.DictReader(csv_file, delimiter=';')
    for row in reader:
        data['de'].append([row['deutsch'], row['preis']])
        data['en'].append([row['englisch'], row['preis']])
styles = getSampleStyleSheet()
style = styles['h1']
story['de'].append(Paragraph('Preisliste Deutsch', style))
story['de'].append(Table(data['de'], hAlign='LEFT'))
story['en'].append(Paragraph('Price List English', style))
story['en'].append(Table(data['en'], hAlign='LEFT'))
doc_de = SimpleDocTemplate('preisliste.pdf')
doc_en = SimpleDocTemplate('pricelist.pdf')
doc_de.build(story['de'])
doc_en.build(story['en'])
Das erzeugt zwei einfache PDF Dateien. Du hast bei ReportLab noch ca. 1 Millionen Möglichkeiten, dass PDF zu stylen, inkl. sich wiederholenden Kopf- und Fusszeilen etc.

Gruß, noisefloor
Sirius3
User
Beiträge: 17751
Registriert: Sonntag 21. Oktober 2012, 17:20

@noisefloor: mit weasyprint kann man viel einfacher ein ansprechendes Design erstellen, weil man in HTML designen kann.

Code: Alles auswählen

import jinja2
from weasyprint import HTML

BASEPATH = os.path.dirname(__file__)
loader = jinja2.FileSystemLoader(BASEPATH)
environment = jinja2.Environment(autoescape=True, loader=loader)
template = environment.get_template('report.html')
HTML(string=template.render(parameter)).write_pdf(pdf_filename)
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,
mit weasyprint kann man viel einfacher ein ansprechendes Design erstellen, weil man in HTML designen kann.
Würde ich pauschal so nicht unterschreiben, weil HTML nun mal nicht für Print gemacht ist. Bei 1-seitigen Dokumenten bin ich bei dir, bei mehrseitigen inkl. Umsetzung von Corporate Design, vielleicht ein TOC, detaillierte Umbruchkontrolle ist IMHO ReportLab stärker.

Gruß, noisefloor
Sirius3
User
Beiträge: 17751
Registriert: Sonntag 21. Oktober 2012, 17:20

@noisefloor: auch für mehrseitige Dokumente bietet HTML Standards an, die von Weasy auch genutzt werden.
Ultimativ die besten Ergebnisse liefert natürlich nur PdfLaTeX.
Deon
User
Beiträge: 3
Registriert: Donnerstag 16. April 2020, 16:31

Hallo,

vielen Dank für eure Antworten. Und danke für das Schnipsel zur Umsetzung mit reportlab.
Ich muss gestehen, dass Reportlab auf mich einen zu abstrakten Eindruck macht, weshalb ich mich für eine HTML Lösung entscheiden wollte.
Letztendlich habe ich jetzt erstmal nur mit Jinja und Weasyprint ein zufriedenstellendes Ergebnis erreichen können, sehe aber noch viele Punkt die ich verbessern könnte. Aber die Frage ob ich Flask überhaupt hierfür bräuchte, ließ mich hier natürlich nur über die Template Engine nachdenken - und ja, das klappt schonmal erstaunlich gut.
Gibt es eine gute Einführung in ReportLab?
Ist es so, dass ich im Grunde das gesamte Layout als Funktionen schreibe? Ich muss gestehen, mit ReportLab hab ich mich am allerwenigsten befasst, weshalb ich in dem Bereich ein kompletter Noob bin.

Die Nuss die ich nun noch für mich knacken muss ist das speichern der PDFs auf dem Windows Server. Meine erste Idee hier war es mit Hilfe von smbprotocol zu gucken ob ich einen Zugriff auf in die Windowswelt bekomme.
Hat hier jemand Erfahrungen mit? Gibt es hier womöglich einen besseren Weg?

Vielen Dank nochmal für eure Antworten und Hilfen!!
Beste Grüße
Deon
Benutzeravatar
__blackjack__
User
Beiträge: 13111
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Deon: Musst Du das denn unbedingt im Programm lösen? Kannst Du nicht einfach eine Windowsfreigabe auf dem Rechner einbinden wo Dein Programm läuft?
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Sirius3
User
Beiträge: 17751
Registriert: Sonntag 21. Oktober 2012, 17:20

Wenn es mit weasyprint gut funktioniert, dann braucht Du doch kein ReportLab. Was gefällt Dir daran noch nicht?
Zum Zugriff auf Windows-Shares bietet Samba auch Client-Tools.
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,
Gibt es eine gute Einführung in ReportLab? Ist es so, dass ich im Grunde das gesamte Layout als Funktionen schreibe?
Die Doku von ReportLab ist ziemlich umfangreich. Die wirkt zwar manchmal komisch strukturiert, steht aber alles drin. Es gibt aber im Netz auch relativ viele Beispiele zu ReportLab.

Und ja, du instanzierst bei ReportLab eine Reihe von Klassen und nutzt deren Methoden.

ReportLab ist nicht wirklich kompliziert, ist aber auch nichts, was man "einfach so" mal lernt. Von daher ist die Frage von Sirius3 sehr berechtigt: warum wechseln, wenn es mit Weasyprint zufriedenstellend klappt?

Gruß, noisefloor
Deon
User
Beiträge: 3
Registriert: Donnerstag 16. April 2020, 16:31

Ja, das ist schon richtig. Wieso was anderes machen, wenn das eine schon klappt. Ich glaube mit HTML & CSS bekomm ich erstmal alles hin was ich hier machen muss.

Im Moment läuft dieses Skript in einem Docker Container. Es empfängt via sockets die CSV, erstellt mit jinja2 & weasyprint die PDFs und lässt sie dann entweder im Docker Container oder auf dem Volume liegen.
Ich weiß noch nicht genau was der beste/sicherste/schnellste/einfachste Weg ist diese PDFs nun in den Windows Ordner zu bekommen.
Mounte ich den Windows Ordner in den Container(Kann ich das überhaupt? Ist das das was Du, __blackjack__ meinst?)?
Gehe ich den Samba Weg in Python und behalte somit den Transfer im gleichen Skript wie die PDF Erstellung?
Schreib ich ein Shell Skript, welches die PDFs dann sobald sie erstellt sind nach Windows schiebt?
Ich hab in diesem Bereich leider wenig Erfahrung.

Ich freu mich aber sehr über die Unterstützung und danke euch nochmals für die Zeit die ihr hier investiert. Wirklich hilfreich! 1000 Dank :) 8)
Antworten