Free PDF maker app with Python

This time we will create a graphic user interface to make a pdf with Python. Go here to see the code to make it without the GUI.

Now, we will divide the code in 2. One to create the pdf and another to create the GUI. Launching the first, you can still make the pdf, but you need to change the text in the code itself, in the text variable. Launching the GUI, you can change the text into a Text widget called content. Having a file for the logic and a file for the GUI, makes it easy to change both of them, separately.

The script (working also alone) to make the pdf

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):
    
    global doc
    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"

    global doc
    # 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

if __name__ == "__main__":
    name, doc = make_doc("myform.pdf")
    show(text)

    os.startfile(name)

If you do not want to use a GUI, you can use the one above. Works perfectly alone. If you prefer a GUI, go to the next chapter and use both the script in the same folder, calling the one above pdfcreate2.py

The GUI to make the pdf importing pdfcreate2

This is the very simple GUI. You have a template at the beginning, but you can change it as you want.

# GUI for pdfcreate
import os
import pdfcreate2 as pc
import tkinter as tk

root = tk.Tk()

label = tk.Label(root, text="File name: ")
label.pack()

v = tk.StringVar()
entry = tk.Entry(root, textvariable=v)
entry.pack()

content = tk.Text(root)
content.pack()
content.insert("0.0", pc.text)

def create_pdf():
    if v.get() == "":
        v.set("example")
    if ".pdf" not in v.get():
        name, doc = pc.make_doc(v.get() + ".pdf")
    else:
        name, doc = pc.make_doc(v.get())
    pc.show(content.get("0.0", tk.END))
    os.startfile(name)

button = tk.Button(
    root,
    text="Create PDF",
    command = create_pdf)
button.pack()



root.mainloop()

Using templates in txt files

I thought that it could be useful to have files saved as txt that can be used as templates for different occasions, so that you got a good part of the work done and you have just to adjust something. So, I added a button to get the templates from the txt file in the folder. All you got to do is to previously create one or more txt files with the templates you need. Next time I’ll make a way to save the templates from the GUI itself.

# GUI for pdfcreate
import os
import pdfcreate2 as pc
import tkinter as tk
from tkinter import filedialog


root = tk.Tk()

label = tk.Label(root, text="File name: ")
label.pack()

v = tk.StringVar()
entry = tk.Entry(root, textvariable=v)
entry.pack()

content = tk.Text(root)
content.pack()
content.insert("0.0", pc.text)

def create_pdf():
    if v.get() == "":
        v.set("example")
    if ".pdf" not in v.get():
        name, doc = pc.make_doc(v.get() + ".pdf")
    else:
        name, doc = pc.make_doc(v.get())
    pc.show(content.get("0.0", tk.END))
    os.startfile(name)


def get_template():
    try:
        filename = filedialog.askopenfilename(
            initialdir=".")
        with open(filename) as file:
            file = file.read()
        content.delete("0.0", tk.END)
        content.insert("0.0", file)
    except:
        pass

b1 = tk.Button(
    root,
    text="Get a template",
    command=get_template)
b1.pack()

button = tk.Button(
    root,
    text="Create PDF",
    command = create_pdf)
button.pack()



root.mainloop()

See ya.

Make a pdf with flask

Make a pdf from html with Python and Flask


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.