Website py-pdf
$ pip install -r requirements.txt
$ pre-commit install
$ invoke livereload
- Edit
requirements.in
- Run
pip-compile requirements.in
to generaterequirements.txt
$ make github
This project forked from reingart/pyfpdf
Simple PDF generation for Python
Home Page: https://py-pdf.github.io/fpdf2/
License: GNU Lesser General Public License v3.0
I'm currently looking into options to generate a PDF via python. We are currently using LaTeX but it is slow and this project does look good. Especially that it seems to be pythonic.
In the image methods the documentation states that only image format like JPG are supported.
Is there any way to insert PDF, .esp or .svg images (any vector format)? This would be crucial for us.
This would make clearer for all users that this repo is the source code behind the fpdf2
lib: https://pypi.org/project/fpdf2/
What do you think?
The scope of this feature is to add support to fpdf2 to produce linearized PDFs.
Appendix F of the PDF 1.7 spec should be helpful in implementing this.
Linearized PDF requires two additions to the PDF specification:
• Rules for the ordering of objects in the PDF file
• Additional optional data structures, called hint tables, that enable efficient navigation within the document
qpdf --check-linearization / --show-linearization
can also be used to ensure the generated PDFs are valid.
By implementing this feature you, as a benevolent FLOSS developper, will provide access to the large community of fpdf2 users to a standard and useful PDF functionality.
Moreover, by working on this feature, you will learn about PDFs syntax and the lifecycle & structure of a popular Python library.
You will also be added into the contributors list & map.
As a contributor you will be able to design and expose this feature as you want in the library.
Implementing this can count as part of hacktoberfest
The .htm
files refer to PHP code but the .py
files seem OK.
The first 3 tutorials are already covered in docs/Tutorial.md
.
Remain the 3 last ones:
4. lay the text across multiple columns
5. tables
6. insert links (internal and external) and shows a new text writing mode + rudimentary HTML parser
Quoting https://docs.verapdf.org/validation/pdfa-part1/#rule-653-2:
For all CIDFont subsets referenced within a conforming file, the font descriptor dictionary shall include a CIDSet stream identifying which CIDs are present in the embedded CIDFont file, as described in PDF Reference Table 5.20.
For now this rule is disabled in scripts/verapdf-ignore.json
You can use the following commands to run VeraPDF on PDF files in this repository, once you have cloned it:
scripts/install-verapdf.sh
# The following command will analyze the given PDF file, generate verapdf-aggregated.json and finally display the aggregated report:
rm -f verapdf-aggregated.json && scripts/verapdf.py $path/to/file.pdf && scripts/verapdf.py
# You can also directly call VeraPDF, without our Python wrapper script:
verapdf/verapdf --format text -v $path/to/file.pdf
It would be good summarize the releases, maybe even tag them in vcs and sum up the changes, and grab dates from the commits.
Maybe using https://github.com/lincolnloop/python-qrcode?
The existing code39 method can be used as an model.
How can be created a table with borders to each cells?
Using write_html, I can set borders to the TABLE but not to each TD.
I tried to use the Computer Modern (CM) fonts (https://ctan.org/pkg/bakoma-fonts) with pyfpdf but failed.
Also tried to add the font via the .ttf
file but I get a UnpicklingError: invalid load key, '\x00'
exception.
pdf.add_font('cmss12', fname='cmss12.ttf')
pdf.set_font('cmss12', '', 16)
Open parenthesis '(' and close parenthesis ')' is not shown correctly in justified mode if UNICODE font is used. Parenthesis' were replaced with two squares which I believe are Japanese letters.
When installing with python3.9, the following error message occurs (private details omitted):
pillow also has a list of compatible versions to reference here so that's probably something to just update, the question is which one? I don't remember why the current version was chosen.
(39env) $USER@HOSTNAME:~$ pip install fpdf2
Collecting fpdf2
Using cached fpdf2-2.0.5-py2.py3-none-any.whl (71 kB)
Collecting numpy
Using cached numpy-1.19.2.zip (7.3 MB)
Installing build dependencies ... done
Getting requirements to build wheel ... done
Preparing wheel metadata ... done
Collecting Pillow<7.0,>=4
Downloading Pillow-6.2.2.tar.gz (37.8 MB)
|████████████████████████████████| 37.8 MB 6.2 MB/s
Collecting six
Downloading six-1.15.0-py2.py3-none-any.whl (10 kB)
Collecting future
Using cached future-0.18.2.tar.gz (829 kB)
Building wheels for collected packages: numpy, Pillow, future
Building wheel for numpy (PEP 517) ... done
Created wheel for numpy: filename=numpy-1.19.2-cp39-cp39-linux_x86_64.whl size=16980752 sha256=d916775dd4dd8eb16f3313270470bc0059de0dadcb5f8e1e51027f86d4ec060c
Stored in directory: $HOME/.cache/pip/wheels/a3/17/dd/f2dba23a35bb6008732772ccfb13d3d0e537fbc6919ce6862b
Building wheel for Pillow (setup.py) ... error
ERROR: Command errored out with exit status 1:
command: $VIRTUALENV/bin/python -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'$PIP_TEMP_DIR/pillow/setup.py'"'"'; __file__='"'"'$PIP_TEMP_DIR/pillow/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' bdist_wheel -d /tmp/pip-wheel-237g34ts
cwd: $PIP_TEMP_DIR/pillow/
Complete output (172 lines):
running bdist_wheel
running build
running build_py
creating build
creating build/lib.linux-x86_64-3.9
creating build/lib.linux-x86_64-3.9/PIL
copying src/PIL/PdfImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/MpegImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/ImtImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/ImageWin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/McIdasImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/ImageDraw.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/JpegImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/ContainerIO.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/BlpImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/ImageFile.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/BmpImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/MpoImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/PdfParser.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/ImageFilter.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/__main__.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/Image.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/Hdf5StubImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/PngImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/ImageGrab.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/IcoImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/ImageMorph.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/SgiImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/PaletteFile.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/BufrStubImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/PalmImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/MicImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/EpsImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/DcxImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/ImageMath.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/FliImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/WebPImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/PyAccess.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/ImageShow.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/FpxImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/FtexImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/BdfFontFile.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/TgaImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/WalImageFile.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/ImageDraw2.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/ImageEnhance.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/_binary.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/PcfFontFile.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/PcxImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/WmfImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/ImImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/DdsImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/ExifTags.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/XpmImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/SpiderImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/ImageOps.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/ImagePalette.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/_version.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/MspImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/IptcImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/_tkinter_finder.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/PpmImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/PSDraw.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/ImageTk.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/PsdImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/GimpGradientFile.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/XbmImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/ImageFont.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/ImageStat.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/ImageCms.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/TarIO.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/Jpeg2KImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/GribStubImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/GifImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/GbrImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/ImageColor.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/ImageMode.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/XVThumbImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/PcdImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/ImageChops.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/ImagePath.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/IcnsImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/TiffImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/ImageSequence.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/TiffTags.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/PixarImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/features.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/SunImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/CurImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/__init__.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/GimpPaletteFile.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/ImageQt.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/_util.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/ImageTransform.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/JpegPresets.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/FitsStubImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/FontFile.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/GdImageFile.py -> build/lib.linux-x86_64-3.9/PIL
running egg_info
writing src/Pillow.egg-info/PKG-INFO
writing dependency_links to src/Pillow.egg-info/dependency_links.txt
writing top-level names to src/Pillow.egg-info/top_level.txt
reading manifest file 'src/Pillow.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
warning: no files found matching '*.c'
warning: no files found matching '*.h'
warning: no files found matching '*.sh'
warning: no previously-included files found matching '.appveyor.yml'
warning: no previously-included files found matching '.coveragerc'
warning: no previously-included files found matching '.codecov.yml'
warning: no previously-included files found matching '.editorconfig'
warning: no previously-included files found matching '.readthedocs.yml'
warning: no previously-included files found matching 'azure-pipelines.yml'
warning: no previously-included files matching '.git*' found anywhere in distribution
warning: no previously-included files matching '*.pyc' found anywhere in distribution
warning: no previously-included files matching '*.so' found anywhere in distribution
no previously-included directories found matching '.azure-pipelines'
no previously-included directories found matching '.travis'
writing manifest file 'src/Pillow.egg-info/SOURCES.txt'
running build_ext
The headers or library files could not be found for jpeg,
a required dependency when compiling Pillow from source.
Please see the install instructions at:
https://pillow.readthedocs.io/en/latest/installation.html
Traceback (most recent call last):
File "$PIP_TEMP_DIR/pillow/setup.py", line 852, in <module>
setup(
File "$VIRTUALENV/lib/python3.9/site-packages/setuptools/__init__.py", line 153, in setup
return distutils.core.setup(**attrs)
File "$PYTHON_INSTALLATION/distutils/core.py", line 148, in setup
dist.run_commands()
File "$PYTHON_INSTALLATION/distutils/dist.py", line 966, in run_commands
self.run_command(cmd)
File "$PYTHON_INSTALLATION/distutils/dist.py", line 985, in run_command
cmd_obj.run()
File "$VIRTUALENV/lib/python3.9/site-packages/wheel/bdist_wheel.py", line 290, in run
self.run_command('build')
File "$PYTHON_INSTALLATION/distutils/cmd.py", line 313, in run_command
self.distribution.run_command(command)
File "$PYTHON_INSTALLATION/distutils/dist.py", line 985, in run_command
cmd_obj.run()
File "$PYTHON_INSTALLATION/distutils/command/build.py", line 135, in run
self.run_command(cmd_name)
File "$PYTHON_INSTALLATION/distutils/cmd.py", line 313, in run_command
self.distribution.run_command(command)
File "$PYTHON_INSTALLATION/distutils/dist.py", line 985, in run_command
cmd_obj.run()
File "$PYTHON_INSTALLATION/distutils/command/build_ext.py", line 340, in run
self.build_extensions()
File "$PIP_TEMP_DIR/pillow/setup.py", line 687, in build_extensions
raise RequiredDependencyException(f)
__main__.RequiredDependencyException: jpeg
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "$PIP_TEMP_DIR/pillow/setup.py", line 903, in <module>
raise RequiredDependencyException(msg)
__main__.RequiredDependencyException:
The headers or library files could not be found for jpeg,
a required dependency when compiling Pillow from source.
Please see the install instructions at:
https://pillow.readthedocs.io/en/latest/installation.html
----------------------------------------
ERROR: Failed building wheel for Pillow
Running setup.py clean for Pillow
Building wheel for future (setup.py) ... done
Created wheel for future: filename=future-0.18.2-py3-none-any.whl size=491059 sha256=25ce33157ac5f32d404f80c8768c0f7be1c193ef4c2a03497600e475a8a140a7
Stored in directory: $HOME/.cache/pip/wheels/2f/a0/d3/4030d9f80e6b3be787f19fc911b8e7aa462986a40ab1e4bb94
Successfully built numpy future
Failed to build Pillow
Installing collected packages: numpy, Pillow, six, future, fpdf2
Running setup.py install for Pillow ... error
ERROR: Command errored out with exit status 1:
command: $VIRTUALENV/bin/python -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'$PIP_TEMP_DIR/pillow/setup.py'"'"'; __file__='"'"'$PIP_TEMP_DIR/pillow/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record /tmp/pip-record-6sq9ss4q/install-record.txt --single-version-externally-managed --compile --install-headers $VIRTUALENV/include/site/python3.9/Pillow
cwd: $PIP_TEMP_DIR/pillow/
Complete output (174 lines):
running install
running build
running build_py
creating build
creating build/lib.linux-x86_64-3.9
creating build/lib.linux-x86_64-3.9/PIL
copying src/PIL/PdfImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/MpegImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/ImtImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/ImageWin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/McIdasImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/ImageDraw.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/JpegImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/ContainerIO.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/BlpImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/ImageFile.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/BmpImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/MpoImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/PdfParser.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/ImageFilter.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/__main__.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/Image.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/Hdf5StubImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/PngImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/ImageGrab.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/IcoImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/ImageMorph.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/SgiImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/PaletteFile.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/BufrStubImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/PalmImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/MicImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/EpsImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/DcxImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/ImageMath.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/FliImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/WebPImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/PyAccess.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/ImageShow.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/FpxImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/FtexImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/BdfFontFile.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/TgaImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/WalImageFile.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/ImageDraw2.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/ImageEnhance.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/_binary.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/PcfFontFile.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/PcxImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/WmfImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/ImImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/DdsImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/ExifTags.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/XpmImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/SpiderImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/ImageOps.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/ImagePalette.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/_version.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/MspImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/IptcImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/_tkinter_finder.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/PpmImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/PSDraw.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/ImageTk.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/PsdImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/GimpGradientFile.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/XbmImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/ImageFont.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/ImageStat.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/ImageCms.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/TarIO.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/Jpeg2KImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/GribStubImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/GifImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/GbrImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/ImageColor.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/ImageMode.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/XVThumbImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/PcdImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/ImageChops.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/ImagePath.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/IcnsImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/TiffImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/ImageSequence.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/TiffTags.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/PixarImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/features.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/SunImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/CurImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/__init__.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/GimpPaletteFile.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/ImageQt.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/_util.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/ImageTransform.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/JpegPresets.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/FitsStubImagePlugin.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/FontFile.py -> build/lib.linux-x86_64-3.9/PIL
copying src/PIL/GdImageFile.py -> build/lib.linux-x86_64-3.9/PIL
running egg_info
writing src/Pillow.egg-info/PKG-INFO
writing dependency_links to src/Pillow.egg-info/dependency_links.txt
writing top-level names to src/Pillow.egg-info/top_level.txt
reading manifest file 'src/Pillow.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
warning: no files found matching '*.c'
warning: no files found matching '*.h'
warning: no files found matching '*.sh'
warning: no previously-included files found matching '.appveyor.yml'
warning: no previously-included files found matching '.coveragerc'
warning: no previously-included files found matching '.codecov.yml'
warning: no previously-included files found matching '.editorconfig'
warning: no previously-included files found matching '.readthedocs.yml'
warning: no previously-included files found matching 'azure-pipelines.yml'
warning: no previously-included files matching '.git*' found anywhere in distribution
warning: no previously-included files matching '*.pyc' found anywhere in distribution
warning: no previously-included files matching '*.so' found anywhere in distribution
no previously-included directories found matching '.azure-pipelines'
no previously-included directories found matching '.travis'
writing manifest file 'src/Pillow.egg-info/SOURCES.txt'
running build_ext
The headers or library files could not be found for jpeg,
a required dependency when compiling Pillow from source.
Please see the install instructions at:
https://pillow.readthedocs.io/en/latest/installation.html
Traceback (most recent call last):
File "$PIP_TEMP_DIR/pillow/setup.py", line 852, in <module>
setup(
File "$VIRTUALENV/lib/python3.9/site-packages/setuptools/__init__.py", line 153, in setup
return distutils.core.setup(**attrs)
File "$PYTHON_INSTALLATION/distutils/core.py", line 148, in setup
dist.run_commands()
File "$PYTHON_INSTALLATION/distutils/dist.py", line 966, in run_commands
self.run_command(cmd)
File "$PYTHON_INSTALLATION/distutils/dist.py", line 985, in run_command
cmd_obj.run()
File "$VIRTUALENV/lib/python3.9/site-packages/setuptools/command/install.py", line 61, in run
return orig.install.run(self)
File "$PYTHON_INSTALLATION/distutils/command/install.py", line 590, in run
self.run_command('build')
File "$PYTHON_INSTALLATION/distutils/cmd.py", line 313, in run_command
self.distribution.run_command(command)
File "$PYTHON_INSTALLATION/distutils/dist.py", line 985, in run_command
cmd_obj.run()
File "$PYTHON_INSTALLATION/distutils/command/build.py", line 135, in run
self.run_command(cmd_name)
File "$PYTHON_INSTALLATION/distutils/cmd.py", line 313, in run_command
self.distribution.run_command(command)
File "$PYTHON_INSTALLATION/distutils/dist.py", line 985, in run_command
cmd_obj.run()
File "$PYTHON_INSTALLATION/distutils/command/build_ext.py", line 340, in run
self.build_extensions()
File "$PIP_TEMP_DIR/pillow/setup.py", line 687, in build_extensions
raise RequiredDependencyException(f)
__main__.RequiredDependencyException: jpeg
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "$PIP_TEMP_DIR/pillow/setup.py", line 903, in <module>
raise RequiredDependencyException(msg)
__main__.RequiredDependencyException:
The headers or library files could not be found for jpeg,
a required dependency when compiling Pillow from source.
Please see the install instructions at:
https://pillow.readthedocs.io/en/latest/installation.html
----------------------------------------
ERROR: Command errored out with exit status 1: $VIRTUALENV/bin/python -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'$PIP_TEMP_DIR/pillow/setup.py'"'"'; __file__='"'"'$PIP_TEMP_DIR/pillow/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record /tmp/pip-record-6sq9ss4q/install-record.txt --single-version-externally-managed --compile --install-headers $VIRTUALENV/include/site/python3.9/Pillow Check the logs for full command output.
WARNING: You are using pip version 20.2.3; however, version 20.2.4 is available.
You should consider upgrading via the '$VIRTUALENV/bin/python -m pip install --upgrade pip' command.
I'm currently working on a project which uses the fpdf library to generate PDF files. I'm looking into options to highlight some specific words in a cell (or multi_cell) using bold or Italic text. I found that we can use multiple cells with different font styles to achieve this but if we have multiple words that need to be styled, this idea is not so efficient. It makes the code messy and reduces the readability of the code.
I'm also willing to work on this and contribute to this library. Can we discuss it?
Thanks
cf. PDF-417 on Wikipedia
Maybe using https://github.com/mosquito/pdf417?
The existing code39 method can be used as an model.
It seems to me that the API docs generated with pdoc
serve the same purpose as the Markdown files in docs/reference.
Hence the idea would be to remove docs/reference
after migrating all those useful API docs directly in the code as docstrings.
Moreover, in my experience the closest the doc is to the code, the higher are the chances to keep it up-to-date as the code evolves.
What do you think?
I'm having an issue when using multi_cell with a unicode font, it seems like I get corrupted characters when a line break occurs and the line contains a parenthesis before the line break. This doesn't occur when I use pdf.write.
Python: 3.9.2
fpdf2: 2.3.1
I've been able to reproduce the issue with a sample project:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from fpdf import FPDF
pdf = FPDF()
pdf.add_page()
# Add a DejaVu Unicode font (uses UTF-8)
# Supports more than 200 languages. For a coverage status see:
# http://dejavu.svn.sourceforge.net/viewvc/dejavu/trunk/dejavu-fonts/langcover.txt
pdf.add_font('DejaVu', '', 'DejaVuSans.ttf', uni=True)
pdf.set_font('DejaVu', '', 14)
text = """
Line wrap : lorem () dolor sit amet, consectetur sit amet adipiscing elit et dolore
No wrap : ipsum () dolor sit amet, consectetur sit amet adipiscing
Parenthesis after line break : ipsum dolor sit amet, consectetur adipiscing et dolore elit () lorem
"""
pdf.set_font('helvetica', '', 18)
pdf.write(8, "using pdf.multi_cell with built in font")
pdf.ln(0)
pdf.multi_cell(w=0, h=8, txt=text, ln=1)
pdf.ln(8)
pdf.add_font('DejaVu', '', 'DejaVuSans.ttf', uni=True)
pdf.set_font('DejaVu', '', 14)
pdf.write(8, "using pdf.multi_cell with unicode font")
pdf.ln(0)
pdf.multi_cell(w=0, h=8, txt=text, ln=1)
pdf.ln(8)
pdf.write(10, "using pdf.write, line by line with unicode font")
for line in text.split('\n'):
pdf.write(8, line)
pdf.ln(8)
pdf.write(8, "using pdf.write for whole literal with unicode font")
pdf.write(8, text)
pdf.ln(8)
pdf.output("unicode.pdf")
The code outputs this pdf:
unicode.pdf
Any help you could provide would be greatly appreciated. Thanks.
Inpiration could be taken from the existing line(x1, y1, x2, y2)
method.
The table 4.9 of the PDF 1.7 spec should also be helpful
Adding this method will bring us one step further to map SVG primitives like polyline
or path
An additional method polygon
could also be added, that auto-join the start & end points, and fill the enclosed area using the f
PDF operator.
This is up: https://pypi.org/project/fpdf2/2.2.0rc1/
I just want to understand how ready it is for 2.2.0.
If there are no other font bugs introduced as a result of all these new changes, then that is fine.
Also would like to get back to a release cycle that is regular, makes sense, and maybe even with CI on a protected branch to automatically do "rc$((++version))"
...
@Lucas-C ive started working on this locally, and ive pushed my changes to here: https://github.com/alexanderankin/pyfpdf/pull/new/merging_lucas-c
there's still a couple merge conflicts (in the committed version) and I'm not sure that ive done everything right. I think my python unit tests have more line coverage than the old ones (ive added a unit testing framework vs reingart's version), so it can be easily verified if the behavior is correct. Anyways, just wanted to keep you updated
fpdf2
makes use of the Pillow
library with the requirement: Pillow [required: >=4,<=8]
. As of 19th of March, 2021, there seem to be 6 security issues with Pillow < 8.1.1:
I was wondering if you could update to the latest version of Pillow
, so that all projects using your awesome library, would not experience GitHub security issues.
Thanks in advance!
Is it possible to specify that a paragraph or table should not be divided on two pages?
This will be usefull to fill already existed PDF
Currently, "Arial" is defined in the code as an alias for "helvetica":
This could be generalized according to the table of alternatives from appendix H, section 5.5.1 of the PDF 1.7 spec:
Standard name | Alternative |
---|---|
Courier | CourierNew |
Courier − Oblique | CourierNew,Italic |
Courier − Bold | CourierNew,Bold |
Courier − BoldOblique | CourierNew,BoldItalic |
Helvetica | Arial |
Helvetica − Oblique | Arial,Italic |
Helvetica − Bold | Arial,Bold |
Helvetica − BoldOblique | Arial,BoldItalic |
Times − Roman | TimesNewRoman |
Times − Italic | TimesNewRoman,Italic |
Times − Bold | TimesNewRoman,Bold |
Times − BoldItalic | TimesNewRoman,BoldItalic |
Would you consider converting the tests to pytest?
assert expr
is easier to read than self.assertSomething(x, y)
Using their tmp_path
fixture would simplify the temporary files manipulation enormously. Every test function gets its own subdirectory in /tmp/pytest-of-$USER
and three latest test runs are kept there for further investigation. This would save the whole housekeeping after tests.
Reorganizing the tests to /tests
and the testdata to /tests/testdata
would also make the ubiquitous relative_path_to
method redundant.
And, last, but not least, organizing tests to simple methods would remove one indentation level from the test files.
We miss unit tests for this case
These three lines:
are in the code unchanged since ten years. The check and retrieval access different levels of the self.texts
dict.
Quoting https://docs.verapdf.org/validation/pdfa-part1/#rule-64-2:
An XObject dictionary shall not contain the SMask key.
The SMask key in XObject dictionaries specifies a subsidiary image XObject defining a soft-mask image to be used as a source of mask shape or mask opacity values in the PDF transparent imaging model.
This provision, along with Rules 6.4-1 and 6.4-3 to 6.4-6, prohibits the use of transparency within a conforming PDF/A-1 document.
For now this rule is disabled in scripts/verapdf-ignore.json
I have the following code while trying to deliver a PDF file via Django:
from django.http import HttpResponse
from fpdf import FPDF
def certificate_entrepreneur(request):
"""
Provides Entrepreneur Certificate as PDF.
TODO: define permission (is authenticated)
TODO: protect view (only if user has completed incubation program)
"""
pdf = FPDF(orientation='L', unit='mm', format='A4')
pdf.add_page()
pdf.set_draw_color(39, 147, 217)
pdf.line(15, 15, 15, 195) # left bar
pdf.line(15, 15, 280, 15) # upper bar
pdf.line(280, 15, 280, 195) # right bar
pdf.line(15, 195, 280, 195) # bottom bar
pdf.image("bfb_certificates/images/image.png", x=165, y=35, w=100)
response = HttpResponse(pdf.output(), content_type='application/pdf')
response['Content-Disposition'] = 'filename="file.pdf"'
return response
After a request, this view provides a new tab where the browser tries to load the PDF file, but in fact, it presents the download option. When I download the file, I check its MIME type, and it turns out that it is a text/plain
, comparison to other PDF files that I have from different sources:
~/Downloads $ file --mime-type hello.pdf
hello.pdf: application/pdf
~/Downloads $ file --mime-type file.pdf
file.pdf: text/plain
While looking for an answer on Stackoverflow, I found this Thread for Reportlab, which gave me the perception that maybe, I should set the buffer position to the beginning, but the FPDF()
class has no method or variable where I can set the buffer position.
I tried to implement a custom buffer by using io.BytesIO()
from Python standard library, trying to adapt Reportlab example to fpdf2, but after generating a request to Django, I got the following exception:
....
File "/code/bfb_certificates/views.py", line 38, in certificate_entrepreneur
response = HttpResponse(pdf.output(), content_type='application/pdf')
File "/usr/local/lib/python3.9/site-packages/fpdf/fpdf.py", line 1772, in output
self.close()
File "/usr/local/lib/python3.9/site-packages/fpdf/fpdf.py", line 452, in close
self._enddoc() # close document
File "/usr/local/lib/python3.9/site-packages/fpdf/fpdf.py", line 2421, in _enddoc
with self._trace_size("header"):
File "/usr/local/lib/python3.9/contextlib.py", line 117, in __enter__
return next(self.gen)
File "/usr/local/lib/python3.9/site-packages/fpdf/fpdf.py", line 2661, in _trace_size
prev_size = len(self.buffer)
TypeError: object of type '_io.BytesIO' has no len()
If buffer position is the issue here, how could I adapt this, so I generate PDF files on the fly and deliver them via Django?
Disclaimer:
pdf.output(dest='S')
instead of pdf.output()
, and I can normally generate PDF contents on the fly and deliver them via Django. I rather use fpdf2, for a believe that has fewer bugs and should be more stable than fpdf.Example HTML to use:
<table border="1"><thead><tr>
<th width="30%">First name</th><th width="30%">Last name</th><th width="15%">Age</th><th width="25%">City</th>
</tr></thead><tbody><tr>
<td>Jean Abdul William</td><td>Smith</td><td>34</td><td>San Juan</td>
</tr></tbody></table>
The text in the first cell of the first row currently overflows.
A starting point would be to add a dedicated test in test_html.py.
In terms of code, some changes could be made in HTML2FPDF.handle_data
in order to call self.pdf.multi_cell(... ln=3)
instead of FPDF.cell
. Inspiration could be taken from this test: https://github.com/PyFPDF/fpdf2/blob/master/test/cells/test_multi_cell.py#L85 Corresponding output: https://github.com/PyFPDF/fpdf2/blob/master/test/cells/multi_cell_ln_3_table.pdf
This issue can count as part of hacktoberfest
some code still reaches the util string functions with a buffer:
def escape(s):
"Add \ before \, ( and )"
return s.replace('\\', '\\\\') \
.replace(')', '\\)') \
.replace('(', '\\(') \
.replace('\r', '\\r')
this is obviously bad and is why i had to yank the 2.1.0
.
Creating an issue to track all the other issues with font handling. Fonts did not really work with the original code. This issue is supposed to track progress towards figuring it out and implementing changes.
In html I could have <a href="url">link text</a>
. Is there a possibility to have a kindof link(..)
function which writes such a link to pdf? Something like link_external("link text", "url")
The link()
function I found does only link to some other place in the pdf document.
Thank you.
Minimal reproduction code:
pdf=FPDF()
pdf.add_page()
pdf.set_font('Times', 'B', 14)
pdf.cell(50, 0, 'ABC')
pdf.set_font('Times', size=10)
pdf.cell(50, 0, 'DEF')
pdf.set_font('Times', 'B', 14)
assert_pdf_equal(self, pdf, "output.pdf")
Currently an alt_text
parameter can be provided to this method: https://github.com/PyFPDF/fpdf2/blob/2.2.0/fpdf/fpdf.py#L794
However, it is never used in _putpages
: https://github.com/PyFPDF/fpdf2/blob/2.2.0/fpdf/fpdf.py#L1476
Resources on how to implement alternate text descriptions on links:
First, a big thanks for all the work on this library. I'm already using it to produce professional-looking PDF documents efficiently.
Is it possible to produce inline bold and/or italic text when using cell()
or multi_cell()
? I note the discussion in #52, but I don't know how I'd use the HTML renderer to replace or augment what I'm currently doing with cell/multi_cell.
I'm little bit confused between pyfpdf and fpdf2,
What you have enhanced in fpdf2 ?
I want to use it with python 3.7 or 3.8, is this stable with python3.7 ?
Looking for a properly maintained library of python (3.7+), i want to generate some custom PDF that will contain text from dict.
Looking forward for your response.
Inspiration could be taken from pikepdf
: https://github.com/pikepdf/pikepdf/blob/master/src/pikepdf/models/metadata.py#L323
Some bits are alredy set by FPDF._putinfo
: https://github.com/PyFPDF/fpdf2/blob/master/fpdf/fpdf.py#L2060
This should also properly documented in a new docs/Metadata.md
file
Section 12.5 of the PDF 1.7 spec should be helpful in implementing this.
It would be especially useful to add a documentation page indicating how to add such text annotations on an existing PDF.
Specifically, https://github.com/PyFPDF/fpdf2/blob/6511eb02bd38acfd871e299cb781052f4fd0c73f/fpdf/fpdf.py#L573-L580 makes it impossible to add fonts from arbitrary locations without changing the working directory or setting the SYSTEM_TTFONTS
constant.
This was possible in PyFPDF by just passing the path as str (see https://github.com/reingart/pyfpdf/blob/cb3340806c140b6e63eb4ce9d6230be84fba456e/fpdf/fpdf.py#L491-L492 ).
Bonus points for support of Path-Like Objects instead of just str.
pdf = FPDF()
pdf.add_page()
pdf.add_font('arial', style='', fname=r'./fonts/arial.ttf', uni=True)
pdf.set_font('arial', '', 16)
pdf.write_html(u'''<p>中文</p>''')
pdf.output("test.pdf")
It would simply be a user-friendly wrapper around a call to FPDF.ellipse
Adding this method will bring us one step further to map SVG primitives.
I am having weird issues with multicell inserting a page break after every cell if it crosses a page break.
import logging
from fpdf import fpdf
fpdf.LOGGER.setLevel(logging.DEBUG)
fpdf.LOGGER.addHandler(logging.StreamHandler())
data = (
("First name", "Last name", "Age", "City"),
("Jules", "Smith", "34", "San Juan"),
("Mary", "Ramos", "45", "Orlando"),
("Carlson", "Banks", "19", "Los Angeles"),
("Lucas", "Cimon", "31", "Saint-Mahturin-sur-Loire"),
)
pdf = fpdf.FPDF()
pdf.add_page()
pdf.set_font("Times", size=16)
line_height = pdf.font_size * 2
col_width = pdf.epw / 4 # distribute content evenly
for i in range(5):
for row in data:
for datum in row:
pdf.multi_cell(col_width, line_height, datum, border=1, ln=3, max_line_height=pdf.font_size)
pdf.ln(line_height)
pdf.output('table_with_cells.pdf')
This seems related to issue #111, thanks for the cool lib.
multi_cell()
s used to modify the Document self.y
coordinate in pyfpdf (adding their own height to it). In pyfpdf2, self.y
stays the same. Is this intended, or a bug?
Hii,
I am using fpdf2 and trying to write data into pdf in Tabular format. But if the length of the Table cell is less than the length of the text(string), data is overlapping with the content of another cell.Is there any way I use word wrap and have data in the next line instead of overlapping with adjacent cell content?
I have attached my test code and generated pdf files for reference and better explanation.
I know it is asking a lot but if this can be done I think it will make fpdf2 a formidable pdf writer tool.
Thanks in advance
Sree Harsha
This worked in fpdf
.
I have an object that I created called _Report
that subclasses fpdf
:
from pathlib import Path
from fpdf import FPDF
class _Report(FPDF):
def __init__(self, title: str):
super().__init__()
self._title = title
self._user_documents = Path('.').absolute()
ypos = 50
xpos = 10
self.set_x(xpos)
self.set_y(ypos)
self.set_font('Arial', 'B', 12)
self.add_page()
self.alias_nb_pages()
self.saved_as = None
def create_report(self, save_path=None):
if save_path is None:
save_as = self._user_documents
else:
save_as = save_path
save_as = save_as / 'report.pdf'
self.output(save_as, 'F')
self.saved_as = save_as
def header(self):
pos = 30
self.set_y(pos)
self.cell(0, 0, 'Organization Name')
self.set_y(pos + 8)
self.cell(0, 0, self._title)
def footer(self):
self.set_y(-15)
# Page number
self.cell(0, 10, f'Page {self.page_no()} of ' + '{nb}', 0, 0, 'C')
if __name__ == '__main__':
rp = _Report(title='test title')
rp.create_report()
I have tried several items for that last line in the footer
to no avail. I have also tried to move the self.alias_nb_pages()
to a couple of different locations, but it always prints "{nb}" on to the PDF.
I'm having weird page breaks, and it seems it's related to multi_cell + unbreakable use.
Here is a test case, based on the tutorial:
import logging
from fpdf import fpdf
fpdf.LOGGER.setLevel(logging.DEBUG)
fpdf.LOGGER.addHandler(logging.StreamHandler())
data = (
("First name", "Last name", "Age", "City"),
("Jules", "Smith", "34", "San Juan"),
("Mary", "Ramos", "45", "Orlando"),
("Carlson", "Banks", "19", "Los Angeles"),
("Lucas", "Cimon", "31", "Saint-Mahturin-sur-Loire"),
)
pdf = fpdf.FPDF()
pdf.add_page()
pdf.set_font("Times", size=16)
line_height = pdf.font_size * 2
col_width = pdf.epw / 4 # distribute content evenly
for i in range(5): # repeat table 4 times
with pdf.unbreakable() as pdf:
fpdf.LOGGER.debug(f"unbreakable block {i+1}")
for row in data: # data comes from snippets on the Tables documentation page
for datum in row:
pdf.multi_cell(col_width, line_height, f"{datum} ({i})", border=1, ln=3)
pdf.ln(line_height)
pdf.ln(line_height * 2)
pdf.output("unbreakable_tables.pdf")
This outputs this pdf:
The first four table are OK, but there is an unexpected page break after the 4th table.
Here is the logger output:
unbreakable block 1
unbreakable block 2
unbreakable block 3
unbreakable block 4
Page break on page 1 at y=269 for element of height 11
Page break on page 2 at y=269 for element of height 11
Page break on page 3 at y=269 for element of height 11
Page break on page 4 at y=269 for element of height 11
Page break on page 5 at y=280 for element of height 11
Page break on page 6 at y=280 for element of height 11
Page break on page 7 at y=280 for element of height 11
Page break on page 8 at y=280 for element of height 11
Page break on page 9 at y=292 for element of height 11
Page break on page 10 at y=292 for element of height 11
Page break on page 11 at y=292 for element of height 11
Page break on page 12 at y=292 for element of height 11
Performing page jump due to unbreakable height
Page break on page 1 at y=247 for element of height 3260
Page break on page 2 at y=66 for element of height 3260
unbreakable block 5
Final doc sections size summary:
- header.size: 9.0B
- pages.size: 3.3KiB
- resources.fonts.size: 98.0B
- resources.images.size: 0.0B
- resources.dict.size: 104.0B
- info.size: 55.0B
- catalog.size: 104.0B
- xref.size: 250.0B
- trailer.size: 64.0B
I cannot easily understand this log, but I find quite weird that we see 12 pages in a row for a 3 rows file.
Thanks for any input on this! :)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.