Some projects may need to use a PDF library to output content as a PDF file, or change permissios of original document. I really hate PDF technology and there's no good Python library (Reportlab is the lesser evil, i guess). But nevertheless, it is preferable format as portability and it has some alternatives like searchable, accessible, etc.

In Django project site, i found a document about outputting PDF files with Reportlab. You can see very simple example code for creating a PDF file. It's short and insufficient example, so i'll try to expand the code, you can find example codes from here: https://bitbucket.org/gokmen/django_pdf_example

The view function that's in shared from djangoproject.com, returns a single page PDF file named somefilename.pdf. We wrote a string "Hello world." and set string position as 100 from bottom left. Now, let's try to use this output as a watermark for stamping to an example pdf file. I'm using pdftk command line tool for adding watermark. It's licensed with GPLv2 and you can install from package manager easily. Please check package list from this url.

After the pdftk installation, we need to a function to process PDF document:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# utils.py
import random
import string
import tempfile
from subprocess import call


class UsageError(Exception):

    def __str__(self):
        return repr("You should define at least one: watermark, password")


def pdftk(document, watermark=None, password=None):
    """ Run pdftk for watermark and printable processes.

    Arguments:
        document: file path of original document. it should be string.
        watermark: file path of watermark pdf file. it should be string.
        password: required to disable printable. it should be random string.
    """
    if not watermark and password:
        raise UsageError()

    command = ['pdftk', document]

    # if watermark is defined, add watermark to the output
    if watermark:
        command.extend(['stamp', watermark])

    # create temporary file path and add as output argument.
    file_path = tempfile.mktemp()
    command.extend(['output', file_path])

    if password:
        # password can be boolean. at this status, we create a random password.
        if type(password) == bool:
            cluster = string.ascii_uppercase + string.digits
            password = ''.join(random.choice(cluster) for x in range(8))

        command.extend(['owner_pw', password])

    # then, run pdftk with arguments
    call(command)

    # and last, return file path
    return file_path

The pdftk function needs to an original document path, a single page pdf file path for watermark or a password for encrypting. For example, let's create a single page with reportlab to stamp to original file, add to original file and encrypt it:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# views.py
import os
import tempfile
from django.http import HttpResponse
from django.views.generic import View
from reportlab.pdfgen import canvas
from core.utils import pdftk


class Index(View):

    def get(self, *args, **kwargs):
        # Create the HttpResponse object with the appropriate PDF headers.
        response = HttpResponse(mimetype='application/pdf')
        response['Content-Disposition'] = 'filename=somefilename.pdf'

        # First, create watermark..
        # Create the PDF object, using the response object as its "file."
        watermark_path = tempfile.mktemp()
        watermark = canvas.Canvas(watermark_path)

        # Draw things on the PDF. Here's where the PDF generation happens.
        # See the ReportLab documentation for the full list of functionality.
        watermark.drawString(100, 100, "Hello world.")

        # Close the PDF object cleanly, and we're done.
        watermark.showPage()
        watermark.save()

        # Now stamp watermark and encrypt original file.
        doc_path = os.path.join(os.path.dirname(__file__), 'example.pdf')
        output_path = pdftk(doc_path, watermark_path, password=True)

        # And last, write output to response.
        response.write(file(output_path, 'r').read())

        return response

When you run runserver command from console, and open localhost:8000 from the browser, it responses a processed pdf file. You will see a watermark text in bottom left side of pdf pages, and the response won't allow to print output. Get the repository from bitbucket, you can try too.