Skip to content

Commit

Permalink
Implement FPDF.table() - close #701 & #723 (#703)
Browse files Browse the repository at this point in the history
  • Loading branch information
Lucas-C authored Mar 27, 2023
1 parent f371035 commit 0579097
Show file tree
Hide file tree
Showing 97 changed files with 1,620 additions and 1,613 deletions.
12 changes: 6 additions & 6 deletions .github/workflows/continuous-integration-workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
python-version: ${{ matrix.python-version }}
- name: Install system dependencies ⚙️
if: matrix.platform == 'ubuntu-latest'
run: sudo apt-get install libjpeg-dev
run: sudo apt-get install ghostscript libjpeg-dev
- name: Install qpdf ⚙️
if: matrix.platform == 'ubuntu-latest' && matrix.python-version != '3.9' # This allows us to run the unit tests WITHOUT qpdf in just one parallel execution
run: sudo apt-get install qpdf
Expand All @@ -35,9 +35,9 @@ jobs:
- name: Statically checking code 🔎
if: matrix.python-version == '3.10' && matrix.platform == 'ubuntu-latest'
run: |
pylint fpdf test tutorial/tuto*.py
bandit -c .banditrc.yml -r contributors/ fpdf/ tutorial/
semgrep scan --config auto --lang=py --error --strict --exclude-rule=python.lang.security.insecure-hash-function.insecure-hash-function fpdf
pylint fpdf test tutorial/tuto*.py
bandit -c .banditrc.yml -r contributors/ fpdf/ tutorial/
semgrep scan --config auto --lang=py --error --strict --exclude-rule=python.lang.security.insecure-hash-function.insecure-hash-function fpdf
- name: Ensure code has been autoformatted with black 🖌️
if: matrix.python-version == '3.10' && matrix.platform == 'ubuntu-latest'
run: black --check .
Expand All @@ -59,7 +59,7 @@ jobs:
# Ensuring there is no `generate=True` left remaining in calls to assert_pdf_equal:
grep -IRF generate=True test/ && exit 1
# Executing all tests:
pytest -vv --final-memory-usage
pytest -vv --trace-memory-usage
- name: Uploading coverage report to codecov.io ☑
if: matrix.python-version == '3.10' && matrix.platform == 'ubuntu-latest'
run: bash <(curl -s https://codecov.io/bash)
Expand All @@ -75,7 +75,7 @@ jobs:
sed -i "s/author:.*/author: v$(python setup.py -V 2>/dev/null)/" mkdocs.yml
cp tutorial/notebook.ipynb docs/
mkdocs build
pdoc --html -o public/ fpdf
pdoc --html -o public/ fpdf --config "git_link_template='https://github.com/PyFPDF/fpdf2/blob/{commit}/{path}#L{start_line}-L{end_line}'"
cd contributors/ && PYTHONUNBUFFERED=1 ./build_contributors_html_page.py PyFPDF/fpdf2
cp -t ../public/ contributors.html contributors-map-small.png
- name: Deploy documentation 🚀
Expand Down
10 changes: 7 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@ in order to get warned about deprecated features used in your code.

This can also be enabled programmatically with `warnings.simplefilter('default', DeprecationWarning)`.

## [2.6.2] - Not released yet
## [2.7.0] - Not released yet
### Added
* [`FPDF.multi_cell()`](https://pyfpdf.github.io/fpdf2/fpdf/fpdf.html#fpdf.fpdf.FPDF.multi_cell) and [`FPDF.write()`](https://pyfpdf.github.io/fpdf2/fpdf/fpdf.html#fpdf.fpdf.FPDF.write) now accept a `wrapmode` argument for word or character based line wrapping ("WORD"/"CHAR").
- new method [`FPDF.table()`](https://pyfpdf.github.io/fpdf2/fpdf/fpdf.html#fpdf.fpdf.FPDF.table): [documentation](https://pyfpdf.github.io/fpdf2/Tables.html)
- [`FPDF.image()`](https://pyfpdf.github.io/fpdf2/fpdf/fpdf.html#fpdf.fpdf.FPDF.image) has a new `keep_aspect_ratio` optional boolean parameter, to fit it inside a given rectangle: [documentation](https://pyfpdf.github.io/fpdf2/Images.html#fitting-an-image-inside-a-rectangle)
- new method `FPDF.preload_image()`: [documentation](https://pyfpdf.github.io/fpdf2/fpdf/fpdf.html#fpdf.fpdf.FPDF.preload_image)
- [`FPDF.multi_cell()`](https://pyfpdf.github.io/fpdf2/fpdf/fpdf.html#fpdf.fpdf.FPDF.multi_cell) and [`FPDF.write()`](https://pyfpdf.github.io/fpdf2/fpdf/fpdf.html#fpdf.fpdf.FPDF.write) now accept a `wrapmode` argument for word or character based line wrapping ("WORD"/"CHAR").
- new methods: [`FPDF.preload_image()`](https://pyfpdf.github.io/fpdf2/fpdf/fpdf.html#fpdf.fpdf.FPDF.preload_image) & [`FPDF.use_font_style()`](https://pyfpdf.github.io/fpdf2/fpdf/fpdf.html#fpdf.fpdf.FPDF.use_font_style)
- new translation of the tutorial in [简体中文](https://pyfpdf.github.io/fpdf2/Tutorial-zh.html) - thanks to @Bubbu0129
- new method [`FPDF.set_fallback_fonts()`](https://pyfpdf.github.io/fpdf2/fpdf/fpdf.html#fpdf.fpdf.FPDF.set_fallback_fonts) allow alternative fonts to be provided if a character on the text is not available on the currently set font - thanks to @andersonhc
- documentation on how to embed static [Plotly](https://plotly.com/python/) charts: [link to docs](https://pyfpdf.github.io/fpdf2/Maths.html)
Expand All @@ -32,10 +33,13 @@ This can also be enabled programmatically with `warnings.simplefilter('default',
- all `TitleStyle` constructor parameters are now effectively optional
- memory usage was reduced by 10 MiB in some cases, thanks to a small optimization in using `fonttools`
### Changed
* [`FPDF.write_html()`](https://pyfpdf.github.io/fpdf2/fpdf/fpdf.html#fpdf.fpdf.FPDF.write_html) now uses the new [`FPDF.table()`](https://pyfpdf.github.io/fpdf2/Tables.html) method to render `<table>` tags. As a consequence, vertical space before `<table>` tags has sometimes been reduced.
- vector images parsing is now more robust: `fpdf2` can now embed SVG files without `viewPort` or no `height` / `width`
- bitonal images are now encoded using `CCITTFaxDecode`, reducing their size in the PDF document - thanks to @eroux
- when possible, JPG and group4 encoded TIFFs are now embedded directly without recompression - thanks to @eroux
- ICC Profiles of included images are now extracted and turned into PDF objects; they should now be taken into account by PDF viewers - thanks to @eroux
### Removed
* [`FPDF.write_html()`](https://pyfpdf.github.io/fpdf2/fpdf/fpdf.html#fpdf.fpdf.FPDF.write_html) now uses the new [`FPDF.table()`](https://pyfpdf.github.io/fpdf2/Tables.html) method to render `<table>` tags. As a consequence, it does not support the `height` attribute defined on `<td>` / `<th>` tags anymore, nor `height` / `width` attributes defined on `<img>` tags inside cells, nor `width` attributes defined on `<thead>` / `<tfoot>` tags.

## [2.6.1] - 2023-01-13
### Added
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ pip install git+https://github.com/PyFPDF/fpdf2.git@master
* Embedding images, including transparency and alpha channel
* Arbitrary path drawing and basic [SVG](https://pyfpdf.github.io/fpdf2/SVG.html) import
* Embedding [barcodes](https://pyfpdf.github.io/fpdf2/Barcodes.html), [charts & graphs](https://pyfpdf.github.io/fpdf2/Maths.html), [emojis, symbols & dingbats](https://pyfpdf.github.io/fpdf2/EmojisSymbolsDingbats.html)
* [Cell / multi-cell / plaintext writing](https://pyfpdf.github.io/fpdf2/Text.html), with [automatic page breaks](https://pyfpdf.github.io/fpdf2/PageBreaks.html), line break and text justification
* [Tables](https://pyfpdf.github.io/fpdf2/Tables.html) and also [cell / multi-cell / plaintext writing](https://pyfpdf.github.io/fpdf2/Text.html), with [automatic page breaks](https://pyfpdf.github.io/fpdf2/PageBreaks.html), line break and text justification
* Choice of measurement unit, page format & margins. Optional page header and footer
* Basic [conversion from HTML to PDF](https://pyfpdf.github.io/fpdf2/HTML.html)
* A [templating system](https://pyfpdf.github.io/fpdf2/Templates.html) to render PDFs in batchs
Expand Down
2 changes: 1 addition & 1 deletion docs/Images.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ When you want to scale an image to fill a rectangle, while keeping its aspect ra
and ensuring it does **not** overflow the rectangle width nor height in the process,
you can set `w` / `h` and also provide `keep_aspect_ratio=True` to the [`image()`](fpdf/fpdf.html#fpdf.fpdf.FPDF.image) method.

The following unit test illustrates that:
The following unit tests illustrate that:

* [test_image_fit.py](https://github.com/PyFPDF/fpdf2/blob/master/test/image/test_image_fit.py)
* resulting document: [image_fit_in_rect.pdf](https://github.com/PyFPDF/fpdf2/blob/master/test/image/image_fit_in_rect.pdf)
Expand Down
27 changes: 11 additions & 16 deletions docs/Maths.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,25 +128,20 @@ columns = [list(df)] # Get list of dataframe columns
rows = df.values.tolist() # Get list of dataframe rows
data = columns + rows # Combine columns and rows in one list

# Start pdf creating
pdf = FPDF()
pdf.add_page()
pdf.set_font("Times", size=10)
line_height = pdf.font_size * 2.5
col_width = pdf.epw / 4 # distribute content evenly

for row in data:
for datum in row:
pdf.multi_cell(
col_width,
line_height,
datum,
border=1,
new_y="TOP",
max_line_height=pdf.font_size,
)
pdf.ln(line_height)
pdf.output("table_with_cells.pdf")
with pdf.table(borders_layout="MINIMAL",
cell_fill_color=200, # grey
cell_fill_mode="ROWS",
line_height=pdf.font_size * 2.5,
text_align="CENTER",
width=160) as table:
for data_row in data:
row = table.row()
for datum in data_row:
row.cell(datum)
pdf.output("table_from_pandas.pdf")
```

Result:
Expand Down
Loading

0 comments on commit 0579097

Please sign in to comment.