[reportlab-users] RE: Page Totals
CLIFFORD ILKAY
reportlab-users@reportlab.com
Wed, 25 Aug 2004 07:15:13 -0400
Hello Henning,
At 08:52 AM 25/08/2004 +0200, Henning von Bargen wrote:
>What do you mean with "Page Totals"?
I mean totals for a given column in a table for the page, as opposed to the=
=20
whole report. e.g. if you have a report where you have subtotals on each=20
page for some column, I refer to that, as do many of the report generators=
=20
that I have seen, as a page total.
In this particular case, I have a column in a table that is displayed on=20
each page called "Amount Due". I want a subtotal at the bottom of each page=
=20
for that column and a grand total at the end of the report. I guess this=20
would be done with afterPage(), as per your example below. So mine would=20
look something like:
def afterPage(self):
subtotal =3D subtotal + amountDue
I am not sure how subtotal actually gets placed on the page footer though.
Similarly, I want a variable called expiryDate, which can change many times=
=20
during the report, placed on the page header on every page. I think this is=
=20
what I have to do:
def beforePage(self, xpiry):
expiryDate =3D xpiry
Again, I am not sure how beforePage is going to be invoked so that I can=20
pass expiryDate to it from my main method and I am not sure how expiryDate=
=20
is going to appear on the page header.
>I can give you an example how to
>output "Page X of Y" on each page.
Thank you.
>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.
Yes, that would help.
>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
>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.
>
> Bemerkenswert bei diesem DocTemplate ist, dass die Gesamtseitenzahl
>berechnet wird
> und in der Kopzeile ausgegeben werden kann.
>
> 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
>
> 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)
>
> 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)
Regards,
Clifford Ilkay
Dinamis Corporation
3266 Yonge Street, Suite 1419
Toronto, Ontario
Canada M4N 3P6
Tel: 416-410-3326=20