[reportlab-users] Addition to PageTemplate class

Marc Stober reportlab-users@reportlab.com
Fri, 11 Apr 2003 15:02:01 -0400


This message is in MIME format. Since your mail reader does not understand
this format, some or all of this message may not be legible.

------_=_NextPart_001_01C3005C.D55CB600
Content-Type: text/plain


Hello:

The ReportLab-based application I work with makes use of a lot of customized
PageTemplate classes. Each derived PageTemplate class is customized to
represent a specific section of a report. In certain sections, I would like
to have a header repeat at the top of each Frame on the page (for example,
at the top of each column). In a multi-column page template, if there's not
enough data to fill all the columns, the header should only appear at the
top of the columns that actually have content in them. To achieve this using
a customized page template, I made a small change in the BaseDocTemplate
class, to call an additional virtual function I could override in the
PageTemplate class, as follows:

# revised method of BaseDocTemplate class
    def handle_frameBegin(self,resume=0):
        '''What to do at the beginning of a frame'''
        self.pageTemplate.onFrame(self.frame, self.canv) # MLS 4/11/03
        f = self.frame
        if f._atTop:
            if self.showBoundary or self.frame.showBoundary:
                self.frame.drawBoundary(self.canv)

# new virtual method of PageTemplate class
# note that this works much like the existing onPage method!
    def onFrame(self, frame, canvas):
        """
        override to access a frame before we draw flowables in it.
        for example, re-draw header at the top of a frame
        """
        pass

# sample override of method to insert header at the top of each frame used
    def onFrame(self, frame, canvas):
        """
        act on frame before we start to draw flowables inside
        add a column-header flowable
        """
        if not frame.add(
                Table([['ColumnA', 'ColumnB', 'ColumnC']]),
                canvas):
            print "WARNING: Couldn't add table header on multi-column page."

I'm not sure what the official way to submit new code to ReportLab is, but
feel free to use this, as well as point out any corrections or further
improvements.

Thank you,
Marc Stober
mstober@dalbar.com

------_=_NextPart_001_01C3005C.D55CB600
Content-Type: text/html
Content-Transfer-Encoding: quoted-printable

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV=3D"Content-Type" CONTENT=3D"text/html; =
charset=3DUS-ASCII">
<META NAME=3D"Generator" CONTENT=3D"MS Exchange Server version =
5.5.2653.12">
<TITLE>Addition to PageTemplate class</TITLE>
</HEAD>
<BODY>
<BR>

<P><FONT SIZE=3D2>Hello:</FONT>
</P>

<P><FONT SIZE=3D2>The ReportLab-based application I work with makes use =
of a lot of customized PageTemplate classes. Each derived PageTemplate =
class is customized to represent a specific section of a report. In =
certain sections, I would like to have a header repeat at the top of =
each Frame on the page (for example, at the top of each column). In a =
multi-column page template, if there's not enough data to fill all the =
columns, the header should only appear at the top of the columns that =
actually have content in them. To achieve this using a customized page =
template, I made a small change in the BaseDocTemplate class, to call =
an additional virtual function I could override in the PageTemplate =
class, as follows:</FONT></P>

<P><FONT SIZE=3D2># revised method of BaseDocTemplate class</FONT>
<BR><FONT SIZE=3D2>&nbsp;&nbsp;&nbsp; def =
handle_frameBegin(self,resume=3D0):</FONT>
<BR><FONT SIZE=3D2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; '''What =
to do at the beginning of a frame'''</FONT>
<BR><FONT SIZE=3D2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =
self.pageTemplate.onFrame(self.frame, self.canv) # MLS 4/11/03</FONT>
<BR><FONT SIZE=3D2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; f =3D =
self.frame</FONT>
<BR><FONT SIZE=3D2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if =
f._atTop:</FONT>
<BR><FONT =
SIZE=3D2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp; if self.showBoundary or self.frame.showBoundary:</FONT>
<BR><FONT =
SIZE=3D2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp; self.frame.drawBoundary(self.canv)</FONT>
</P>

<P><FONT SIZE=3D2># new virtual method of PageTemplate class</FONT>
<BR><FONT SIZE=3D2># note that this works much like the existing onPage =
method!</FONT>
<BR><FONT SIZE=3D2>&nbsp;&nbsp;&nbsp; def onFrame(self, frame, =
canvas):</FONT>
<BR><FONT SIZE=3D2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =
&quot;&quot;&quot;</FONT>
<BR><FONT SIZE=3D2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; override =
to access a frame before we draw flowables in it.</FONT>
<BR><FONT SIZE=3D2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for =
example, re-draw header at the top of a frame</FONT>
<BR><FONT SIZE=3D2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =
&quot;&quot;&quot;</FONT>
<BR><FONT SIZE=3D2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =
pass</FONT>
</P>

<P><FONT SIZE=3D2># sample override of method to insert header at the =
top of each frame used</FONT>
<BR><FONT SIZE=3D2>&nbsp;&nbsp;&nbsp; def onFrame(self, frame, =
canvas):</FONT>
<BR><FONT SIZE=3D2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =
&quot;&quot;&quot;</FONT>
<BR><FONT SIZE=3D2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; act on =
frame before we start to draw flowables inside</FONT>
<BR><FONT SIZE=3D2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; add a =
column-header flowable</FONT>
<BR><FONT SIZE=3D2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =
&quot;&quot;&quot;</FONT>
<BR><FONT SIZE=3D2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if not =
frame.add(</FONT>
<BR><FONT =
SIZE=3D2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp; Table([['ColumnA', 'ColumnB', =
'ColumnC']]),</FONT>
<BR><FONT =
SIZE=3D2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp; canvas):</FONT>
<BR><FONT =
SIZE=3D2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp; print &quot;WARNING: Couldn't add table header on multi-column =
page.&quot;</FONT>
</P>

<P><FONT SIZE=3D2>I'm not sure what the official way to submit new code =
to ReportLab is, but feel free to use this, as well as point out any =
corrections or further improvements.</FONT></P>

<P><FONT SIZE=3D2>Thank you,</FONT>
<BR><FONT SIZE=3D2>Marc Stober</FONT>
<BR><FONT SIZE=3D2>mstober@dalbar.com</FONT>
</P>

</BODY>
</HTML>
------_=_NextPart_001_01C3005C.D55CB600--