Releases: py-pdf/fpdf2
Releases · py-pdf/fpdf2
Support for page labels & Python 3.13 - various fixes & improvements
Added
- new optional parameter
border
for table cells: users can define specific borders (left, right, top, bottom) for individual cells - thanks to @Kaustbh - issue #1192 FPDF.write_html()
: now parses<title>
tags to set the document title. By default, it is added as PDF metadata, but not rendered in the document body. However, this can be enabled by passingrender_title_tag=True
toFPDF.write_html()
.- support for LZWDecode compression - thanks to @opposss - issue #1271
- Python 3.13 is now officially supported
- support for page labels and created a reference table of contents implementation - thanks to @andersonhc - PR #1188
- documentation on how to: render spreadsheets as PDF tables
- support for passing
Align
values (along with string values like'C'
,'L'
,'R'
) inl_margin
ofTextStyle
to horizontally align text - issue #1282
Fixed
- support for
align=
inFPDF.table()
. Due to this correction, tables are now properly horizontally aligned on the page by default. This was always specified in the documentation, but was not in effect until now. You can revert to have left-aligned tables by passingalign="LEFT"
toFPDF.table()
. FPDF.set_text_shaping(False)
was broken since version 2.7.8 and is now working properly - issue #1287- fixed bug where cells with
rowspan
,colspan
> 1 and null text were not displayed properly - issue #1293 CreationDate
metadata used a wrong timezone offset for UTC - issue #1261insert_toc_placeholder()
did not properly the page orientation, which caused a bug when the last page of the document was in a different orientation - issue #1213
Changed
- improved logic for handling text substitution of the total number of pages, ensuring compatibility with text shaping - issue #1090
- all
AnnotationDict
properties can now be passed toFPDF.text_annotation()
,FPDF.free_text_annotation()
,FPDF.add_action()
,FPDF.add_text_markup_annotation()
&FPDF.ink_annotation()
. This includestitle
,color
,border_width
...
Removed
- reminder : since release
2.8.1
,fpdf2
does not support Python 3.7, that reached end-of-life in 2023
FPDF.bezier() to render quadratic and cubic Bézier curves, and many improvements
Note: a temporary 2.8.0 version was released but then erroneously removed on Pypi.
Versions 2.8.0 & 2.8.1 are exactly the same.
Added
- support for quadratic and cubic Bézier curves with
FPDF.bezier()
- thanks to @awmc000 - support for escape character for markers in markdown text issue #1215
- Wrapping words on spaces now considers all common space symbols in addition to regular spaces (' '), addressing issues with word-wrapping for languages like Thai, as per #1190 and #1191.
Templates
can now be also defined in JSON files.- support to optionally set
wrapmode
in templates (default"WORD"
can optionally be set to"CHAR"
to support wrapping on characters for scripts like Chinese or Japanese) - cf. #1159 - thanks to @carlhiggs - documentation on how to use
fpdf2
with Rough.js: link to docs - documentation on how to use
fpdf2
with gunicorn: link to docs - new translation of the tutorial in Türkçe, thanks to @Natgho: Türkçe
- feature to identify the Unicode script of the input text and break it into fragments when different scripts are used, improving text shaping results
FPDF.image()
: now handleskeep_aspect_ratio
in combination with an enum value provided tox
FPDF.write_html()
: now supports CSS page breaks properties : documentationFPDF.write_html()
: new optionalfont_family
parameter to set the default font familyFPDF.write_html()
: spacing before lists can now be adjusted via thetag_styles
attribute - thanks to @lcgeneralprojects- file names are mentioned in errors when
fpdf2
fails to parse a SVG image
Fixed
FPDF.local_context()
used to leak styling during page breaks, when renderingfooter()
&header()
- MR: #1207fpdf.drawing.DeviceCMYK
objects can now be passed toFPDF.set_draw_color()
,FPDF.set_fill_color()
andFPDF.set_text_color()
without raising aValueError
: documentation.FPDF.write_html()
: fixing rendering of<hr>
tags, that do not trigger a page break anymoreFPDF.write_html()
: fixed automatic page break when an image does not have enough vertical space to be rendered on a page- individual
/Resources
directories are now properly created for each document page. This change ensures better compliance with the PDF specification but results in a slight increase in the size of PDF documents. You can still use the old behavior by settingFPDF().single_resources_object = True
- line size calculation for fragments when text shaping is used
FPDF.write_html()
: fixed incoherent indentation of long<ul>
list entries - cf. issue #1073 - thanks to @lcgeneralprojects- default values for
top_margin
andbottom_margin
inHTML2FPDF._new_paragraph()
calls are now correctly converted into chosen document units. - In text_columns(), paragraph top/bottom margins didn't correctly trigger column breaks; issue #1214
fpdf.drawing.color_from_hex_string
did not test or mention accepting lowercase hex values.- handling of bidirectional text on
FPDF.get_string_width()
[issue #1231] - new translation of the tutorial in Indonesian - thanks to @odhyp
RecursionError
in some cases when callingFPDF.write_html()
insideFPDF.footer()
- issue #1222
Removed
- support for Python 3.7, that reached end-of-life in 2023
- an obscure and undocumented feature of
FPDF.write_html()
, which used to magically pass instance attributes as arguments.
Deprecated
fpdf.TitleStyle
has been renamed intofpdf.TextStyle
FPDF.write_html()
:tag_indents
introduced in the last version - Now the indentation can be provided through thetag_styles
parameter, using the.l_margin
ofTextStyle
instances
Changed
FPDF.local_context()
used to treatfont_size
as a value in points. Now this is the role offont_size_pt
, whereasfont_size
allows to set the font size into chosen document units (specified withFPDF(unit=)
) - MR: #1207FPDF.circle()
: the previousr
parameter, that in fact defined the diameter, has been replaced by a newradius
paremeter. Thex
&y
parameters now define the circle center, instead of its top-left corner as it used to be - issue #1245FPDF.table()
now raises an error when a single row is too high to be rendered on a single pageFPDF.write_html()
: indentation of HTML elements can now be non-integer (float), and is now independent of font size and bullet strings.- improved performance of font glyph selection by using functools cache
- Clarified usage of the
style
attribute inFPDF.add_font()
Improvements on `table()` and `write_html()`, and several bugfixes.
Added
- new optional parameter
repeat_headings
forFPDF.table()
that indicates whether to print table headings on every page - support for overriding paragraph direction on bidirectional text
- new optional
li_prefix_color
parameter forFPDF.write_html()
- support for
start
&type
attributes of<ol>
tags, andtype
attribute of<ul>
tags, when usingFPDF.write_html()
FPDF.write_html()
now accepts atag_styles
parameter to control the font, color & size of HTML elements:<a>
,<blockquote>
,<li>
...FPDF.write_html()
now accepts atag_indents
parameter to control, for example, the indent of<blockquote>
elementsFPDF.write_html()
now honorsline-height
attributes on<ol>
&<li>
elements, or the same CSS property instyle
attributes on those tags- allow to define custom
cell_fill_mode
logic for tables: Set cells background - documentation section. Also added 2 new values:TableCellFillMode.EVEN_ROWS
&TableCellFillMode.EVEN_COLUMNS
: documentation
Fixed
- a bug when rendering vector images with dashed lines that caused a warning message in Adobe Acrobat Reader
- ordering RTL fragments on bidirectional texts
- fixed type hint of member
level
in classOutlineSection
fromstr
toint
. - SVG clipping paths being incorrectly painted - cf. issue #1147]
- new translation of the tutorial in Polski - thanks to @DarekRepos
Changed
- improved the performance of
FPDF.start_section()
- cf. issue #1092
Deprecated
- The
dd_tag_indent
&li_tag_indent
parameters ofFPDF.write_html()
are replaced by the newtag_indents
generic parameter. - The
heading_sizes
&pre_code_font
parameters ofFPDF.write_html()
are replaced by the newtag_styles
generic parameter.
Table improvements, bidirectional text support, support for <path> in SVG and several bug fixes
Added
- support for
<path>
elements in SVG<clipPath>
elements - support for
bidirectional
text shaping - thanks to @andersonhc - documentation on how to combine
fpdf2
with mistletoe in order to generate PDF documents from Markdown (link) - tutorial in Dutch: Handleiding - thanks to @Polderrider
- support for
Table
cells that span multiple rows via therowspan
attribute, which can be combined withcolspan
- thanks to @mjasperse TableSpan.COL
andTableSpan.ROW
enums that can be used as placeholder table entries to identify span extents - thanks to @mjasperse
Fixed
- when adding a link on a table cell, an extra link was added erroneously on the left. Moreover, now
FPDF._disable_writing()
properly disable link writing. FPDF.write_html()
now handles linking directly to other pages - thanks to @mjasperse- non-bold
TitleStyle
is now rendered as non-bold even when the current font is bold - calling
.table()
inside therender_toc_function
- using
.set_text_shaping(True)
&.offset_rendering()
- fixed gutter handing when a pagebreak occurs within a table with header rows - thanks to @mjasperse
- fixed handling of
border=0
in HTML table - thanks to @mjasperse FPDF.write_html()
now properly honorsalign=
attributes in<th>
tags- fixed problem using bold italic standard fonts in markdown - thanks to @Alan-Collins
Changed
- refactored
FPDF.multi_cell()
to generate fewer PDF component objects - thanks to @mjasperse - outer table borders are now drawn continuously for nonzero
gutter_width
/gutter_height
, with spacing applied inside the border similar to HTML tables - thanks to @mjasperse - cf. #1071 - removed the requirement that all rows in a
Table
have the same number of columns - thanks to @mjasperse
Deprecated
- font aliases (
Arial
→Helvetica
,CourierNew
→Courer
,TimesNewRoman
→Times
). They will be removed in a later release.
Support for Images and Clipping Paths in SVG files - Python 3.12 Support - Several Bugfixes
Added
- Basic support for
<image>
elements in SVG vector graphics inserted - SVG importing now supports clipping paths, and
<defs>
tags anywhere in the SVG file - thanks to @afriedman412 - cf. #968 FPDF.fonts.FontFace
: Now has a staticcombine
method that allows overriding a default FontFace (e.g. for specific cells in a table). Unspecified properties of the override FontFace retain the values of the default - thanks to @TedBrookings - cf. #979TextColumns()
can now have images inserted (both raster and vector) - thanks to @gmischlerTextColumns()
can now advance to the next column with the newnew_column()
method or a FORM_FEED character (\u000c
) in the text - thanks to @gmischler- Added support for Free Text annotations: documentation - thanks to @MarekT0v - cf. #1039
- Tutorial in Dutch: Handleiding - thanks to @Polderrider
- Python 3.12 is now officially supported
Fixed
- Links over text in tables were broken in release 2.7.6, this is now fixed
FPDF.set_font_color()
raised aTypeError
when used in tablesFPDF.image(x=Align.C)
used to fail for SVG images - fixed thanks to @gmischler - cf. #1003- Previously set dash patterns were not transferred correctly to new pages - fixed thanks to @gmischler - cf. #993
- Inserted Vector images used to ignore the
keep_aspect_ratio
argument. FPDF.write_html()
now properly honor the current text font color when styling table cellsFPDF.write_html()
delays unescaping data so as not to confuse entity names as nested tagsFPDF.multi_cell()
has improved handling ofnew_x
andnew_y
whenpadding
is non-zero.FPDF.multi_cell(fill=True)
now avoids overlapping multiline strings whenpadding
is non-zero.
Changed
- the public
.images
,.icc_profiles
&.image_filter
attributes ofFPDF
instances have been moved inside a nestedFPDF.image_cache
attribute. Similarly, theFPDF.preload_image()
is now a function in thefpdf.image_parsing
module: documentation - the
fpdf.svg
module now producesWARNING
log messages for unsupported SVG tags & attributes.
If those logs annoy you, you can suppress them:logging.getLogger("fpdf.svg").propagate = False
FPDF.table()
: If cell styles are provided for cells in heading rows, combine the cell style as an override with the overall heading style.
Improvements to FPDF.table() - Text regions layout management - several bugfixes
This release is the first performed from the @py-pdf GitHub org, where fpdf2
migrated.
This release also marks the arrival of two new maintainers: Georg Mischler (@gmischler) and Anderson Herzogenrath da Costa (@andersonhc).
Added
- The new experimental method
text_columns()
allows to render text within a single or multiple columns, including height balancing: documentation FPDF.write_html()
now supports heading colors defined as attributes (e.g.<h2 color="#00ff00">...
)FPDF.table()
: Now supports padding in cells : documentationFPDF.table()
: Now supports vertical alignment in cells : documentationFPDF.table()
: Now supports outer border width for rendering the outer border of the table with a different line-widthFPDF.table()
: Now supports multiple heading rows : documentation- documentation on how to use
livereload
to enable a "watch" mode with PDF generation: Combine with livereload
Changed
- The formatting output by
write_html()
has changed in some aspects. Vertical spacing around headings and paragraphs may be slightly different, and elements at the top of the page don't have any extra spacing above anymore. 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".- variable-width non-breaking space (NBSP) support issue #834
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
- In multi_cells and table cells with horizontal padding, the text was not given quite enough space.
write_html()
can now handle formatting tags within paragraphs without adding extra line breaks (except in table cells for now).- the font size in HTML
<pre>
and<code>
tags is not fixed to 11 pica anymore, but adapts to the preceding text. FPDF.ln()
, when called before any text has been written, will now use the current font height instead of doing nothing - cf. issue #937FPDF.image()
, when provided aBytesIO
instance, does not close it anymore - cf. issue #881- Invalid characters were being generated when a string contains parentheses - cf. issue #884
- Frozen Glyph dataclass was causing problems for FPDFRecorder with TTF fonts - cf. issue #890
- Edge case when parsing a Markdown link followed by a newline - cf. issue #916, and when bold/italics/underline markers are repeated
- Zoom not set correctly when a numeric value was set in
set_display_mode()
- cf. issue #926 FPDF.table()
: images no longer overlap with cell borders - cf. issue #892- Encryption of strings containing non-latin characters - cf. issue #933
- Handling of fragments with zero-length - cf. issue #902
Deprecated
- to improve naming consistency, the
txt
parameters ofFPDF.cell()
,FPDF.multi_cell()
,FPDF.text()
&FPDF.write()
have been renamed totext
Text shaping using Harfbuzz - New mirror() method - New AES-256 encryption - Several bugfixes
Added
FPDF.set_text_shaping()
: new method to perform text shaping using Harfbuzz - documentation - thanks to @andersonhc in PR #820FPDF.mirror()
- New method: documentation page - Contributed by @sebastiantiaFPDF.table()
: new optional parametersgutter_height
,gutter_width
andwrapmode
. Links can also be added to cells by passing alink
parameter toRow.cell()
FPDF.multi_cell()
: has a new optionalcenter
parameter to position the cell horizontally at the center of the page- New AES-256 encryption: documentation - thanks to @andersonhc in PR #872
- Added tutorial in Khmer language: ភាសខ្មែរ - thanks to @kuth-chi
- Added tutorial in 日本語 - thanks to @alcnaka
- Better documentation & errors when facing HTML rendering limitations for
<table>
tags: https://pyfpdf.github.io/fpdf2/HTML.html
Fixed
FPDF.table()
: thecolspan
setting has been fixed - documentationFPDF.image()
: allowing images path starting withdata
to be passed as input- text overflow is better handled by
FPDF.write()
&FPDF.write_html()
- cf. issue #847 - the initial text color is preserved when using
FPDF.write_html()
- cf. issue #846 - PDF metadata not encrypted - cf. issue #865
- handle superscript and subscript correctly when rendering
TextLine
- thanks to @Tolker-KU - cf. Pull Request #862 - make sure warnings always point to the users code - cf. Pull request #869
Deprecated
- the
center
optional parameter ofFPDF.cell()
is no more deprecated, as it allows for horizontal positioning, which is different from text alignment control withalign="C"
Images can now be embedded as CMYK - Docs for using Pygal & FastAPI - Various bugfixes
Added
FPDF.image()
: CMYK images can now be inserted directly by passing them into the image method. Contributed by @devdev29- documentation on how to embed
graphs
andcharts
generated usingPygal
lib: documentation section - thanks to @ssavi-ict - documentation on how to use
fpdf2
with FastAPI: https://pyfpdf.github.io/fpdf2/UsageInWebAPI.html#FastAPI - thanks to @KamarulAdha FPDF.write_html()
:<table>
elements can now be aligned left or right on the page usingalign=
FPDF.write_html()
: a custom font can now be specified for<code>
&<pre>
elements, using the new optional parameterpre_code_font
Fixed
FPDF.table()
: images no more overflow cellsFPDF.table()
: text overflow in the last cell of the header row is now properly handledFPDF.table()
: whenalign="RIGHT"
is provided, the page right margin is now properly taken in consideration
Changed
FPDF.write_html()
does not render the top row as a header, in bold with a line below, when no<th>
are used, in order to be more backward-compatible with earlier versions offpdf2
- cf. #740
Deprecated
- the
split_only
optional parameter ofFPDF.multi_cell()
, which is replaced by two new distincts optional parameters:dry_run
&output
Removing debug print() statement
Fixed
- removed a debug
print()
statement left inoutput.py:OutputProducer._add_fonts()
🤦♂️ - A rule was also added to.pre-commit-config.yaml
to avoid this to happen again.
SVG & table() bugfixes
Fixed
- custom fonts can be used with
FPDF.table()
without triggering aTypeError: cannot pickle 'dict_keys' object
- thanks @aeris07 for the bug report - the SVG parser now accepts
<rect>
withwidth
/height
defined as percents