[reportlab-users] Re: Playpus "Total pages" before PDF gets generated.

Henning von Bargen H.vonBargen at triestram-partner.de
Thu Dec 2 03:17:38 EST 2004


> Date: Wed, 1 Dec 2004 11:47:01 +0200
> From: bo at bitute.b4net.lt
> Subject: [reportlab-users] Playpus "Total pages" before PDF gets
> 	generated.
> To: ReportLab Maillist <reportlab-users at reportlab.com>
> Message-ID: <20041201094701.GA30237 at bitute.b4net.lt>
> Content-Type: text/plain; charset=utf-8
> 
> Hello.
> 
> Does anybody know how to get total pages in Platypus BEFORE I generated
the
> PDF? I need something like this:
> 
>                  "Page 16 of 328"
> 
> Where to RTFM? I searched (not so much though) and still can't find it. 
> Does Platypus knows about how much pages will be generated ahead? Hmm...
> I also looked over the code a bit, but still nothing suitable I found.
> 
> Thank you much for advice...

It should be possible to use Forms, but I've never seen a working example
anywhere.
And the problem is (AFAIK) that the form has to use a fixed size.
So if you wanted "Page 16 of NNN"  to be displayed right-aligned,
you would have to know in advance the amount of "N"s. This could be
difficult
if you don't know if your document needs 9 or 10 pages...

The way I do it is to call doc.multibuild and a variable total_pages
(initialize with 1).
A trigger is called for each page, setting total_pages = max(total_pages,
currentpage).
On the first run, total_pages is unknown and thus the page header shows
wrong values.
On the second run, total_pages has the correct value, so the header is
correct.

Here is an excerpt from the code:

excerpt from vorlage.py :

class StandardDocTemplate(BaseDocTemplate):
    """Hier wird das Standardlayout definiert.
    
       Bemerkenswert bei diesem DocTemplate ist, dass die Gesamtseitenzahl
berechnet wird
       und in der Kopzeile ausgegeben werden kann.
       
       Sauberer wäre es eigentlich, ein IndexingFlowable zu verwenden,
       dass als allerletztes Element hinzugefügt wird.
    """

    def progresshandler(self, what, arg):
        if what in ["PASS", "PAGE"]:
            print what, arg
        #print "numPages=%d" % self.numPages
        if what=='STARTED':
            self._lastnumPages = self.numPages
    
    def afterInit(self):
        # Standard: ohne Deckblatt
        # self.addPageTemplates(DeckblattTemplate('Deckblatt',
self.pagesize))
        self.addPageTemplates(EinspaltigTemplate('Einspaltig',
self.pagesize))

        #just playing
        self.title = "(Titel fehlt)"
        self.numPages = 1
        self._lastnumPages = 0
        self.setProgressCallBack(self.progresshandler)

    def afterPage(self):
        """This is called after page processing, and
        immediately after the afterDrawPage method
        of the current page template."""
        self.numPages = max(self.canv.getPageNumber(), self.numPages)
        
    def _allSatisfied(self):
        """Eine unsaubere Implementierung, aber bevor wir jetzt anfangen mit
Cross-Referenzen etc.
           machen wir es lieber so.
           Called by multi-build - are all cross-references resolved?
        """
        if self._lastnumPages < self.numPages:
            return 0
        return BaseDocTemplate._allSatisfied(self)


class EinspaltigTemplate(PageTemplate):
    def __init__(self, id, pageSize):
        self.numPages = 0
        self.pageWidth = pageSize[0]
        self.pageHeight = pageSize[1]

        # Seitenrand links/rechts 2cm, oben 2cm, unten 1.5cm,
        frame1 = Frame(20*mm,
                       15*mm,
                       self.pageWidth - 40*mm,
                       self.pageHeight - 35*mm, id='normal')
        PageTemplate.__init__(self, id, [frame1])  # note lack of onPage

    def afterDrawPage(self, canvas, doc):
        # Titel und Seitenzahl in der Kopfzeile ausgeben
        y = self.pageHeight - 15*mm
        canvas.saveState()
        canvas.drawImage(os.path.join(imagePath,'logo.jpeg'),20*mm,
self.pageHeight-14*mm)
        canvas.setFont('Helvetica', 12)
        canvas.drawString(60*mm, y+8, doc.title)
        canvas.line(20*mm, y, self.pageWidth - 20*mm, y)
        canvas.setFont('Helvetica', 8)
        canvas.drawRightString(self.pageWidth - 20*mm, y+8, doc.rightHeader
% { "page":canvas.getPageNumber(), "numpages":doc.numPages})
        canvas.restoreState()


excerpt from pdftab.py (using the templates):

        import vorlage
        ...

        # Dokument anlegen
        vorlage.imagePath = os.path.join (imagePath, "../html/images")
        doc = vorlage.StandardDocTemplate (outPDF, pagesize=pagesize,
allowSplitting=1)
        doc.title = metadaten.titel
        doc.rightHeader = metadaten.rightHeader
        story = []
        
        story.append(...)
        ....

        doc.multiBuild(story)





More information about the reportlab-users mailing list