[reportlab-users] Float flowable to bottom of page

Robin Becker robin at reportlab.com
Thu Feb 4 09:30:52 EST 2010


On 03/02/2010 21:59, James Lance wrote:

> Is there a way to make a flowable element float to the bottom of the page?

>

> I'm working on a invoice document, at the bottom of the page is a tear off segment that can be returned with payment. I can draw directly on the canvas, but I don't want to include the segment on every page, just the last.

>

> What I've done is put all the elements that make up my tear off segment into a KeepTogether flowable. I've tried messing around with putting a spacer before it what attempts to fill all remaining space with out pushing it to the next page. I can't seem to work out the correct height of the spacer, and still be flexible concerning the previous flowable content. Of course if there are enough line items or other data then naturally the tear off segment will go to the next page.

>

> So, how can I pin the tear off to the bottom of the page while still keeping it a flowable? Is that even possible?

>

> Thanks,

>

> James


OK this code appears a bit better in that you don't need to work out the height
of the flowables before doing stuff

#############################################
from reportlab.platypus.flowables import KeepTogether, Spacer, _listWrapOn,
_flowableSublist, PageBreak
from reportlab.platypus.doctemplate import FrameBreak
class FloatToEnd(KeepTogether):
'''
Float some flowables to the end of the current frame
'''
def __init__(self,flowables,maxHeight=None,brk='frame'):
self._content = _flowableSublist(flowables)
self._maxHeight = maxHeight
self._state = 0
self._brk = brk

def wrap(self,aW,aH):
return aW,aH+1 #force a split

def _makeBreak(self,h):
if self._brk=='page':
return PageBreak()
else:
return FrameBreak

def split(self,aW,aH):
dims = []
W,H = _listWrapOn(self._content,aW,self.canv,dims=dims)
if self._state==0:
if H<aH:
return [Spacer(aW,aH-H)]+self._content
else:
S = self
S._state = 1
return [self._makeBreak(aH), S]
else:
if H>aH: return self._content
return [Spacer(aW,aH-H)]+self._content

if __name__=='__main__':
from reportlab.platypus.doctemplate import SimpleDocTemplate
from reportlab.platypus.paragraph import Paragraph
from reportlab.platypus.flowables import Spacer, KeepTogether, _listWrapOn
from reportlab.lib.styles import getSampleStyleSheet
ss = getSampleStyleSheet()
Normal= ss['Normal']

t1 = '''Comparing these examples with their parasitic gap counterparts in (96)
and (97), we see that relational information is to be regarded as an
abstract underlying order. We have already seen that a descriptively
adequate grammar is rather different from the extended c-command
discussed in connection with (34). To characterize a linguistic level
L, the natural general principle that will subsume this case raises
serious doubts about the ultimate standard that determines the accuracy
of any proposed grammar. A consequence of the approach just outlined is
that an important property of these three types of EC is not quite
equivalent to the traditional practice of grammarians. A majority of
informed linguistic specialists agree that this selectionally introduced
contextual feature does not readily tolerate a parasitic gap
construction.
'''
t2 ='''However, this assumption is not correct, since the descriptive power of
the base component is not subject to nondistinctness in the sense of
distinctive feature theory. Note that this selectionally introduced
contextual feature is not to be considered in determining a corpus of
utterance tokens upon which conformity has been defined by the paired
utterance test. I suggested that these results would follow from the
assumption that the natural general principle that will subsume this
case is unspecified with respect to the ultimate standard that
determines the accuracy of any proposed grammar. Note that the earlier
discussion of deviance does not affect the structure of nondistinctness
in the sense of distinctive feature theory. A consequence of the
approach just outlined is that the theory of syntactic features
developed earlier is not quite equivalent to the ultimate standard that
determines the accuracy of any proposed grammar.'''

#case where we need the page throw
d = SimpleDocTemplate('flowfloat0.pdf')
S =[] #the story

S.append(Paragraph('Line 1 followed by lots of space',Normal))
S.append(Spacer(10,481))
S.append(Paragraph('Line 2',Normal))
S.append(FloatToEnd([Paragraph(t1,Normal),Paragraph(t2,Normal)]))
d.build(S)

#case where we don't need the page throw
d = SimpleDocTemplate('flowfloat1.pdf')
S =[] #the story

S.append(Paragraph('Line 1 followed by less space',Normal))
S.append(Spacer(10,381))
S.append(Paragraph('Line 2',Normal))
S.append(FloatToEnd([Paragraph(t1,Normal),Paragraph(t2,Normal)]))
d.build(S)
#############################################
--
Robin Becker


More information about the reportlab-users mailing list