Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allowing to set padding in tables and multi_cell + vertical alignment in tables #797

Merged
merged 103 commits into from
Sep 23, 2023
Merged
Show file tree
Hide file tree
Changes from 95 commits
Commits
Show all changes
103 commits
Select commit Hold shift + click to select a range
b3ac854
added padding to multi_cell
RubendeBruin Jun 1, 2023
d42aa2a
fixed border for border=1,
RubendeBruin Jun 1, 2023
f4d13cf
implemented in table
RubendeBruin Jun 1, 2023
6cf7afb
decoupled drawing of borders/fill and text
RubendeBruin Jun 2, 2023
a575190
works
RubendeBruin Jun 2, 2023
18abfbc
fill now behind image
RubendeBruin Jun 2, 2023
56abc6c
only-images table works
RubendeBruin Jun 2, 2023
c63b4b4
and per-cell padding as well.
RubendeBruin Jun 2, 2023
88d21ab
Added v_align option and alignV enum
RubendeBruin Jun 2, 2023
c6e8994
Added docs in Tables.md
RubendeBruin Jun 2, 2023
bd86201
Blacked
RubendeBruin Jun 2, 2023
99d8d31
Added borders_outside_width option for tables
RubendeBruin Jun 5, 2023
7b122a3
Fixed padding
RubendeBruin Jun 5, 2023
0a65382
Update fpdf/fpdf.py
RubendeBruin Jun 6, 2023
cce511b
Update fpdf/fpdf.py
RubendeBruin Jun 6, 2023
1e98c3f
Update fpdf/fpdf.py
RubendeBruin Jun 6, 2023
544bc67
Update fpdf/fpdf.py
RubendeBruin Jun 6, 2023
64fdd93
Update fpdf/fpdf.py
RubendeBruin Jun 6, 2023
06745d7
Update fpdf/fpdf.py
RubendeBruin Jun 6, 2023
e34f5b4
Update fpdf/table.py
RubendeBruin Jun 6, 2023
9aa7405
Update fpdf/table.py
RubendeBruin Jun 6, 2023
b52ed25
Update fpdf/table.py
RubendeBruin Jun 6, 2023
ae23e6f
Incorporating comments
RubendeBruin Jun 6, 2023
3a78bbc
Merge remote-tracking branch 'fork/padding' into padding
RubendeBruin Jun 6, 2023
c1899fd
Merge branch 'padding_and_border' into padding
RubendeBruin Jun 6, 2023
ad0078b
Incorporating comments
RubendeBruin Jun 6, 2023
66a44dd
Incorporating comments
RubendeBruin Jun 6, 2023
9deb86c
Docs and tests for colspan
RubendeBruin Jun 7, 2023
8ba2899
Merge branch 'test_colspan' into padding
RubendeBruin Jun 7, 2023
6952bdf
wip
RubendeBruin Jun 7, 2023
e317928
Update fpdf/table.py
RubendeBruin Jun 7, 2023
c54e35b
Merge remote-tracking branch 'fork/padding' into padding
RubendeBruin Jun 7, 2023
611a8d2
Added c_margin and docs
RubendeBruin Jun 7, 2023
6446e15
Added c_margin and docs and docstrings
RubendeBruin Jun 7, 2023
90e6ad7
Merge branch 'master' into padding
RubendeBruin Jul 20, 2023
78ad49b
Merged with master
RubendeBruin Jul 20, 2023
d6cbb13
wip
RubendeBruin Jul 20, 2023
c61920b
wip
RubendeBruin Jul 20, 2023
29621df
wip
RubendeBruin Jul 20, 2023
7f419a7
Gutters and colspan now works
RubendeBruin Jul 20, 2023
8b6b693
Gutters and colspan now works
RubendeBruin Jul 21, 2023
d77e88a
fixed style bug
RubendeBruin Jul 21, 2023
11cb956
fixed draw_box borders
RubendeBruin Jul 21, 2023
ad6401b
Added tests for table_padding
RubendeBruin Jul 21, 2023
af2659c
Added rendered heigh to RowLayoutInfo to avoid having to call multice…
RubendeBruin Jul 21, 2023
21587ac
Added reference pdfs
RubendeBruin Jul 21, 2023
e408cf7
Renamed AlignV to VAlign (also affects test pdfs where name is printed)
RubendeBruin Jul 21, 2023
ca06b13
and docs
RubendeBruin Jul 21, 2023
c1c31a1
and docs
RubendeBruin Jul 21, 2023
780e56e
Removed a commented generate=True
RubendeBruin Jul 28, 2023
df484ee
Fixes for static code check
RubendeBruin Jul 28, 2023
b2e00c1
Fixes for static code check
RubendeBruin Jul 28, 2023
d78b0c6
Fixes for static code check
RubendeBruin Jul 28, 2023
5af74eb
Ok, I'm now starting to rewrite code in a BAD way just to pass the tests
RubendeBruin Jul 28, 2023
69fabe0
ok, nosemgrep
RubendeBruin Jul 28, 2023
7bb9cfc
trying nosemgrep again
RubendeBruin Jul 28, 2023
8fb862e
trying nosemgrep again
RubendeBruin Jul 28, 2023
b8d7a8e
black
RubendeBruin Jul 28, 2023
88b3295
# pylint: disable=protected-access
RubendeBruin Aug 1, 2023
8322730
Merge branch 'master' into padding
RubendeBruin Aug 15, 2023
8637289
Updated the reference PDFs for "table" tests
RubendeBruin Aug 15, 2023
4886777
Image size adjustments to fit in cell
RubendeBruin Aug 15, 2023
57548a6
Updated HTML table reference PDFs
RubendeBruin Aug 15, 2023
421e1ac
Fixed multi_cell
RubendeBruin Aug 15, 2023
be7ec89
pylint complaints
RubendeBruin Aug 15, 2023
ae97385
black complaints
RubendeBruin Aug 15, 2023
18c333f
changed vertical alignment implemented
RubendeBruin Aug 15, 2023
e56a3cd
Pre-computing the column widths for speedup
RubendeBruin Aug 21, 2023
2915bd9
Update docs/Tables.md
RubendeBruin Aug 21, 2023
82edd68
Update docs/Tables.md
RubendeBruin Aug 21, 2023
22863e7
Update docs/Tables.md
RubendeBruin Aug 21, 2023
6c3a6dc
Update docs/Tables.md
RubendeBruin Aug 21, 2023
3328cf4
Update docs/Tables.md
RubendeBruin Aug 21, 2023
2307264
Update docs/Tables.md
RubendeBruin Aug 21, 2023
089b337
Changelog
RubendeBruin Aug 21, 2023
5335fb9
Merge remote-tracking branch 'fork/padding' into padding
RubendeBruin Aug 21, 2023
00ce643
Merge branch 'master' into padding
RubendeBruin Aug 21, 2023
7849132
Update fpdf/fpdf.py
RubendeBruin Aug 21, 2023
102f8ce
removed padding=0 from tests
RubendeBruin Aug 21, 2023
3a4d88d
Merge remote-tracking branch 'fork/padding' into padding
RubendeBruin Aug 21, 2023
dbd4450
replaced local_c_margin with horizontal_margin as per earlier convers…
RubendeBruin Aug 21, 2023
11710dc
removed logging import (unused)
RubendeBruin Aug 21, 2023
2b51486
replaced local_c_margin with horizontal_margin as per earlier convers…
RubendeBruin Sep 12, 2023
d73aa19
Updated some of the reference pdfs
RubendeBruin Sep 12, 2023
4aff223
merged origin/master
RubendeBruin Sep 12, 2023
aeeaa17
Updated reference PDFs for HTML table tests - final render look ident…
RubendeBruin Sep 12, 2023
406c4d4
Black
RubendeBruin Sep 12, 2023
07b445a
Updated two more reference pdfs with tables (no visual changes)
RubendeBruin Sep 12, 2023
5aae1a9
Update fpdf/table.py
RubendeBruin Sep 12, 2023
db2bfd8
Update fpdf/table.py
RubendeBruin Sep 12, 2023
78b7ecd
Comments from Lucas' review
RubendeBruin Sep 12, 2023
5c4900d
Black
RubendeBruin Sep 12, 2023
c4c7c20
Merge branch 'py-pdf:master' into padding
RubendeBruin Sep 12, 2023
96c5897
Updated reference pdf
RubendeBruin Sep 12, 2023
80a2aa1
removed table_colspan_and_gutter.pdf
RubendeBruin Sep 12, 2023
c7b86bb
removed more obsolete reference pdfs
RubendeBruin Sep 12, 2023
f7aae69
Revert "removed more obsolete reference pdfs"
RubendeBruin Sep 12, 2023
66cdd7e
Replaced "Center" with "Middle" for vertical alignment in tables to b…
RubendeBruin Sep 17, 2023
6607dc3
And updated the default value as well
RubendeBruin Sep 17, 2023
01f8909
Merge remote-tracking branch 'origin/master' into padding
RubendeBruin Sep 22, 2023
ac069a3
And updated the default value as well
RubendeBruin Sep 22, 2023
1ffc9a3
Re-generated the pdfs of HTML tests with tables
RubendeBruin Sep 22, 2023
930cdae
Update Tables.md
RubendeBruin Sep 22, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,21 @@ This can also be enabled programmatically with `warnings.simplefilter('default',
This release is the first performed from the [@py-pdf GitHub org](https://github.com/py-pdf), where `fpdf2` migrated.
### Added
* [`FPDF.write_html()`](https://py-pdf.github.io/fpdf2/fpdf/fpdf.html#fpdf.fpdf.FPDF.write_html) now supports heading colors defined as attributes (_e.g._ `<h2 color="#00ff00">...`)
- documentation on how to use `livereload` to enable a "watch" mode with PDF generation: [Combine with livereload](https://py-pdf.github.io/fpdf2/CombineWithLivereload.html)
* [`FPDF.table()`](https://py-pdf.github.io/fpdf2/fpdf/fpdf.html#fpdf.fpdf.FPDF.table): Now supports padding in cells
* [`FPDF.table()`](https://py-pdf.github.io/fpdf2/fpdf/fpdf.html#fpdf.fpdf.FPDF.table): Now supports vertical alignment in cells
* [`FPDF.table()`](https://py-pdf.github.io/fpdf2/fpdf/fpdf.html#fpdf.fpdf.FPDF.table): Now supports outer border width for rendering the outer border of the table with a different line-width.

### Changed
* [`FPDF.table()`](https://py-pdf.github.io/fpdf2/fpdf/fpdf.html#fpdf.fpdf.FPDF.table): If the height of a row is governed by an image, then the default vertical alignment of the other cells is "center". This was "top".
This change was made for consistency between row-height governed by text or images. The old behaviour can be enforced using the new vertical alignment parameter.

### Fixed
* [`FPDF.image()`](https://py-pdf.github.io/fpdf2/fpdf/fpdf.html#fpdf.fpdf.FPDF.image), when provided a `BytesIO` instance, does not close it anymore - _cf._ issue [#881](https://github.com/py-pdf/fpdf2/issues/881)
* Invalid characters were being generated when a string contains parentheses - _cf._ issue [#884](https://github.com/py-pdf/fpdf2/issues/884)
* Frozen Glyph dataclass was causing problems for FPDFRecorder with TTF fonts - _cf._ issue [#890](https://github.com/py-pdf/fpdf2/issues/890)
* Edge case when parsing a Markdown link followed by a newline - _cf._ issue [#916](https://github.com/py-pdf/fpdf2/issues/916), and when bold/italics/underline markers are repeated
- [`FPDF.table()`](https://py-pdf.github.io/fpdf2/fpdf/fpdf.html#fpdf.fpdf.FPDF.table): images no longer overlap with cell borders - _cf._ issue [#892](https://github.com/py-pdf/fpdf2/issues/892)


## [2.7.5] - 2023-08-04
### Added
Expand Down
56 changes: 50 additions & 6 deletions docs/Tables.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,52 @@ Result:

![](table_align.jpg)

## Setting cell padding

RubendeBruin marked this conversation as resolved.
Show resolved Hide resolved
_New in [:octicons-tag-24: 2.7.5](https://github.com/PyFPDF/fpdf2/blob/master/CHANGELOG.md)_
RubendeBruin marked this conversation as resolved.
Show resolved Hide resolved

Cell padding (the space between the cells content and the edge of the cell) can be set globally or on a per-cell basis.

Following the CCS standard the padding can be specified using 1,2 3 or 4 values.
- When one value is specified, it applies the same padding to all four sides.
- When two values are specified, the first padding applies to the top and bottom, the second to the left and right.
- When three values are specified, the first padding applies to the top, the second to the right and left, the third to the bottom.
- When four values are specified, the paddings apply to the top, right, bottom, and left in that order (clockwise)

```python
...
style = FontFace(color=black, fill_color=red)
with pdf.table(line_height=pdf.font_size, padding=2) as table:
for irow in range(5):
row = table.row()
for icol in range(5):
datum = "Circus"
if irow == 3 and icol %2 == 0:
row.cell("custom padding", style=style, padding=(2*icol, 8, 8, 8))
else:
row.cell(datum)
```
(also an example of coloring individual cells)

![img.png](img_table_padding.png)

Note: the `c_margin` parameter (default 1.0) also controls the horizontal margins in a cell. If a non-zero padding for left and right is supplied then c_margin is ignored.


## Setting vertical alignment of text in cells

RubendeBruin marked this conversation as resolved.
Show resolved Hide resolved
_New in [:octicons-tag-24: 2.7.5](https://github.com/PyFPDF/fpdf2/blob/master/CHANGELOG.md)_

Can be set globally or per cell.
Works the same way as padding, but with the `v_align` parameter.

```python

with pdf.table(v_align=VAlign.C) as table:
...
row.cell(f"custom v-align", v_align=VAlign.T) # <-- align to top
```

## Setting row height
```python
...
Expand All @@ -77,7 +123,7 @@ with pdf.table(line_height=2.5 * pdf.font_size) as table:
## Disable table headings
```python
...
with pdf.table(first_row_as_headings=False) as table:y
with pdf.table(first_row_as_headings=False) as table:
...
```

Expand Down Expand Up @@ -229,9 +275,7 @@ Result:

## Column span
Cells spanning multiple columns can be defined by passing a `colspan` argument to `.cell()`.
The cells that are overwritten by the spanned cell are not rendered but must be added to the table.

Result:
Only the cells with data in them need to be defined. This means that the number of cells on each row can be different.
Lucas-C marked this conversation as resolved.
Show resolved Hide resolved

```python
...
Expand All @@ -245,17 +289,17 @@ Result:
row = table.row()
row.cell("A1")
row.cell("A2", colspan=2)
row.cell("void") # <--- this cell is not rendered
row.cell("A4")

row = table.row()
row.cell("B1", colspan=2)
row.cell("void") # <--- this cell is not rendered
row.cell("B3")
row.cell("B4")
...
```

result:

![](image-colspan.png)

## Table from pandas DataFrame
Expand Down
14 changes: 7 additions & 7 deletions docs/Text.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

There are several ways in fpdf to add text to a PDF document, each of which comes with its own special features and its own set of advantages and disadvantages. You will need to pick the right one for your specific task.

| method | lines | markdown support | HTML support | accepts new current position | details |
| -- | :--: | :--: | :--: | :--: | -- |
| [`.text()`](#text) | one | no | no | fixed | Inserts a single-line text string with a precise location on the base line of the font.|
| [`.cell()`](#cell) | one | yes | no | yes | Inserts a single-line text string within the boundaries of a given box, optionally with background and border. |
| [`.multi_cell()`](#multi_cell) | several | yes | no | yes | Inserts a multi-line text string within the boundaries of a given box, optionally with background and border. |
| method | lines | markdown support | HTML support | accepts new current position | details |
| -- | :--: | :--: | :--: | :--: |-----------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [`.text()`](#text) | one | no | no | fixed | Inserts a single-line text string with a precise location on the base line of the font. |
| [`.cell()`](#cell) | one | yes | no | yes | Inserts a single-line text string within the boundaries of a given box, optionally with background and border. |
| [`.multi_cell()`](#multi_cell) | several | yes | no | yes | Inserts a multi-line text string within the boundaries of a given box, optionally with background, border and padding. |
| [`.write()`](#write) | several | no | no | auto | Inserts a multi-line text string within the boundaries of the page margins, starting at the current x/y location (typically the end of the last inserted text). |
| [`.write_html()`](#write_html) | several | no | yes | auto | An extension to `.write()`, with additional parsing of basic HTML tags.
| [`.write_html()`](#write_html) | several | no | yes | auto | An extension to `.write()`, with additional parsing of basic HTML tags.

## Typography and Language Specific Concepts
### Supported Features
Expand Down Expand Up @@ -77,7 +77,7 @@ Allows printing text with word or character based line breaks. Those can be auto
reaches the right border of the cell, or explicit (via the `\\n` character).
As many cells as necessary are stacked, one below the other.
Text can be aligned, centered or justified. The cell block can be framed and
the background painted.
the background painted. Padding between text and the cell edge can be specified in the same way as for tables.

Using `new_x="RIGHT", new_y="TOP", maximum height=pdf.font_size` can be
useful to build tables with multiline text in cells.
Expand Down
Binary file added docs/img_table_padding.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
20 changes: 20 additions & 0 deletions fpdf/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,26 @@ def coerce(cls, value):
return super(cls, cls).coerce(value)


class VAlign(CoerciveEnum):
"""Defines how to vertically render text in a cell.
Default value is CENTER"""

C = intern("CENTER")
RubendeBruin marked this conversation as resolved.
Show resolved Hide resolved
"Center text vertically"

T = intern("TOP")
"Place text at the top of the cell, but obey the cells padding"

B = intern("BOTTOM")
"Place text at the bottom of the cell, but obey the cells padding"

@classmethod
def coerce(cls, value):
if value == "":
return cls.C
return super(cls, cls).coerce(value)


class TextEmphasis(CoerciveIntFlag):
"""
Indicates use of bold / italics / underline.
Expand Down
Loading
Loading