Seite 1 von 1
Reportlab - Y-Position von letzter Tabellenzeile
Verfasst: Sonntag 3. Mai 2015, 12:11
von Nobuddy
Hallo zusammen,
ich erstelle mit Reportlab PDF-Dokumente (Rechnung, Lieferschein ...).
Die Auflistung der Daten, setze ich mittels einer Tabelle um, die auch über mehrere Seiten gehen können.
Die Erstellung der Dokumente mittels Reportlab, funktioniert problemlos.
Um ein Problem zu lösen, benötige ich bei der letzten Seite die Y-Position der letzten Tabellenzeile.
Gibt es eine Möglichkeit, diese Information zu erhalten?
BZW. welches Werkzeug von Reportlab ist dafür geeignet?
Grüße Nobuddy
Re: Reportlab - Y-Position von letzter Tabellenzeile
Verfasst: Samstag 25. Juli 2015, 18:13
von DMD
ich beschäftige mich auch grad damit.
hab auch keine ahnung, wie ich eine normale ausgabetabelle in tkinter in reportlab übersetzen soll.
ziemlich enttäuschend, dass man das noch nicht standardisiert hat!
Re: Reportlab - Y-Position von letzter Tabellenzeile
Verfasst: Sonntag 26. Juli 2015, 21:14
von Sirius3
@Nobuddy: was hast Du denn bereits? Und was willst Du genau mit der y-Position anfange?
Re: Reportlab - Y-Position von letzter Tabellenzeile
Verfasst: Montag 27. Juli 2015, 07:07
von noisefloor
Hallo,
ReportLab ermittelt beim bauen des Dokuments defintiv diese Wert, da diese für die Positionierung des Flowables währendc der Generierung benötigt werden.
Du musst auch das PDF-Dokument 1x bauen, um an die Position überhaupt ran zu kommen. Aber das _wie_ ist mir auch noch nicht klar. Aber ich bin mir sicher, dass es geht
Und was willst Du genau mit der y-Position anfange?
Genau - warum brauchst du das? Wenn du mit Flowables arbeitest sollte diese Abfrage eigentlich nicht nötig sein...
Gruß, noisefloor
Re: Reportlab - Y-Position von letzter Tabellenzeile
Verfasst: Montag 27. Juli 2015, 19:06
von noisefloor
Hallo,
habe mal ein bisschen rum gespielt: man kann den verbleibenden Platz berechnen und zwar so:
Jedes Flowable hat nach dem Bauen des PDFs ein `height` bzw. `_height`-Attribute. Das in Summe mit dem reservierten Platz vor und hinter dem Flowable gibt den Gesamtplatzbedarf pro Flowable.
Auf deiner Seite sind im einfachsten Fall Seitenhöhe minus (Rand unten + Rand oben) Platz. Davon die Summe des Platzbedarfs aller im Dokument enthalten Flowables abgezogen erhält man den restlichen freien Platz.
Praktisch sieht das z.B. so aus:
Code: Alles auswählen
>>> from reportlab.platypus import Paragraph, Table, SimpleDocTemplate
>>> from reportlab.lib.styles import getSampleStyleSheet
>>> style = getSampleStyleSheet()
>>> table_data = [['foo', 'bar'], ['spam', 'egg']]
>>> p1 = Paragraph('foobarspamegg', style['Normal'])
>>> p1.spaceAfter = 10
>>> t = Table(table_data)
>>> t.spaceBefore = 5
>>> t.spaceAfter = 5
>>> p2 = Paragraph('Foo!'*150, style['Normal'])
>>> p2.spaceBefore = 10
>>> doc = SimpleDocTemplate('space_test.pdf')
>>> story = [p1, t, p2]
>>> doc.build(story)
>>> doc_available_space = doc.height-doc.topMargin-doc.bottomMargin
>>> doc_available_space
553.8897637795275
>>> p1_space_comsumed = p1.getSpaceBefore()+p1.height+p1.getSpaceAfter()
>>> p1_space_comsumed
22
>>> p1.height
12
>>> t._height
36
>>> t_space_consumed = t.getSpaceBefore()+t._height+t.getSpaceAfter()
>>> p2_space_comsumed = p2.getSpaceBefore()+p2.height+p2.getSpaceAfter()
>>> remainig_space = doc_available_space - p1_space_consumed - t_space_comsumed - p2_space_comsumed
>>> remainig_space
391.88976377952747
>>>
Wenn man Kopf- und Fusszeilen, Frames oder mehrseitige Dokumente hat, wird das ganze ein wenig aufwendiger, das Prinzip bleibt aber das gleiche.
Wenn man übrigens nur will, dass das der Tabelle folgende Flowable auf jeden Fall unter der Tabelle bleiben soll, dann gibt für Flowables das `keepWithNext` Attribut, was man auf `True` setzt.
Gruß, noisefloor
Re: Reportlab - Y-Position von letzter Tabellenzeile
Verfasst: Dienstag 11. August 2015, 18:06
von Nobuddy
Hallo noisefloor,
ist zwar schon ein wenig her, habe aber eine Frage zu Deinem Code-Beispiel.
Ich möchte das Beispiel aufgreifen.
Code: Alles auswählen
p1 = Paragraph('foobarspamegg', style['Normal'])
p1.spaceAfter = 10
p1_space_comsumed = p1.getSpaceBefore()+p1.height+p1.getSpaceAfter()
Bei mir sieht das im Test so aus:
Code: Alles auswählen
text = 'Erste Zeile\nZweite Zeile blablabalbalabalanalanalan'
p1 = Paragraph('foobarspamegg', style['Normal'])
p1.spaceAfter = 10
p1_space_comsumed = p1.getSpaceBefore()+p1.height+p1.getSpaceAfter()
Ich erhalte dann die Fehlermeldung:
p1_space_comsumed = p1.getSpaceBefore()+p1.height+p1.getSpaceAfter()
AttributeError: 'Paragraph' object has no attribute 'height'
Wo liegt der Fehler?
Evtl. bei dem formatierten Text mit Newline, oder doch was ganz anderes?
Grüße Nobuddy
Re: Reportlab - Y-Position von letzter Tabellenzeile
Verfasst: Dienstag 11. August 2015, 18:14
von noisefloor
Hallo,
das `height` Attribute hat ein Flowable _nur_, wenn du das PDF-Dokument einmal gebaut hast.
Geht auch nicht anders, da ReportLab ja vor dem bauen eines PDFs nicht weiß, wie viel Platz in der Breite ist, was ja auch einen Einfluß auf die Höhe des Flowables haben kann (z.B. breite Seite -> viel Text pro Zeile -> weniger Zeilen).
Im obigen Code rufe ich `flowable.height` ja auch erst das 1. Mal auf, nachdem `doc.build()` gelaufen ist
Gruß, noisefloor
Re: Reportlab - Y-Position von letzter Tabellenzeile
Verfasst: Dienstag 11. August 2015, 18:17
von Nobuddy
Hallo und Danke für die schnelle Antwort!
Nobuddy hat geschrieben:Im obigen Code rufe ich `flowable.height` ja auch erst das 1. Mal auf, nachdem `doc.build()` gelaufen ist
Das hatte ich wohl total ignoriert ...
Grüße Nobuddy