py-pdf / fpdf2

Simple PDF generation for Python

Home Page:https://py-pdf.github.io/fpdf2/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Tables with headings and filled cells - ignore header lines for background fill of data rows

4lexRed opened this issue · comments

Intent
If I have a table with a header-styling and filled cells via cell_fill_mode="ROWS".
The first line of the data rows is filled with color. The second line of the data rows is not filled. Third line is filled again (and so on)

I want this first data line to be without filling - the second row filled - the third row not filled (and so on).
See pictures at the end of the text for examples

Describe the solution you'd like
Add a keyword to pdf.table() function called cell_fill_consider_heading_lines with the possible options True or False.
If true, the amount of heading rows gets subtracted from the temporary row index number.

Possible Code Changes
in the file table.py change the line 351

cell_mode_fill = self._cell_fill_mode.should_fill_cell(i, j)

to

tmp_i = i - self._num_heading_rows
cell_mode_fill = self._cell_fill_mode.should_fill_cell(tmp_i, j)

Additional context
If the table get the keyword cell_fill_mode="ROWS", then the class TableCellFillMode method should_fill_cell is called to see if the cell should be filled or not.
The method only has a look if the row-index is even or odd and fills the cell if it is odd (row-index % 2).

Current behavior:
We have 1 heading line. The heading line number is 0 -> the first data line has the number 1 -> is odd and the cell gets filled.
We have 2 heading lines. The heading lines numbers are 0 and 1 -> the first data line has the number 2 -> is even and the cell does not get filled.
We have 3 heading line(s). The heading lines numbers are 0, 1 and 2 -> the first data line has the number 3 -> is odd and the cell gets filled.

To get my wanted behavior it is crucial that the row-index number depends on the value of the keyword num_heading_rows.

Wanted behavior:
We have 1 heading line. The heading line number is irrelevant -> the first data line has the number 0 -> is "even" and does not get filled.
We have 2 heading lines. The heading line numbers are irrelevant -> the first data line has the number 0 -> is "even" and does not get filled.
We have 3 heading line(s). The heading line numbers are irrelevant -> the first data line has the number 0 -> is "even" and does not get filled.

PS: I'd render a pull request with an , but I am too new to github and have no clue how to do that

Screenshots of my pdf file - current look and wanted look (with the fix)
example_current_behavior
example_wanted_behavior

Hi @4lexRed,
I am not 100% sold on the cell_fill_consider_heading_lines concept.
Perhaps it would be better having ROWS-EVEN and ROWS-ODD in TableCellFillMode and you use one or the other depending on the number of header row or another different criteria you have.

Hi @andersonhc
ROWS-EVEN and ROWS-ODD might be an additional change, that gives more flexibility to which rows are to be filled.
And yes, this flexibility would solve the problem in 99.5% of the cases, as the programmer can fiddle around with the setting and get the desired formatting as he knows how many heading lines the table will have.

Yet, I did recon that the problems basic question is:
Do heading-rows count into the rows?
Or do only data-rows matter?

In my personal opinion (aka my formatting style) heading-rows do not count.
I think it looks weird if my heading line is filled gray 170 and my first data line is filled gray 205.
Especially if there is only one data row in the table (see example pictures).
Gives the reader a hard time to differ between header and data.

[had a quick look into Excel's table formats templates and it might be that I am the only one who thinks there should be a non filled row after the heading]

I suggested the keyword cell_fill_consider_heading_lines with a default setting to False,
as it simply would not break current code and still gives the option to change the filling style. And it's easy to implement. Still adding a new keyword might be a thing to avoid.

Yet, introducing three TableCellFillMode options ROWS-ODD, ROWS-EVEN and ROWS would also not break old code (or is legacy code a better word?).

So choose whichever way you recon better.
But do not forget COLUMNS, COLUMNS-ODD, COLUMNS-EVEN if you change the ROWS ;-)

Hi @4lexRed @Lucas-C , just stumbeld on this enhancement request, as I am having same problem. Want to fill the second data row, as the header line is also filled. Especially in case of just two data lines, this looks confusing with the current behaviour.
I think the concept of controlling the even/odd filling is preferable. In combination with the already existing possibility to swith on/off the header row filling, this is most flexible (and backward compatible). I agree with @4lexRed same funtionality should also be implemented for the columns.

Thanks for all the work in this great library!

Hey @kaufmann-jan

Are you interested in submitting a PR adding the options on the TableCellFillMode enum?

Hi @andersonhc , yes I could do this

I opened a quick PR that would allow ANY custom cell-filling logic: #1117

Maybe that's enough to solve your issues?
What do you think of this approach?

I opened a quick PR that would allow ANY custom cell-filling logic: #1117

Maybe that's enough to solve your issues? What do you think of this approach?

Hi 😊

Without feedback I'm planning on merging this PR in a few days.
Regards!

Hi @Lucas-C ,
sorry for not providing any feeback earlier. Just tested your implementation, works well so far and solves my issue. Thanks! This solution is quite generic. My only concern would be that it is maybe not super intuitive (from a top-level user's view). So maybe one can in addition add a TableCellFillMode enum with something like:

class EvenRowsFillMode():
    def should_fill_cell(self,i,j):
        return not i % 2

ROWS-EVEN = EvenRowsFillMode()

Thank you for the feedback @kaufmann-jan!

I added two new enum values EVEN_ROWS & EVEN_COLUMNS in PR #1117:

What do you think?
Are the naming & behaviour of those enum values OK with you?

Yes, I agree on both naming and behaviour!

Yes, I agree on both naming and behaviour!

Alright, thanks!

PR #1117 is now merged!

Closing this issue now