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
Reportlab - Y-Position von letzter Tabellenzeile
- noisefloor
- User
- Beiträge: 3856
- Registriert: Mittwoch 17. Oktober 2007, 21:40
- Wohnort: WW
- Kontaktdaten:
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
Gruß, noisefloor
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
Genau - warum brauchst du das? Wenn du mit Flowables arbeitest sollte diese Abfrage eigentlich nicht nötig sein...Und was willst Du genau mit der y-Position anfange?
Gruß, noisefloor
- noisefloor
- User
- Beiträge: 3856
- Registriert: Mittwoch 17. Oktober 2007, 21:40
- Wohnort: WW
- Kontaktdaten:
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:
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
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 ü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
Hallo noisefloor,
ist zwar schon ein wenig her, habe aber eine Frage zu Deinem Code-Beispiel.
Ich möchte das Beispiel aufgreifen.
Bei mir sieht das im Test so aus:
Ich erhalte dann die Fehlermeldung:
Evtl. bei dem formatierten Text mit Newline, oder doch was ganz anderes?
Grüße Nobuddy
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()
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()
Wo liegt der Fehler?p1_space_comsumed = p1.getSpaceBefore()+p1.height+p1.getSpaceAfter()
AttributeError: 'Paragraph' object has no attribute 'height'
Evtl. bei dem formatierten Text mit Newline, oder doch was ganz anderes?
Grüße Nobuddy
- noisefloor
- User
- Beiträge: 3856
- Registriert: Mittwoch 17. Oktober 2007, 21:40
- Wohnort: WW
- Kontaktdaten:
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
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
Hallo und Danke für die schnelle Antwort!
Grüße Nobuddy
Das hatte ich wohl total ignoriert ...Nobuddy hat geschrieben:Im obigen Code rufe ich `flowable.height` ja auch erst das 1. Mal auf, nachdem `doc.build()` gelaufen ist
Grüße Nobuddy