[reportlab-users] Header appears mid-page due to splitByRow/splitInRow interaction
Yoshua Wakeham
yosh at atticus.tech
Thu Nov 27 09:51:36 EST 2025
Thanks Robin.
The existing settings that Lennart Regebro added actually support
preferring either type of split:
- splitByRow=1, splitInRow=0 (or omitted): try by-row split, don't try
in-row
- splitByRow=1, splitInRow=1: try by-row split first; if that fails, try
in-row split
- splitByRow=0, splitInRow=1: try in-row split first; if that fails, try
by-row split.
It's a little hard to see that from the implementation of Table.split,
though!
On Thu, Nov 27, 2025 at 6:26 AM Robin Becker <robin at reportlab.com> wrote:
> Hi Yoshua,
> the current code seems to refer byRow splits and I am unsure if in row is
> to be preferred. If a printer was doing it then the look and overall size
> requirement would be used to select the split.
>
> For now I will leave the rowsplit try first.even though it can lead to the
> overflowing row being pushed to the next page. It seems fairly obvious that
> in row can use less overall space though.
>
> On Wed, 26 Nov 2025 at 17:52, Yoshua Wakeham <yosh at atticus.tech> wrote:
>
>> 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
>>>
>>
>
> --
> Robin Becker
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://pairlist2.pair.net/pipermail/reportlab-users/attachments/20251127/0d30b720/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/20251127/0d30b720/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/20251127/0d30b720/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/20251127/0d30b720/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/20251127/0d30b720/attachment-0007.jpg>
More information about the reportlab-users
mailing list