[reportlab-users] RE: Page Totals

Henning von Bargen reportlab-users@reportlab.com
Wed, 25 Aug 2004 08:52:02 +0200


> From: CLIFFORD ILKAY <clifford_ilkay@dinamis.com>
> Subject: [reportlab-users] Page Totals
> Reply-To: reportlab-users@reportlab.com
>=20
> Hi,
>=20
> How would you put a total on each page for a given column of values? =
I=20
> suspect one would have to use the afterPage method but I am not sure =
how
to=20
> do that. Similarly, my earlier question about injecting variables =
into the

> page header can be solved using beforePage but I do not know how to =
use=20
> that either. Does anyone have any code snippets they can share that=20
> illustrates the use of beforePage and afterPage?
>=20
> Regards,
>=20
> Clifford Ilkay
> Dinamis Corporation
> 3266 Yonge Street, Suite 1419
> Toronto, Ontario
> Canada M4N 3P6
>=20
> Tel: 416-410-3326=20
>=20

What do you mean with "Page Totals"?
I can give you an example how to
output "Page X of Y" on each page.

You'll have to create your subclasses of PageTemplate and =
BaseDocTemplate,
then use doc.multibuild() with 2 passes to
count the total number of pages first,
then build once again, this time with the correct number of pages.

There may be other ways to achieve this, but this works.

It's a pity that one cannot use Platypus in the page headers/footers,
it would certainly simplify the task.

HTH
Henning

#!/bin/env python
# -*- coding: iso-8859-1 -*-
#
#Copyright Triestram&Partner GmbH 2003
#
# @AUTHOR Henning von Bargen
#
# @SINCE  13.10.2003
#
# @VERSION 0.1  $$ Revision                     $$
#

__version__=3D''' $$ Revision                     $$ '''

__doc__=3D"""Vorlage f=FCr Tabellarische Berichte.

Die hier definierten Klassen definieren das grunds=E4tzliche Layout=20
der Berichte (z.B. Kopf- und Fusszeilen).
"""

from reportlab.platypus import PageTemplate, BaseDocTemplate, Frame,
Paragraph
from reportlab.platypus import Spacer, SimpleDocTemplate, TableStyle

from reportlab.lib.units import inch,cm,mm
from reportlab.lib import colors
from reportlab.lib import pagesizes
from reportlab.lib.styles import getSampleStyleSheet

import os.path

imagePath=3D"../images"

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

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

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

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

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

        #just playing
        self.numPages =3D 1
        self._lastnumPages =3D 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 =3D max(self.canv.getPageNumber(), self.numPages)
       =20
    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)