Code Monkey home page Code Monkey logo

fpdf2's Introduction

py-pdf.github.io

Website py-pdf

Install requirements

$ pip install -r requirements.txt
$ pre-commit install

Launch local server with livereload

$ invoke livereload

Adding a Python dependency

  1. Edit requirements.in
  2. Run pip-compile requirements.in to generate requirements.txt

Publish

$ make github

fpdf2's People

Contributors

alexanderankin avatar allcontributors[bot] avatar andersonhc avatar bubbu0129 avatar cgkoutzigiannis avatar devdev29 avatar dmail00 avatar emperorarthur avatar eocasio avatar eroux avatar eumiro avatar fbernhart avatar gmischler avatar jmunoz94 avatar kuth-chi avatar leoleozhu avatar lucas-c avatar marcelotduarte avatar mjasperse avatar moe-25 avatar redshy avatar reingart avatar romankharin avatar rysson avatar semaeostomea avatar ssavi-ict avatar tolker-ku avatar tzvigreenfeld avatar xit4 avatar yanone avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fpdf2's Issues

merge versions and release new 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

Support multi-lines text in table cells with write_html

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

Produce linearized PDFs

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

Suggestion: migrate all the docs in docs/reference into docstrings

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?

Chore: release version 2.2.0

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))"...

Q: Bold and/or Italic text within 'cell()' or 'multi_cell()'?

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.

Suggestion: Add support for Inline bold Text

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

Fix VeraPDF rule 6.3.5-3: the font descriptor dictionary shall include a CIDSet stream

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

Review & adapt remaining tutorial/tuto*.* files

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

Support python3.9

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.

Page Break after every cell if multicell crosses a page break.

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')

table_with_cells.pdf

This seems related to issue #111, thanks for the cool lib.

Avoid page break

Is it possible to specify that a paragraph or table should not be divided on two pages?

Bordered cells in a table

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.

write_html can't support unicode

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")

Are vector graphics supported

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.

Add a FPDF.polyline method

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.

Number of pages appears to not function correctly

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.

Add a FPDF.text_annotation method

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.

Validate all fpdf2 examples using PDF checkers

The goal here is:

  • to detect any future change that would break generated PDFs syntax, by introducing checkers in our CD pipeline
  • to ensure that PDFs generated by fpdf2 conform to several checker tools, including PDF/A & PDF/UA standards

Some work towards this has been started in #50

set_auto_page_break is not working

The function set_auto_page_break(auto: bool, margin: int) is not actually preventing text to over write my footer.
This is in loop that is calling multicell function.
Attached image below for more clarification.
image

Generalize the font-alias mechanism

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

Handle alt_text in FPDF.link

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:

Convert tests to pytest

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.

unbreakable and multi_cells

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:

unbreakable_tables.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! :)

Unicode multi_cell line wrap breaks after parenthesis

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.

pdf.output() no delivering application/pdf (Django)

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:

  • I used the same code above with pyfpdf (which I believe it is not maintained anymore), with the simple modification of using 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.

`add_font` should support an explicit path instead only a filename

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.

Question: Possibilty of WordWrap while represent data in Tabular format.

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

wordwrap.zip

How to add Border on page ?

I want to add border in each page (individual or all at once).
Image is attached for better understanding.
image

Suggestion: logo

I thought it could be nice to find a logo for fpdf2.

I made this one with Gimp, tell me what yout think about it:
pyfpdf-logo

Create a URL link

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.

Fix VeraPDF rule 6.4-2: remove support for SMask keys in order to achieve PDF/A-1 comformity

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

Unicode font usage still calls into the util string functions

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.

Is this project Maintained ?

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.

Fonts

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.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.