Make a formal letter in pdf with Python (v.2)

This code enables you to create a pdf with just text using python and the module reportlab. You need to install reportlab with pip

pip install reportlab

I tried to make the code more readable and now you can:

  • write text and go to new line just going to a new line in the multiline string
  • add an image (only .png, but it’s easy to add other formats) just putting the name of the image in the text
  • add the time adding time.ctime() in the text

Now that we have this basic foundation, we can add many other features to it. I have also created a function add_doc() to wich you pass the name of the pdf you create, to make it easier to change it, putting all the code you need to change at the bottom of the script.

If you use windows, maybe you can change the last line of code into.

os.startfile(name)

In a next version we will make use of tkinter to create a little nice GUI to make this work even easier.

import time
from reportlab.lib.enums import TA_JUSTIFY
from reportlab.lib.pagesizes import letter
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Image
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import inch
import os



def make_doc(name):
    doc = SimpleDocTemplate(
        name,
        pagesize=letter,
        rightMargin=72,leftMargin=72,
        topMargin=72,bottomMargin=18)
    return name, doc


def add_image(img):
    "Add an image to page"
    im = Image(img, 2*inch, 2*inch)
    page.append(im)


def add_space():
    "Add a space to page"
    page.append(Spacer(1, 12))


def add_text(text, space=0):
    "Add a text to page followed by a space"
    if type(text)==list:
        for f in text:
            add_text(f)
    else:
        ptext = f'<font size="12">{text}</font>'
        page.append(Paragraph(ptext, styles["Normal"]))
        if space==1:
            add_space()
        add_space()


def show(text):
    "Adds images and text for each line in 'text' multiline string"
    # using add_image and add_text and recognizing .png and ctime
    text = text.splitlines()
    for line in text:
        if ".png" in line:
            add_image(line)
        elif "ctime()" in line:
            add_text(time.ctime())
        else:
            add_text(line)
    doc.build(page)

# ==========style

styles=getSampleStyleSheet()
styles.add(ParagraphStyle(name='Justify', alignment=TA_JUSTIFY))
page=[]

# ======= Write text and images here =======================

text = """
python_logo.png
time.ctime()

Giovanni Gatto
Via Leonardo Da Vinci
tel. 335556566

Hello,
This is a formal letter
    Thank you very much and we look forward to serving you.
"""
# ===========================================================

# put the name of the pdf file here

name, doc = make_doc("myform.pdf")
show(text)

os.system("echo " + name)

Version to change width, height and align of images

In this version, you can add the width, height and align of the image in the text with this syntax

image.png 200 100 LEFT

There is just this two lines of code to control the string with the image name

def add_image(img, w=200, h=100, align="LEFT"):
    "Add an image to page"
    im = Image(img, w, h, hAlign=align)
    # im = Image(img, 2*inch, 2*inch)
    page.append(im)
        if ".png" in line:
            if len(line.split()) == 4:
                l, w, h, align = line.split()
                add_image(l, int(w), int(h), align)

In the function add_image now there are the two arguments w and h for width and height

This is the code

import time
from reportlab.lib.enums import TA_JUSTIFY
from reportlab.lib.pagesizes import letter
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Image
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import inch
import os



def make_doc(name):
    doc = SimpleDocTemplate(
        name,
        pagesize=letter,
        rightMargin=72,leftMargin=72,
        topMargin=72,bottomMargin=18)
    return name, doc


def add_image(img, w=200, h=100, align="LEFT"):
    "Add an image to page"
    im = Image(img, w, h, hAlign=align)
    # im = Image(img, 2*inch, 2*inch)
    page.append(im)


def add_space():
    "Add a space to page"
    page.append(Spacer(1, 12))


def add_text(text, space=0):
    "Add a text to page followed by a space"
    if type(text)==list:
        for f in text:
            add_text(f)
    else:
        ptext = f'<font size="12">{text}</font>'
        page.append(Paragraph(ptext, styles["Normal"]))
        if space==1:
            add_space()
        add_space()


def show(text):
    "Adds images and text for each line in 'text' multiline string"
    # using add_image and add_text and recognizing .png and ctime
    text = text.splitlines()
    for line in text:
        if ".png" in line:
            if len(line.split()) == 4:
                l, w, h, align = line.split()
                add_image(l, int(w), int(h), align)
            else:
                add_image(line)

        elif "ctime()" in line:
            add_text(time.ctime())
        else:
            add_text(line)
    doc.build(page)

# ==========style

styles=getSampleStyleSheet()
styles.add(ParagraphStyle(name='Justify', alignment=TA_JUSTIFY))
page=[]

# ======= Write text and images here =======================

text = """
logo.png 200 100 LEFT
time.ctime()

Giovanni Gatto
Via Leonardo Da Vinci
tel. 335556566

Hello,
This is a formal letter
    Thank you very much and we look forward to serving you.
"""
# ===========================================================

# put the name of the pdf file here

name, doc = make_doc("myform.pdf")
show(text)

os.startfile(name)

Add a GUI to this script

In this post I added a Graphic User Interface to this script

Free PDF maker app with Python


Subscribe to the newsletter for updates
Tkinter templates
Avatar My youtube channel

Twitter: @pythonprogrammi - python_pygame

Videos

Speech recognition game

Pygame's Platform Game

Other Pygame's posts

Published by pythonprogramming

Started with basic on the spectrum, loved javascript in the 90ies and python in the 2000, now I am back with python, still making some javascript stuff when needed.