[reportlab-users] Header appears mid-page due to splitByRow/splitInRow interaction

Yoshua Wakeham yosh at atticus.tech
Wed Nov 26 12:52:20 EST 2025


Thanks Robin!

Thanks for letting me know about the UseUpSpace() flowable, I hadn't seen
that before. I'm not surprised to hear that manually inserting a page break
is not the best approach! :)

It's true that prioritising an in-row split over a by-row split can largely
avoid this problem. That said, I agree it's not obvious which split should
be preferred in many cases. I think it makes sense to preserve the existing
config options, which allow the user to prioritise whichever kind of split
they prefer.

Also, I did encounter a case (which I haven't since been able to reproduce)
where the bug surfaced even when prioritising in-row splits. An in-row
split initially failed as the leftover content was less than the minimum
height, then by-row split succeeded, then the insertion of the header row
pushed down the postponed content, which allowed the previously-failing
in-row split to succeed! Definitely an edge case, and as I say not one I've
so far been able to minimally reproduce, but another point in favour of
inserting UseUpSpace(), I would say.

Best,
Yosh

On Wed, Nov 26, 2025 at 6:14 AM Robin Becker <robin at reportlab.com> wrote:

> Hi Yoshua,
> I did some more (over) thinking and it seems to me that the problem is
> that when split by row and split in row are bothe supported that we try
> split by row first. The first two rows can be split off and that leaves
> enough space tfor the table to be place on the remaining space.Because the
> header is repeated you get the header again on the same fra,e/page which is
> obviously wrong. However, if split in row had been tried most of the large
> row would appear in the split part 1. The would make the outcome look like
> the first attached attached, we might still need to fix any oustanding
> space, but it's not clear which split is actually best
>
> On Wed, 26 Nov 2025 at 09:30, Robin Becker <robin at reportlab.com> wrote:
>
>> Hi Yoshua,
>>
>> I tried your patch and it does work, but I think it's better to use
>> [part1,  UseUpSPace(), part2}  instead of  [part1,  PageBreak(), part2}.
>>
>> I will visually try the modified code against all the tests.
>>
>> On Tue, 25 Nov 2025 at 12:50, Robin Becker <robin at reportlab.com> wrote:
>>
>>> Hi Yoshua,
>>>
>>> you really like splitting rows. It's something of a problem for
>>> reportlab as it's just grafted on to the old table code and much harder
>>> than the non row splitting case.
>>>
>>> Clearly finding a suitable split point across multiple columns is harrer
>>> than splitting by rows.
>>>
>>> Assuming that the problem is that a row split may leave space behind I
>>> guess that the problem is that we should just fill that space and leave the
>>> layout to the higher levels.
>>>
>>> Certainly just using a PageBreak is not right as it will cause problems
>>> for the higher level eg we might want a frame break or be inside one of the
>>> other container layouts.
>>>
>>> I'll take a look at the example and see if the fix can just use up the
>>> space.
>>>
>>> Thanks for the contribution . If only we had infinitely  long pages :(
>>>
>>>
>>>
>>> On Mon, 24 Nov 2025 at 22:53, Yoshua Wakeham via reportlab-users <
>>> reportlab-users at lists2.reportlab.com> wrote:
>>>
>>>> Hello,
>>>>
>>>> I've found a bug in table-splitting code that can occur when all of
>>>> `splitByRow`, `splitInRow`, and `repeatRows` are non-zero. Namely, a
>>>> between-row split immediately followed by a within-row split can cause
>>>> header/repeated rows to be drawn in the middle of a page/frame.
>>>> Suppose a table T is too tall to fit in a frame, so `T.split()` is
>>>> called. When `splitByRow=1` and `splitInRow>1`, we attempt a between-row
>>>> split before checking whether a within-row split would have succeeded.
>>>> Suppose the between-row split succeeds, splitting the table into T1 and T2.
>>>>
>>>> Notably, the repeated rows specified by `repeatRows` will then be
>>>> inserted at the start of T2, before `T.split()` returns `[T1, T2]`.
>>>>
>>>> It seems that reportlab then tries to fit T2 into the space that
>>>> remains in the frame after T1 is accounted for. Since we know the first row
>>>> of T2 is too big to fit in that space, the between-row split fails, and
>>>> instead we try a within-row split. If that succeeds, it exposes the bug –
>>>> because the repeated header rows will be drawn in the middle of the frame,
>>>> along with the top half of the newly-split row!
>>>>
>>>> I've confirmed this is reproducible in version 4.4.4.
>>>>
>>>> I'm attaching a minimal reproducible example. The output frames look
>>>> like this on v4.4.4:
>>>> [image: CleanShot 2025-11-13 at 14.24.08 at 2x.jpg]
>>>> [image: CleanShot 2025-11-13 at 14.24.21 at 2x.jpg]
>>>>
>>>> I'm not sure how best to fix this, but for the sake of argument, I've
>>>> attached a patch that simply inserts a `PageBreak()` between the two
>>>> returned tables (as long as the successful split was between rows). That
>>>> ensures that the between-row split has the intended effect, and no content
>>>> can "sneak" back onto the page. With my patch applied, the output looks
>>>> like what we would expect:
>>>>
>>>> [image: CleanShot 2025-11-13 at 14.29.58 at 2x.jpg]
>>>> [image: CleanShot 2025-11-13 at 14.30.11 at 2x.jpg]
>>>> If there's another approach that would make more sense, I'd be happy to
>>>> put time into fixing this.
>>>>
>>>> Thanks so much!
>>>> Yosh
>>>>
>>>> --
>>>> *Yoshua Wakeham*
>>>> Senior Software Developer
>>>> yosh at atticus.tech
>>>> _______________________________________________
>>>> reportlab-users mailing list
>>>> reportlab-users at lists2.reportlab.com
>>>> https://pairlist2.pair.net/mailman/listinfo/reportlab-users
>>>>
>>>
>>>
>>> --
>>> Robin Becker
>>>
>>
>>
>> --
>> Robin Becker
>>
>
>
> --
> Robin Becker
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://pairlist2.pair.net/pipermail/reportlab-users/attachments/20251126/bec274be/attachment-0001.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: CleanShot 2025-11-13 at 14.24.08 at 2x.jpg
Type: image/jpeg
Size: 19443 bytes
Desc: not available
URL: <https://pairlist2.pair.net/pipermail/reportlab-users/attachments/20251126/bec274be/attachment-0004.jpg>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: CleanShot 2025-11-13 at 14.24.21 at 2x.jpg
Type: image/jpeg
Size: 16124 bytes
Desc: not available
URL: <https://pairlist2.pair.net/pipermail/reportlab-users/attachments/20251126/bec274be/attachment-0005.jpg>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: CleanShot 2025-11-13 at 14.29.58 at 2x.jpg
Type: image/jpeg
Size: 16179 bytes
Desc: not available
URL: <https://pairlist2.pair.net/pipermail/reportlab-users/attachments/20251126/bec274be/attachment-0006.jpg>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: CleanShot 2025-11-13 at 14.30.11 at 2x.jpg
Type: image/jpeg
Size: 16560 bytes
Desc: not available
URL: <https://pairlist2.pair.net/pipermail/reportlab-users/attachments/20251126/bec274be/attachment-0007.jpg>


More information about the reportlab-users mailing list