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 ... :wink:

Grüße Nobuddy