Create Word Document in Python Tkinter

In this Python Tkinter tutorial, I will walk you through how to create a Word document using a simple GUI application. We will use the tkinter module to build the interface and the python-docx library to generate Word documents with dynamic content.

I will explain the key modules used, show you the complete source code, and demonstrate how the output document is generated.

Let’s get in.

Create a Word Document in Python Tkinter

So we created a complete application using Python Tkinter that will take inputs like below:

User InputsTkinter Widget
Employee IDEntry widget
Employee NameEntry Widget
DesignationEntry Widget
Joining DateEntry Widget
End DateEntry Widget
GenderOptionMenu Widget

Then, when the user fills the form and clicks on the Generate Word button, it will create an experience certificate (Word document) with the dynamic values provided by the user.

The form looks like below:

Create Word Document in Python Tkinter

The output will come like below:

python tkinter generated service certificate

Check out Display Data in Textboxes using Python Tkinter

Tkinter Module in Python

Using the Tkinter module in Python, we can create a graphical user interface (GUI) for any application. It is a popular and easy-to-use Python module that can help you convert your command-line-based application into an interactive GUI-based program.

User InputsTkinter Widget
Employee IDEntry widget
Employee NameEntry Widget
DesignationEntry Widget
Joining DateEntry Widget
End DateEntry Widget
GenderOptionMenu Widget

Gender is a tkinter OptionMenu widget; the user can select the gender using the dropdown. This information is used for declaring a subject pronoun. Using gender information, we have specified he, she, him, his, her in the body text of the message.

Read Set a Background Image in Python Tkinter

Python-docx module in Python

Python-docx can be installed using pip and conda package manager with the following command.

# using pip 
pip install python-docx

# using anaconda
conda install -c conda-forge python-docx

Below is the picture of a Word document with marked features.

python tkinter word document

Each feature has a dedicated method in Python-docx. Few widely used methods of python-docx are add_paragraph(), add_picture(), add_heading(), add_page_break(), add_table(), etc.

from docx import Document
doc = Document()

Moving forward, we will discuss common methods of the Python-docx module, using which you can create a sample Word document in Python.

Check out Create Window Titles in Python Tkinter

docx.styles()

If you want to save time from manually formatting each row of a Word document, then you can apply a bundle of pre-formatted styles using this feature in the python-docx module.

python docx styles

Other than this, you can modify the style by adding bullet points, changing font weight to bold, italics, underline, etc.

Example:

This example demonstrates how to create a style in the Python docx module also shows how to use the style on a paragraph in the Python docx module.

# style created
new_style = doc.styles['Heading 1']

# style applied
doc.add_paragraph(style=new_style)

docx.add_heading()

Heading specifies the short description of the topic or content. A good heading is always short and self-explanatory. In this section, we will learn how to add a heading using Python.

  • Every sub-heading is smaller than the parent heading, and this way they form a hierarchy of 1-9 levels, where 1 is the highest level and 9 is the lowest.
doc.add_heading('United States of America', level=1)

Change the level value to modify the heading size in Python docx.

Check out Create an OptionMenu in the Python Tkinter

docx.add_paragraph()

The paragraph is a widely used method, as this will require you to add text to the Word document using python Python-docx module.

Example:

In this code, we have added a paragraph: ‘Best Country’, and using the run object, added the country name: the United States of America, and then applied bold formatting on the country name.

# one-liner
doc.add_paragraph('Best Country').add_run('United States of America').bold = True

# same thing in 2 lines to make it look good
nomination = doc.add_paragraph('Best Country')
nomination.add_run('United States of America').bold =True
python tkinter docx add paragraph with add run

docx.add_picture()

Using the add_picture() method in Python-docx, you can add an image to the Word document. The picture below shows the column available for uploading images in a Word document.

create a word document using a python tkinter

Python docx add_picture() method provides an option to add a picture to the Word file. You can control the size of the image by defining its height and width of the image.

Syntax:

Height and width are optional to provide, but they will be either in Inches or cm (centimeters). We recommend keeping the image in the same folder where the main project is, but in case it is not possible, then provide the complete path in place of <image_path>.

from docx.shared import Inches
doc = Document()
doc.add_picture(<image_path>, width=Inches(val), height=Inches(val))

Example:

The below example demonstrates the use of docx.add_image() in the Python docx module. In this example, we have added an image file to the Word document.

# import modules
from docx import Document
from docx.shared import Inches

# create an instance 
doc = Document()

# add image
doc.add_picture('logo.png', height=Inches(0.81), width=Inches(2.52))

# save file
doc.save('word.docx')
python tkinter add image using python docx module

Check out Create Layouts with Python Tkinter Frame

Source code of the tkinter application

In this section, we have provided source code for creating an application for generating experience certificates for employees who are leaving the organization.

PermissionError: [Errno 13] Permission denied: 'word.docx'

The Word file must be closed before clicking on the ‘Generate Word’ button again. If you are seeing the above permission error, that means the file is open. Close the file and try again to fix this error.

Read Create a Progress Bar in Python Tkinter

Python Tkinter Code (GUI Development)

Here is the source code for creating a Graphical User Interface (GUI) for the Experience Letter generating application in Python.

# modules
from tkinter import *

# clear function
def clear_inputs():
    eid.delete(0, 'end')
    ename.delete(0, 'end')
    desig.delete(0, 'end')
    jd.delete(0, 'end')
    ed.delete(0, 'end')

ws = Tk()
ws.title('Service Certificate Generator')
ws.geometry('400x300')
ws.config(bg='#456')

f = ('sans-serif', 13)
btn_font = ('sans-serif', 10)
bgcolor = '#BF5517'

genvar = StringVar()
genopt = ['Male', 'Female']
genvar.set('Male')

# frames
frame = Frame(ws, padx=20, pady=20, bg=bgcolor)
frame.pack(expand=True, fill=BOTH)

# label widgets
Label(
    frame, 
    text="Employee ID",
    font=f,
    bg=bgcolor
).grid(row=0, column=0, sticky='w')

Label(
    frame,
    text="Employee Name",
    font=f,
    bg=bgcolor
).grid(row=1, column=0, sticky='w')

Label(
    frame,
    text="Designation",
    font=f,
    bg=bgcolor
).grid(row=2, column=0, sticky='w')

Label(
    frame,
    text="Joining Date",
    font=f,
    bg=bgcolor
).grid(row=3, column=0, sticky='w')

Label(
    frame,
    text="End Date",
    font=f,
    bg=bgcolor
).grid(row=4, column=0, sticky='w')

Label(
    frame,
    text='Gender',
    font=f,
    bg=bgcolor
).grid(row=5, column=0, sticky='w')

# entry widgets
eid = Entry(frame, width=20, font=f)
eid.grid(row=0, column=1)

ename = Entry(frame, width=20, font=f)
ename.grid(row=1, column=1)

desig = Entry(frame, width=20, font=f)
desig.grid(row=2, column=1)

jd = Entry(frame, width=20, font=f)
jd.grid(row=3, column=1)

ed = Entry(frame, width=20, font=f)
ed.grid(row=4, column=1)

gender = OptionMenu(
    frame, 
    genvar,
    *genopt
)
gender.grid(row=5, column=1, pady=(5,0))
gender.config(width=15, font=f)
btn_frame = Frame(frame, bg=bgcolor)
btn_frame.grid(columnspan=2, pady=(50, 0))

# default inputs for testing
eid.insert(0,'E1008')
ename.insert(0, 'Vineet Singh')
desig.insert(0, 'Python Developer')
jd.insert(0, 'Aug 3rd, 2020')
ed.insert(0, 'July 31st, 2021')

# action buttons
submit_btn = Button(
    btn_frame,
    text='Generate Word',
    command=None, #generate,
    font=btn_font,
    padx=10, 
    pady=5
)
submit_btn.pack(side=LEFT, expand=True, padx=(15, 0))

clear_btn = Button(
    btn_frame,
    text='Clear',
    command=clear_inputs,
    font=btn_font,
    padx=10, 
    pady=5,
    width=7
)
clear_btn.pack(side=LEFT, expand=True, padx=15)

exit_btn = Button(
    btn_frame,
    text='Exit',
    command=lambda:ws.destroy(),
    font=btn_font,
    padx=10, 
    pady=5
)
exit_btn.pack(side=LEFT, expand=True)

# mainloop
ws.mainloop()

Check out Master the Python Tkinter Canvas

Source Code for Creating a Word File using Python

Here is the fully functional Python source code for creating a Word file using Python.

# modules
from docx import Document
from docx.opc.coreprops import CoreProperties
from docx.enum.style import WD_STYLE_TYPE
from docx.enum.text import WD_ALIGN_PARAGRAPH
from docx.shared import Inches, Pt

# user inputs 
logo = 'files/tsinfo_logo.jpg'
output = 'Experience_letter1.docx'
sign = 'files/signature.png'
ceo_sig_text = '''Adarshnath Singh \nDirector'''
heading = 'Service Certificate'
emp_id = 'E1001' #eid.get() 
emp_name = 'Vineet Singh' # ename.get() 
designation = 'Software Engineer' #desig.get()
joining_date = 'August 20, 2019' #jd.get()
end_date = 'July 31, 2021' #ed.get()

comp_detail = '''TSInfo Technologies (OPC) Pvt Ltd
Flat G-115, SJR Residency, Devarabeesanahalli, Bellandur, Bangalore, 560103
Email: info@tsinfotechnologies.com, Phone: +91-9916854253
'''
gen = 'He' # who.get()

# subject pronoun 
gen2 = 'his' # her
gen3 = 'him' # her

if gen.lower() == 'he':
    gen2 = 'his'
    gen3 = 'him' 
elif gen.lower() == 'she':
    gen2 = 'her' 
    gen3 = 'her'
else:
    print('Error: accept He/She only')

# certificate template
body_text = f'''This is to certify that {emp_name} has worked with TSInfo Technologies (OPC) Pvt Ltd from {joining_date} to {end_date}, and was designated as {designation} at the time of {gen2} leaving the organization.

{gen.capitalize()} is hardworking and a good team player.

We wish {gen3} all the success in his future endeavor.
    '''
# create instance
doc =  Document()

# declare margin
sections = doc.sections
for section in sections:
    section.top_margin = Inches(0.04)
    section.bottom_margin = Inches(0.19)
    section.left_margin = Inches(0.93)
    section.right_margin = Inches(0.89)

section = doc.sections[0]

# logo image placement
logo = doc.add_picture(logo, width=Inches(2.52), height=Inches(0.81))
logo_placement = doc.paragraphs[-1] 
logo_placement.alignment = WD_ALIGN_PARAGRAPH.CENTER

# line space
for _ in range(1):
    linespace_style = doc.styles['Body Text']
    linespace = doc.add_paragraph(style=linespace_style).add_run(' ')
    linespace_style.font.size = Pt(10)

# employee Id
empid_style = doc.styles['Normal']
empid = doc.add_paragraph(style=empid_style).add_run(f'{emp_id}')
empid.font.bold = True

# line space
for _ in range(1):
    linespace_style = doc.styles['Body Text']
    linespace = doc.add_paragraph(style=linespace_style).add_run()
    linespace.font.size = 10

# Header 
heading_style = doc.styles['Body Text']
head=doc.add_paragraph(style=heading_style).add_run(f'{heading}')
doc.paragraphs[-1].alignment = WD_ALIGN_PARAGRAPH.CENTER
head.font.size = Pt(20)
head.font.bold = True 

# body text 
body_style = doc.styles['Body Text']
body = doc.add_paragraph(style=body_style).add_run(f'{body_text}')
body.font.size = Pt(14)
body.font.name = 'Times New Roman'

#line space
for _ in range(2):
    linespace_style = doc.styles['Body Text']
    linespace = doc.add_paragraph(style=linespace_style).add_run()
    linespace.font.size = 10

# signature image & text
ceo_sign = doc.styles['Body Text']
doc.add_picture(sign, width=Inches(1.57), height=Inches(0.43))
doc.add_paragraph(style=ceo_sign).add_run(f'{ceo_sig_text}')
ceo_sign.font.size = Pt(14)
    
# line space
for _ in range(4):
    linespace_style = doc.styles['Body Text']
    linespace = doc.add_paragraph(style=linespace_style)

# footer text : company description
company_text = doc.styles['Normal']
company_text.paragraph_format.space_before = Pt(12)
doc.add_paragraph(style=company_text).add_run(f'{comp_detail}')
center_align = doc.paragraphs[-1] 
center_align.alignment = WD_ALIGN_PARAGRAPH.CENTER

# saving file to word document
doc.save(output)

Read Set and Manage Window Size in Python Tkinter

Complete Source code for creating a Word document using Python tkinter

Here is the source code of the complete application that will generate the experience letter of an employee. It accepts the information through a graphical user interface created using the tkinter module in Python.

# modules
from docx import Document
from docx.opc.coreprops import CoreProperties
from docx.enum.style import WD_STYLE_TYPE
from docx.enum.text import WD_ALIGN_PARAGRAPH
from docx.shared import Inches, Pt
from tkinter import *
from tkinter import messagebox

ws = Tk()
ws.title('Service Certificate Generator')
ws.geometry('400x300')
ws.config(bg='#456')

f = ('sans-serif', 13)
btn_font = ('sans-serif', 10)
bgcolor = '#BF5517'

genvar = StringVar()
genopt = ['Male', 'Female']
genvar.set('Male')

def clear_inputs():
    eid.delete(0, 'end')
    ename.delete(0, 'end')
    desig.delete(0, 'end')
    jd.delete(0, 'end')
    ed.delete(0, 'end')

def generate():
     # data variables
    logo = 'files/tsinfo_logo.jpg'
    output = 'output/Experience_letter.docx'
    sign = 'files/signature.png'
    ceo_sig_text = '''Adarshnath Singh \nDirector'''
    heading = 'Service Certificate'
    emp_id = eid.get() 
    emp_name = ename.get() 
    designation = desig.get()
    joining_date = jd.get()
    end_date = ed.get()

    comp_detail = '''
    TSInfo Technologies (OPC) Pvt Ltd
    Flat G-115, SJR Residency, Devarabeesanahalli, Bellandur, Bangalore, 560103
    Email: info@tsinfotechnologies.com, Phone: +91-9916854253
    '''
    # gender specification 

    gen1 = 'He' # she
    gen2 = 'his' # her
    gen3 = 'him' # her

    if genvar.get() == 'Male':
        gen1 = 'He'
        gen2 = 'his'
        gen3 = 'him' 
    elif genvar.get() == 'Female':
        gen1 = 'She'
        gen2 = 'her' 
        gen3 = 'her'
    else:
        messagebox.showerror('Error', 'Incorrect gender Selection!')

    # experience certificate template
    body_text = f'''
This is to certify that {emp_name} has worked with TSInfo Technologies (OPC) Pvt Ltd from {joining_date} to {end_date}, and was designated as {designation} at the time of {gen2} leaving the organization.

{gen1} is hardworking and a good team player.
We wish {gen3} all the success in {gen2} future endeavor.
    '''
    # create object(s)
    doc =  Document()
    sections = doc.sections

   # declare margin
    for section in sections:
        section.top_margin = Inches(0.04)
        section.bottom_margin = Inches(0.19)
        section.left_margin = Inches(0.93)
        section.right_margin = Inches(0.89)

    section = doc.sections[0]

    # logo image placement
    logo = doc.add_picture(logo, width=Inches(2.52), height=Inches(0.81))
    logo_placement = doc.paragraphs[-1] 
    logo_placement.alignment = WD_ALIGN_PARAGRAPH.CENTER

    # line space
    for _ in range(1):
        linespace_style = doc.styles['Body Text']
        linespace = doc.add_paragraph(style=linespace_style).add_run(' ')
        linespace_style.font.size = Pt(10)

    # employee Id
    empid_style = doc.styles['Normal']
    empid = doc.add_paragraph(style=empid_style).add_run(f'{emp_id}')
    empid.font.bold = True

    # line space
    for _ in range(1):
        linespace_style = doc.styles['Body Text']
        linespace = doc.add_paragraph(style=linespace_style).add_run()
        linespace.font.size = 10

    # Header 
    heading_style = doc.styles['Body Text']
    head = doc.add_paragraph(style=heading_style).add_run(f'{heading}')
    doc.paragraphs[-1].alignment = WD_ALIGN_PARAGRAPH.CENTER
    head.font.size = Pt(20)
    head.font.bold = True 

    # body text 
    body_style = doc.styles['Body Text']
    body = doc.add_paragraph(style=body_style).add_run(f'{body_text}')
    body.font.size = Pt(14)
    body.font.name = 'Times New Roman'

    #line space
    for _ in range(2):
        linespace_style = doc.styles['Body Text']
        linespace = doc.add_paragraph(style=linespace_style).add_run()
        linespace.font.size = 10

    # signature image & text
    ceo_sign = doc.styles['Body Text']
    doc.add_picture(sign, width=Inches(1.57), height=Inches(0.43))
    doc.add_paragraph(style=ceo_sign).add_run(f'{ceo_sig_text}')
    ceo_sign.font.size = Pt(14)

    # line space
    for _ in range(4):
        linespace_style = doc.styles['Body Text']
        linespace = doc.add_paragraph(style=linespace_style)
        # linespace.font.size = Pt(10)

    # footer text : company description
    company_text = doc.styles['Normal']
    company_text.paragraph_format.space_before = Pt(12)
    doc.add_paragraph(style=company_text).add_run(f'{comp_detail}')
    center_align = doc.paragraphs[-1] 
    center_align.alignment = WD_ALIGN_PARAGRAPH.CENTER

    doc.save(output)

# frames
frame = Frame(ws, padx=20, pady=20, bg=bgcolor)
frame.pack(expand=True, fill=BOTH)

# label widgets
Label(
    frame, 
    text="Employee ID",
    font=f,
    bg=bgcolor
).grid(row=0, column=0, sticky='w')

Label(
    frame,
    text="Employee Name",
    font=f,
    bg=bgcolor
).grid(row=1, column=0, sticky='w')

Label(
    frame,
    text="Designation",
    font=f,
    bg=bgcolor
).grid(row=2, column=0, sticky='w')

Label(
    frame,
    text="Joining Date",
    font=f,
    bg=bgcolor
).grid(row=3, column=0, sticky='w')

Label(
    frame,
    text="End Date",
    font=f,
    bg=bgcolor
).grid(row=4, column=0, sticky='w')

Label(
    frame,
    text='Gender',
    font=f,
    bg=bgcolor
).grid(row=5, column=0, sticky='w')

# entry widgets
eid = Entry(frame, width=20, font=f)
eid.grid(row=0, column=1)

ename = Entry(frame, width=20, font=f)
ename.grid(row=1, column=1)

desig = Entry(frame, width=20, font=f)
desig.grid(row=2, column=1)

jd = Entry(frame, width=20, font=f)
jd.grid(row=3, column=1)

ed = Entry(frame, width=20, font=f)
ed.grid(row=4, column=1)

gender = OptionMenu(
    frame, 
    genvar,
    *genopt
)
gender.grid(row=5, column=1, pady=(5,0))
gender.config(width=15, font=f)

btn_frame = Frame(frame, bg=bgcolor)
btn_frame.grid(columnspan=2, pady=(50, 0))

# default inputs for testing
eid.insert(0,'E1008')
ename.insert(0, 'Vineet Singh')
desig.insert(0, 'Python Developer')
jd.insert(0, 'Aug 3rd, 2020')
ed.insert(0, 'July 31st, 2021')

submit_btn = Button(
    btn_frame,
    text='Generate Word',
    command=generate,
    font=btn_font,
    padx=10, 
    pady=5
)
submit_btn.pack(side=LEFT, expand=True, padx=(15, 0))

clear_btn = Button(
    btn_frame,
    text='Clear',
    command=clear_inputs,
    font=btn_font,
    padx=10, 
    pady=5,
    width=7
)
clear_btn.pack(side=LEFT, expand=True, padx=15)

exit_btn = Button(
    btn_frame,
    text='Exit',
    command=lambda:ws.destroy(),
    font=btn_font,
    padx=10, 
    pady=5
)
exit_btn.pack(side=LEFT, expand=True)

# mainloop
ws.mainloop()

Output of Python Tkinter Application

Create Word Document in Python Tkinter
python tkinter generated service certificate

In this tutorial, I have explained how to create a Word document using a simple GUI application.

You may like to read:

51 Python Programs

51 PYTHON PROGRAMS PDF FREE

Download a FREE PDF (112 Pages) Containing 51 Useful Python Programs.

pyython developer roadmap

Aspiring to be a Python developer?

Download a FREE PDF on how to become a Python developer.

Let’s be friends

Be the first to know about sales and special discounts.