[reportlab-users] Crashing when table goes over a page

Robin Becker reportlab-users@reportlab.com
Tue, 29 Jul 2003 09:07:50 +0100


In article <002501c3556e$3b076610$8a01010a@gkiddxp2>, Garth Kidd <garth@deadlybloodyserious.com>
writes
>Further to my last mail; today's report run doesn't trigger the problem, so
>I've got a new one. :) 
>
>After a few inches' content, my story has a KeepTogether of a header, space,
>long table, and then another space. The table is longer than a page. What I
>want to happen is for the header, space, and first part of the table to
>appear in the remaining 4/5 of the first page, continuing on the second.
>Instead the table doesn't start until page 2 (leaving a lot of empty space),
>fills page 2, and then continues on page 3. 
>
>When I specify a KeepTogether, what I want is for Platypus to ensure that
>each item starts adjacent to the end of the previous item. That aside, I
>want to fill pages as much as is possible. 
>
>Anyone have any ideas on a quick fix? I'd really much rather be
>concentrating on advanced graphing than fixing basic document flow
>functionality. 
>
>Regards,
>Garth.
The keep together tries to do what you want, unfortunately it doesn't know the total frame
height when attempting to split itself. If it did it could perform the split more rationally.
Without that information it can only attempt to get the most space for itself.

We could make a more acceptable keepTogether by giving it an extra argument specifying the frame
height to be assumed for simple (non-page throw splitting).

This isn't tested so be careful.

class KeepTogether(Flowable):
        def __init__(self,flowables,maxHeight=None):
                if type(flowables) not in _SeqTypes:
                        self._flowables = [flowables]
                else:
                        self._flowables = flowables
                self._maxHeight = maxHeight

        def __repr__(self):
                f = self._flowables
                L = map(repr,f)
                import string
                L = "\n"+string.join(L, "\n")
                L = string.replace(L, "\n", "\n  ")
                return "KeepTogether(%s,maxHeight=%s) # end KeepTogether" % (L,self._maxHeight)

        def wrap(self, aW, aH):
                W = 0
                H = 0
                F = self._flowables
                canv = self.canv
                for f in F:
                        w,h = f.wrapOn(canv,aW,0xfffffff)
                        if f is not F[0]: h = h + f.getSpaceBefore()
                        if f is not F[-1]: h = h + f.getSpaceAfter()
                        W = max(W,w)
                        H = H+h
                self._CPage = (H>aH) and (H<=self._maxHeight)
                return W, 0xffffff      # force a split

        def split(self, aW, aH):
                S = getattr(self,'_CPage',1) and [CondPageBreak(aH+1)] or []
                for f in self._flowables: S.append(f)
                return S

-- 
Robin Becker