[python] How to create PDF files in Python

I'm working on a project which takes some images from user and then creates a PDF file which contains all of these images.

Is there any way or any tool to do this in Python? E.g. to create a PDF file (or eps, ps) from image1 + image 2 + image 3 -> PDF file?

This question is related to python pdf

The answer is


fpdf is python (too). And often used. See PyPI / pip search. But maybe it was renamed from pyfpdf to fpdf. From features: PNG, GIF and JPG support (including transparency and alpha channel)


It depends on what format your image files are in, but for a project here at work I used the tiff2pdf tool in LibTIFF from RemoteSensing.org. Basically just used subprocess to call tiff2pdf.exe with the appropriate argument to read the kind of tiff I had and output the kind of pdf I wanted. If they aren't tiffs you could probably convert them to tiffs using PIL, or maybe find a tool more specific to your image type (or more generic if the images will be diverse) like ReportLab mentioned above.


I believe that matplotlib has the ability to serialize graphics, text and other objects to a pdf document.


Here is my experience after following the hints on this page.

  1. pyPDF can't embed images into files. It can only split and merge. (Source: Ctrl+F through its documentation page) Which is great, but not if you have images that are not already embedded in a PDF.

  2. pyPDF2 doesn't seem to have any extra documentation on top of pyPDF.

  3. ReportLab is very extensive. (Userguide) However, with a bit of Ctrl+F and grepping through its source, I got this:

    • First, download the Windows installer and source
    • Then try this on Python command line:

      from reportlab.pdfgen import canvas
      from reportlab.lib.units import inch, cm
      c = canvas.Canvas('ex.pdf')
      c.drawImage('ar.jpg', 0, 0, 10*cm, 10*cm)
      c.showPage()
      c.save()
      

All I needed is to get a bunch of images into a PDF, so that I can check how they look and print them. The above is sufficient to achieve that goal.

ReportLab is great, but would benefit from including helloworlds like the above prominently in its documentation.


You can try this(Python-for-PDF-Generation) or you can try PyQt, which has support for printing to pdf.

Python for PDF Generation

The Portable Document Format (PDF) lets you create documents that look exactly the same on every platform. Sometimes a PDF document needs to be generated dynamically, however, and that can be quite a challenge. Fortunately, there are libraries that can help. This article examines one of those for Python.

Read more at http://www.devshed.com/c/a/Python/Python-for-PDF-Generation/#whoCFCPh3TAks368.99


If you are familiar with LaTex you might want to consider pylatex

One of the advantages of pylatex is that it is easy to control the image quality. The images in your pdf will be of the same quality as the original images. When using reportlab, I experienced that the images were automatically compressed, and the image quality reduced.

The disadvantage of pylatex is that, since it is based on LaTex, it can be hard to place images exactly where you want on the page. However, I have found that using the position argument in the Figure class, and sometimes Subfigure, gives good enough results.

Example code for creating a pdf with a single image:

from pylatex import Document, Figure

doc = Document(documentclass="article")
with doc.create(Figure(position='p')) as fig:
fig.add_image('Lenna.png')

doc.generate_pdf('test', compiler='latexmk', compiler_args=["-pdf", "-pdflatex=pdflatex"], clean_tex=True)

In addition to installing pylatex (pip install pylatex), you need to install LaTex. For Ubuntu and other Debian systems you can run sudo apt-get install texlive-full. If you are using Windows I would recommend MixTex


I have done this quite a bit in PyQt and it works very well. Qt has extensive support for images, fonts, styles, etc and all of those can be written out to pdf documents.


rinohtype supports embedding PDF, PNG and JPEG images (natively) and other bitmap formats (when Pillow is installed).

(Full disclosure: I am the author of rinohtype)


I suggest Pdfkit. (installation guide)

It creates pdf from html files. I chose it to create pdf in 2 steps from my Python Pyramid stack:

  1. Rendering server-side with mako templates with the style and markup you want for you pdf document
  2. Executing pdfkit.from_string(...) method by passing the rendered html as parameter

This way you get a pdf document with styling and images supported.

You can install it as follows :

  • using pip

    pip install pdfkit

  • You will also need to install wkhtmltopdf (on Ubuntu).

Here is a solution that works with only the standard packages. matplotlib has a PDF backend to save figures to PDF. You can create a figures with subplots, where each subplot is one of your images. You have full freedom to mess with the figure: Adding titles, play with position, etc. Once your figure is done, save to PDF. Each call to savefig will create another page of PDF.

Example below plots 2 images side-by-side, on page 1 and page 2.

from matplotlib.backends.backend_pdf import PdfPages
import matplotlib.pyplot as plt
from scipy.misc import imread
import os
import numpy as np

files = [ "Column0_Line16.jpg", "Column0_Line47.jpg" ]
def plotImage(f):
    folder = "C:/temp/"
    im = imread(os.path.join(folder, f)).astype(np.float32) / 255
    plt.imshow(im)
    a = plt.gca()
    a.get_xaxis().set_visible(False) # We don't need axis ticks
    a.get_yaxis().set_visible(False)

pp = PdfPages("c:/temp/page1.pdf")
plt.subplot(121)
plotImage(files[0])
plt.subplot(122)
plotImage(files[1])
pp.savefig(plt.gcf()) # This generates page 1
pp.savefig(plt.gcf()) # This generates page 2
pp.close()

fpdf works well for me. Much simpler than ReportLab and really free. Works with UTF-8.


I use rst2pdf to create a pdf file, since I am more familiar with RST than with HTML. It supports embedding almost any kind of raster or vector images.

It requires reportlab, but I found reportlab is not so straight forward to use (at least for me).


You can actually try xhtml2pdf http://flask.pocoo.org/snippets/68/