Post

Generate Word Report using python-docx

Learn how to use the python-docx package to automate Word .docx files

Generate Word Report using python-docx

Overview

  • python-docx is:
    • open source, so you can use it for free
    • independent of Office; you can generate .docx files even if Office is not installed on your system
    • cross-platform, so you can use it on any operating system or web apps like Streamlit
    • in active development with really good documentation
    • Documentation
  • Requirements
    • Python 3.9 or higher

Setup

  • Use pip install python-docx to install the python-docx package

Write new docx file

1
2
3
4
5
6
7
8
9
from docx import Document

# Create new Word Document
document = Document()

# Add Code to Generate Document Content Here

# Save Document to specific location
document.save("Report.docx")

Use existing document for custom formatting

1
document = Document("Template.docx")

Title

1
2
# Add Title
document.add_heading("Automated Report", 0)
1
2
3
4
5
6
7
8
# Add Header 1
document.add_heading("Header 1", level=1)

# Add Header 2
document.add_heading("Header 2", level=2)

# Add Header 3
document.add_heading("Header 3", level=3)

Paragraph

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
# Add a paragraph
document.add_heading("Paragraph", level=3)
P = document.add_paragraph("This is a sample paragraph in the report.")

# Add more text to the same paragraph
P.add_run("This text is added to the same paragraph.")

# Paragraph formatting
P = document.add_paragraph("This is paragraph with Center Alignment, ")
P_format = P.paragraph_format
P_format.alignment = WD_ALIGN_PARAGRAPH.CENTER  # Center alignment

# Paragraph with space before and after
P = document.add_paragraph("This is paragraph with space before and after.")
P_format = P.paragraph_format
P_format.space_after = Pt(24)  # Space after paragraph
P_format.space_before = Pt(24)  # Space before paragraph

# Paragraph with Different Left Indent
P = document.add_paragraph("This is paragraph with Custom Left Indent.")
P_format = P.paragraph_format
P_format.left_indent = Pt(36)  # Left indent

# Paragraph with different font and size
P = document.add_paragraph("This is paragraph with Arial Font with size 12.")
P_font = P.runs[0].font
P_font.name = "Arial"  # Font name
P_font.size = Pt(12)  # Font size

# Paragraph with Different Underline Style
P = document.add_paragraph("This is paragraph with Underline Style Double.")
P_font = P.runs[0].font
P_font.underline = True  # Underline text
P_font.underline = WD_UNDERLINE.DOUBLE  # Underline style

Text Formatting

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
# Add Bold Text
P = document.add_paragraph("This is paragraph with bold text.")
P.add_run(" Adding Bold Text Here.").bold = True

# Add Italic Text
P = document.add_paragraph("This is paragraph with Italic Text.")
P.add_run(" Adding Italic Text Here.").italic = True

# Add Text with underline
P = document.add_paragraph("This is paragraph with Underlined Text.")
P.add_run(" Adding Underlined Text Here.").underline = True

# Add Text with Red Color
P = document.add_paragraph("This is paragraph with Red Color Text.")
P.add_run(" Adding Red Color Text Here.").font.color.rgb = RGBColor(255, 0, 0)

# Add Text with Yellow Highlight Color
P = document.add_paragraph("This is paragraph with Yellow Highlight Color Text.")
P.add_run(" Adding Yellow Highlight Here.").font.highlight_color = WD_COLOR_INDEX.YELLOW

# Add Text With Different Font
P = document.add_paragraph("This is paragraph with Verdana Font Text.")
P.add_run(" Adding Verdana Font Text Here.").font.name = "Verdana"

# Add Text with Different Font Size
P = document.add_paragraph("This is paragraph with 16 font size Text.")
P.add_run(" Adding 16 font size Text Here.").font.size = Pt(16)

# Adding Text with Different Text Style Subtle Emphasis
P = document.add_paragraph("This is paragraph with Subtle Emphasis Text.")
P.add_run(" Adding text with subtle emphasis.").style = "Subtle Emphasis"
1
2
3
4
5
6
# Apply Multiple Formattings
P = document.add_paragraph()
Line = P.add_run("This is paragraph with Bold, Italic and Underlined Text.")
Line.bold = True
Line.italic = True
Line.underline = True

Bullet List

1
2
3
4
5
# Add a bullet list
document.add_heading("Bullet List", level=3)
document.add_paragraph("First item in unordered list", style="List Bullet")
document.add_paragraph("Second item in unordered list", style="List Bullet")
document.add_paragraph("Third item in unordered list", style="List Bullet")

Numbered List

1
2
3
4
5
# Add a numbered list
document.add_heading("Numbered List", level=3)
document.add_paragraph("First item in ordered list", style="List Number")
document.add_paragraph("Second item in ordered list", style="List Number")
document.add_paragraph("Third item in ordered list", style="List Number")

Formula

  • python-docx doesn’t have built-in support for LaTeX formulas.
  • We’ll use the math2docx library to add formulas.
  • Use pip install math2docx to install the math2docx library.
  • Add import math2docx to include math formulas.
1
2
3
4
5
# Adding Text with formula
document.add_heading("Formula", level=3)
P = document.add_paragraph()
latex_ = r"BM = \frac{w \times l^2}{8}"
math2docx.add_math(P, latex_)

Quote

1
2
3
4
# Add Quote
document.add_heading("Quote", level=3)
P = document.add_paragraph("This is just a sample quote.")
P.style = "Intense Quote"

Image

  • Import the Inches class using from docx.shared import Inches
1
2
3
# Add Image chart.png
document.add_heading("Images", level=3)
document.add_picture("chart.png", width=Inches(5))

Table

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
document.add_heading("Simple Table", level=3)
records = (
    (7, "22.1", "25.5"),
    (14, "26.9", "31.2"),
    (21, "28.5", "35.2"),
    (28, "30.9", "40.0")
)

table = document.add_table(rows=1, cols=3)

# Header Row
hdr_cells = table.rows[0].cells
hdr_cells[0].text = "Days"
hdr_cells[1].text = "M30 Strength"
hdr_cells[2].text = "M40 Strength"

# Data Rows
for qty, id, desc in records:
    row_cells = table.add_row().cells
    row_cells[0].text = str(qty)
    row_cells[1].text = id
    row_cells[2].text = desc

# Set Table style to Table Grid
table.style = "Table Grid"

# Set First row as Bold
for cell in table.rows[0].cells:
    for paragraph in cell.paragraphs:
        for run in paragraph.runs:
            run.bold = True

# Set Center alignment for all columns
for col in table.columns:
    for cell in col.cells:
        cell.paragraphs[0].alignment = 1

PageBreak

1
2
# Add Page Break
document.add_page_break()

Final Code

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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
import math2docx
from docx import Document
from docx.shared import Inches, RGBColor, Pt
from docx.enum.text import WD_ALIGN_PARAGRAPH, WD_UNDERLINE, WD_COLOR_INDEX

# Create new Word Document
document = Document()

# Add Title
document.add_heading("Automated Report", level=0)

# Add Header 1
document.add_heading("Header 1", level=1)

# Add Header 2
document.add_heading("Header 2", level=2)

# Add Header 3
document.add_heading("Header 3", level=3)

# Add a paragraph
document.add_heading("Paragraph", level=3)
P = document.add_paragraph("This is a sample paragraph in the report.")

# Add more text to the same paragraph
P.add_run("This text is added to the same paragraph.")

# Paragraph formatting
P = document.add_paragraph("This is paragraph with Center Alignment, ")
P_format = P.paragraph_format
P_format.alignment = WD_ALIGN_PARAGRAPH.CENTER  # Center alignment

# Paragraph with space before and after
P = document.add_paragraph("This is paragraph with space before and after.")
P_format = P.paragraph_format
P_format.space_after = Pt(24)  # Space after paragraph
P_format.space_before = Pt(24)  # Space before paragraph

# Paragraph with Different Left Indent
P = document.add_paragraph("This is paragraph with Custom Left Indent.")
P_format = P.paragraph_format
P_format.left_indent = Pt(36)  # Left indent

# Paragraph with different font and size
P = document.add_paragraph("This is paragraph with Arial Font with size 12.")
P_font = P.runs[0].font
P_font.name = "Arial"  # Font name
P_font.size = Pt(12)  # Font size

# Paragraph with Different Underline Style
P = document.add_paragraph("This is paragraph with Underline Style Double.")
P_font = P.runs[0].font
P_font.underline = True  # Underline text
P_font.underline = WD_UNDERLINE.DOUBLE  # Underline style

document.add_page_break()
document.add_heading("Text Formatting", level=2)

# Add Bold Text
P = document.add_paragraph("This is paragraph with bold text.")
P.add_run(" Adding Bold Text Here.").bold = True

# Add Italic Text
P = document.add_paragraph("This is paragraph with Italic Text.")
P.add_run(" Adding Italic Text Here.").italic = True

# Add Text with underline
P = document.add_paragraph("This is paragraph with Underlined Text.")
P.add_run(" Adding Underlined Text Here.").underline = True

# Add Text with Red Color
P = document.add_paragraph("This is paragraph with Red Color Text.")
P.add_run(" Adding Red Color Text Here.").font.color.rgb = RGBColor(255, 0, 0)

# Add Text with Yellow Highlight Color
P = document.add_paragraph(
    "This is paragraph with Yellow Highlight Color Text.")
P.add_run(
    " Adding Yellow Highlight Here.").font.highlight_color = WD_COLOR_INDEX.YELLOW

# Add Text With Different Font
P = document.add_paragraph("This is paragraph with Verdana Font Text.")
P.add_run(" Adding Verdana Font Text Here.").font.name = "Verdana"

# Add Text with Different Font Size
P = document.add_paragraph("This is paragraph with 16 font size Text.")
P.add_run(" Adding 16 font size Text Here.").font.size = Pt(16)

# Adding Text with Different Text Style Subtle Emphasis
P = document.add_paragraph("This is paragraph with Subtle Emphasis Text.")
P.add_run(" Adding text with subtle emphasis.").style = "Subtle Emphasis"

# Apply Multiple Formattings
P = document.add_paragraph()
Line = P.add_run("This is paragraph with Bold, Italic and Underlined Text.")
Line.bold = True
Line.italic = True
Line.underline = True

document.add_page_break()
document.add_heading("Text Styles", level=2)

# Add a bullet list
document.add_heading("Bullet List", level=3)
document.add_paragraph("First item in unordered list", style="List Bullet")
document.add_paragraph("Second item in unordered list", style="List Bullet")
document.add_paragraph("Third item in unordered list", style="List Bullet")

# Add a numbered list
document.add_heading("Numbered List", level=3)
document.add_paragraph("First item in ordered list", style="List Number")
document.add_paragraph("Second item in ordered list", style="List Number")
document.add_paragraph("Third item in ordered list", style="List Number")

# Adding Text with formula
document.add_heading("Formula", level=3)
P = document.add_paragraph()
latex_ = r"BM = \frac{w \times l^2}{8}"
math2docx.add_math(P, latex_)

# Add Quote
document.add_heading("Quote", level=3)
quote = document.add_paragraph(
    "The greatest glory in living lies not in never falling, "
    "but in rising every time we fall.")
quote.style = "Intense Quote"

# Add Page Break
document.add_page_break()

# Add Table
document.add_heading("Tables", level=2)

# Simple Table
document.add_heading("Simple Table", level=3)
records = (
    (7, "22.1", "25.5"),
    (14, "26.9", "31.2"),
    (21, "28.5", "35.2"),
    (28, "30.9", "40.0")
)

table = document.add_table(rows=1, cols=3)

# Header Row
hdr_cells = table.rows[0].cells
hdr_cells[0].text = "Days"
hdr_cells[1].text = "M30 Strength"
hdr_cells[2].text = "M40 Strength"

# Data Rows
for qty, id, desc in records:
    row_cells = table.add_row().cells
    row_cells[0].text = str(qty)
    row_cells[1].text = id
    row_cells[2].text = desc

# Set Table style to Table Grid
table.style = "Table Grid"

# Set First row as Bold
for cell in table.rows[0].cells:
    for paragraph in cell.paragraphs:
        for run in paragraph.runs:
            run.bold = True

# Set Center alignment for all columns
for col in table.columns:
    for cell in col.cells:
        cell.paragraphs[0].alignment = 1

document.add_page_break()
document.add_heading("Media", level=2)

# Add Image chart.png
document.add_heading("Images", level=3)
document.add_picture("chart.png", width=Inches(5))

# Save Document to specific location
document.save("Report.docx")

Conclusion

  • The python-docx library is one of the simplest ways to generate Word reports using Python.
  • You can also use an existing document with your own styles and formatting to maintain your custom style
This post is licensed under CC BY-NC-ND 4.0 by the author.