ReportLab Problem

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Benutzeravatar
Domroon
User
Beiträge: 104
Registriert: Dienstag 3. November 2020, 10:27
Wohnort: Dortmund

Hallo liebes Forum,
ich stecke fest. Ich möchte gerne eine Rechnung mithilfe von ReportLab erzeugen. Dabei möchte ich gerne nach dem "PLATYPUS" (Page Layout and Typography Using Scripts) Verfahren arbeiten.

Siehe hier unter Kapitel 5: https://www.reportlab.com/docs/reportlab-userguide.pdf

Nun scheitert es bei mir leider schon daran, dass ich nicht mal eine Seite in mein Dokument bekomme.

Wenn ich diesen Quellcode ausführen will:

Code: Alles auswählen

from reportlab.platypus import BaseDocTemplate, PageTemplate
from reportlab.lib.units import mm
from reportlab.platypus import Paragraph, Frame
from reportlab.lib.pagesizes import letter, A4


class Document(BaseDocTemplate):
    def __init__(self, filename, pagesize, pageTemplates=[]):
        super().__init__(self)

    def afterInit(self):
        self.addPageTemplates(self.pageTemplates)


def main():
    first_paragraph = Paragraph('this is a test')
    flowables = [first_paragraph]
    first_frame = Frame(10*mm, 10*mm, 50*mm, 50*mm, showBoundary=1)
    frames = [first_frame]
    first_page = PageTemplate(frames)
    document = Document('test_document.pdf', A4, first_page)
    document.build(flowables)


if __name__ == "__main__":
    main()
Dann bekomme ich diese Fehlermeldung:

Code: Alles auswählen

Traceback (most recent call last):
  File "C:/Users/haeus/workspace/LoyaltyCustomer/platypus3.py", line 27, in <module>
    main()
  File "C:/Users/haeus/workspace/LoyaltyCustomer/platypus3.py", line 23, in main
    document.build(flowables)
  File "C:\Users\haeus\AppData\Local\Programs\Python\Python38-32\lib\site-packages\reportlab\platypus\doctemplate.py", line 1059, in build
    self._startBuild(filename,canvasmaker)
  File "C:\Users\haeus\AppData\Local\Programs\Python\Python38-32\lib\site-packages\reportlab\platypus\doctemplate.py", line 1030, in _startBuild
    self.handle_documentBegin()
  File "C:\Users\haeus\AppData\Local\Programs\Python\Python38-32\lib\site-packages\reportlab\platypus\doctemplate.py", line 607, in handle_documentBegin
    self.pageTemplate = self.pageTemplates[self._firstPageTemplateIndex]
IndexError: list index out of range
Ich habe schon verstanden, dass der Index der Liste "pageTemplates" außerhalb des gültigen Bereichs ist. Wenn ich das ganze debugge, dann sehe ich, dass in die Liste garnichts herein kommt.
Hier einmal der Code, auf den ich durchs debuggen aufmerksam geworden bin, dieser steckt in der BaseDocTemplate-Klasse des ReportLab Moduls (Wichtig ist hierbei zu erwähnen, dass die Variable "_firstPageTemplateIndex" weiter oben auf 0 gesetzt wird, es wird also nur das erste Listenelement aufgerufen):

Code: Alles auswählen

    def handle_documentBegin(self):
        '''implement actions at beginning of document'''
        self._hanging = [PageBegin]
        if isinstance(self._firstPageTemplateIndex,list):
            self.handle_nextPageTemplate(self._firstPageTemplateIndex)
            self._setPageTemplate()
        else:
            self.pageTemplate = self.pageTemplates[self._firstPageTemplateIndex]
        self.page = 0
        self.beforeDocument()
Ich stehe jetzt ein bisschen auf dem Schlauch. Ich "schiebe" doch mit diesen beiden Zeilen eine Seite in mein document-Objekt, wo ist die denn hin? :D:

Code: Alles auswählen

first_page = PageTemplate(frames)
document = Document('test_document.pdf', A4, first_page)
Benutzeravatar
__blackjack__
User
Beiträge: 14053
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Domroon: Die ist im Nirvana, denn Du machst mit diesem Wert in der `Document.__init__()` überhaupt nichts. Auch mit dem `filename` passiert nichts. Auch komisch ist, dass der Defaultwert eine Liste ist, Du aber ein einzelnes `PageTemplate`-Objekt übergibst.

Du möchtest da die Signatur von der `BaseDocTemplate.__init__()`-Methode besser abbilden und den Kram auch beim Aufruf durchreichen. Oder besser Deine `__init__()` ganz weg lassen wenn da überhaupt nichts eigenes passiert.

Edit: Mit `pagesize` passiert auch nix, `PageTemplate` erwartet als erstes Argument keine `frames`, und die `afterInit()` erzeugt eine nette Endlosschleife die den Arbeitsspeicher schnell füllt.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Benutzeravatar
noisefloor
User
Beiträge: 4194
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

brauchst du wirklich eigene PageTemplates und Frames? Zumindest für den Anfang würde ich das weglassen, damit du erst mal ein PDF erzeugt bekommst. Und dann darauf aufbauen.

Tipp: die Doku alleine von ReportLab ist manchmal ein bisschen komisch bzw. für den Anfang teilweise schwer verständlich, weil das in Teilen direkt ziemlich in die Tiefe geht. Im Netz gibt es aber ziemlich viele Beispiele und auch bei Stack Overflow einige Threads dazu. Das hat zumindest mir beim Lernen damals geholfen.

Gruß, noisefloor
Benutzeravatar
Domroon
User
Beiträge: 104
Registriert: Dienstag 3. November 2020, 10:27
Wohnort: Dortmund

@__blackjack__: danke für Deine Hilfe, habe mit Deiner Hilfe die Fehler erkannt, bis ich dann auf die nächsten Fehler stoß und nach Stunden(!) immernoch nichts hinbekommen habe.Werde mich nun erstmal von von ReportLab erholen und die nächsten Tage erst wieder weiter machen :D

@noisefloor: ich wollte es eig. schon mit PageTemplates machen, aber ich sollte es wirklich erstmal ohne versuchen. Danke für deinen Tipp, ich dachte echt ich wäre einfach nur zu doof die Doku zu verstehen. Da bin ich erleichtert zu hören das ich nicht der einzige bin der damit am Anfang Probleme hat ;) Werde mir in nächster Zeit mal ein paar Beispiele auf StackOverflow angucken, denke auch das mich das am ehesten weiter bringt ;)
Antworten