├── Create_Your_Own_Template ├── Placeholders │ ├── Placeholder.png │ ├── Placeholder_1.png │ ├── Placeholder_2.png │ ├── Placeholder_3.png │ ├── Placeholder_4.png │ └── Placeholder_5.png ├── Template.docx ├── Template_Rendered.docx └── example.py ├── README.md ├── Sales_Report_April.docx ├── Sales_Report_April.pdf ├── Sales_Report_TEMPLATE.docx ├── requirements.txt ├── sales_by_subcategory.png ├── word_automation.py └── word_automation.xlsm /Create_Your_Own_Template/Placeholders/Placeholder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sven-Bo/python-word-automation/19fc2ff12e2aee7c860d49351b5a5e62d52ff077/Create_Your_Own_Template/Placeholders/Placeholder.png -------------------------------------------------------------------------------- /Create_Your_Own_Template/Placeholders/Placeholder_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sven-Bo/python-word-automation/19fc2ff12e2aee7c860d49351b5a5e62d52ff077/Create_Your_Own_Template/Placeholders/Placeholder_1.png -------------------------------------------------------------------------------- /Create_Your_Own_Template/Placeholders/Placeholder_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sven-Bo/python-word-automation/19fc2ff12e2aee7c860d49351b5a5e62d52ff077/Create_Your_Own_Template/Placeholders/Placeholder_2.png -------------------------------------------------------------------------------- /Create_Your_Own_Template/Placeholders/Placeholder_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sven-Bo/python-word-automation/19fc2ff12e2aee7c860d49351b5a5e62d52ff077/Create_Your_Own_Template/Placeholders/Placeholder_3.png -------------------------------------------------------------------------------- /Create_Your_Own_Template/Placeholders/Placeholder_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sven-Bo/python-word-automation/19fc2ff12e2aee7c860d49351b5a5e62d52ff077/Create_Your_Own_Template/Placeholders/Placeholder_4.png -------------------------------------------------------------------------------- /Create_Your_Own_Template/Placeholders/Placeholder_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sven-Bo/python-word-automation/19fc2ff12e2aee7c860d49351b5a5e62d52ff077/Create_Your_Own_Template/Placeholders/Placeholder_5.png -------------------------------------------------------------------------------- /Create_Your_Own_Template/Template.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sven-Bo/python-word-automation/19fc2ff12e2aee7c860d49351b5a5e62d52ff077/Create_Your_Own_Template/Template.docx -------------------------------------------------------------------------------- /Create_Your_Own_Template/Template_Rendered.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sven-Bo/python-word-automation/19fc2ff12e2aee7c860d49351b5a5e62d52ff077/Create_Your_Own_Template/Template_Rendered.docx -------------------------------------------------------------------------------- /Create_Your_Own_Template/example.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path # core library 2 | 3 | from docx.shared import Cm, Emu, Inches, Mm # pip install python-docx 4 | from docxtpl import DocxTemplate, InlineImage # pip install docxtpl 5 | 6 | # Path settings 7 | current_dir = Path(__file__).parent 8 | template_path = current_dir / "Template.docx" 9 | output_path = current_dir / "Template_Rendered.docx" 10 | img_placeholder1_path = current_dir / "Placeholders" / "Placeholder_1.png" 11 | img_placeholder2_path = current_dir / "Placeholders" / "Placeholder_2.png" 12 | 13 | 14 | doc = DocxTemplate(template_path) 15 | placeholder_1 = InlineImage(doc, str(img_placeholder1_path), Cm(5)) 16 | placeholder_2 = InlineImage(doc, str(img_placeholder2_path), Cm(5)) 17 | context = { 18 | "name": "Sven", 19 | "placeholder_1": placeholder_1, 20 | "placeholder_2": placeholder_2, 21 | } 22 | 23 | doc.render(context) 24 | doc.save(output_path) 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # Automating Word Documents from Excel Using Python 3 | 4 | Did you know you can use Python code to dynamically create Word Documents? For this tutorial, we will be using the Python libraries ‘xlwings’ & ‘docxtpl’ to automate Word. In particular, we will be writing values from Excel to Word by using Python. 5 | 6 | 7 | ## Video 8 | 9 | [![YouTube Video](https://img.youtube.com/vi/T3meVMaV8AA/0.jpg)](https://youtu.be/T3meVMaV8AA) 10 | 11 | 12 | 13 | ## 🤓 Check Out My Excel Add-ins 14 | I've developed some handy Excel add-ins that you might find useful: 15 | 16 | - 📊 **[Dashboard Add-in](https://pythonandvba.com/grafly)**: Easily create interactive and visually appealing dashboards. 17 | - 🎨 **[Cartoon Charts Add-In](https://pythonandvba.com/cuteplots)**: Create engaging and fun cartoon-style charts. 18 | - 🤪 **[Emoji Add-in](https://pythonandvba.com/emojify)**: Add a touch of fun to your spreadsheets with emojis. 19 | - 🛠️ **[MyToolBelt Add-in](https://pythonandvba.com/mytoolbelt)**: A versatile toolbelt for Excel, featuring: 20 | - Creation of Pandas DataFrames and Jupyter Notebooks from Excel ranges 21 | - ChatGPT integration for advanced data analysis 22 | - And much more! 23 | 24 | 25 | 26 | ## 🤝 Connect with Me 27 | - 📺 **YouTube:** [CodingIsFun](https://youtube.com/c/CodingIsFun) 28 | - 🌐 **Website:** [PythonAndVBA](https://pythonandvba.com) 29 | - 💬 **Discord:** [Join the Community](https://pythonandvba.com/discord) 30 | - 💼 **LinkedIn:** [Sven Bosau](https://www.linkedin.com/in/sven-bosau/) 31 | - 📸 **Instagram:** [sven_bosau](https://www.instagram.com/sven_bosau/) 32 | 33 | ## ☕ Support 34 | If you appreciate the project and wish to encourage its continued development, consider [supporting my work](https://pythonandvba.com/coffee-donation). 35 | [![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://pythonandvba.com/coffee-donation) 36 | 37 | ## Feedback & Collaboration 38 | For feedback, suggestions, or potential collaboration opportunities, reach out at contact@pythonandvba.com. 39 | ![Logo](https://www.pythonandvba.com/banner-img) 40 | 41 | -------------------------------------------------------------------------------- /Sales_Report_April.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sven-Bo/python-word-automation/19fc2ff12e2aee7c860d49351b5a5e62d52ff077/Sales_Report_April.docx -------------------------------------------------------------------------------- /Sales_Report_April.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sven-Bo/python-word-automation/19fc2ff12e2aee7c860d49351b5a5e62d52ff077/Sales_Report_April.pdf -------------------------------------------------------------------------------- /Sales_Report_TEMPLATE.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sven-Bo/python-word-automation/19fc2ff12e2aee7c860d49351b5a5e62d52ff077/Sales_Report_TEMPLATE.docx -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | python_docx==0.8.10 2 | pywin32==227 3 | xlwings==0.23.0 4 | pandas==1.2.0 5 | matplotlib==3.3.3 6 | docxtpl==0.11.4 7 | docx==0.2.4 8 | -------------------------------------------------------------------------------- /sales_by_subcategory.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sven-Bo/python-word-automation/19fc2ff12e2aee7c860d49351b5a5e62d52ff077/sales_by_subcategory.png -------------------------------------------------------------------------------- /word_automation.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path # core library 2 | 3 | import matplotlib.pyplot as plt # pip install matplotlib 4 | import pandas as pd # pip install pandas 5 | import win32com.client as win32 # pip install pywin32 6 | import xlwings as xw # pip install xlwings 7 | from docxtpl import DocxTemplate # pip install docxtpl 8 | 9 | # -- Documentation: 10 | # python-docx-template: https://docxtpl.readthedocs.io/en/latest/ 11 | 12 | 13 | def create_barchart(df, barchart_output): 14 | """Group DataFrame by sub-category, plot barchart, save plot as PNG""" 15 | top_products = df.groupby(by=df["Sub-Category"]).sum()[["Sales"]] 16 | top_products = top_products.sort_values(by="Sales") 17 | plt.rcParams["figure.dpi"] = 300 18 | plot = top_products.plot(kind="barh") 19 | fig = plot.get_figure() 20 | fig.savefig(barchart_output, bbox_inches="tight") 21 | return None 22 | 23 | 24 | def convert_to_pdf(doc): 25 | """Convert given word document to pdf""" 26 | word = win32.DispatchEx("Word.Application") 27 | new_name = doc.replace(".docx", ".pdf") 28 | worddoc = word.Documents.Open(doc) 29 | worddoc.SaveAs(new_name, FileFormat=17) 30 | worddoc.Close() 31 | return None 32 | 33 | 34 | def main(): 35 | # Path settings 36 | current_dir = Path(__file__).parent 37 | template_path = current_dir / "Sales_Report_TEMPLATE.docx" 38 | 39 | # Conection to Excel 40 | wb = xw.Book.caller() 41 | sht_panel = wb.sheets["PANEL"] 42 | sht_sales = wb.sheets["Sales"] 43 | context = sht_panel.range("A2").options(dict, expand="table", numbers=int).value 44 | df = sht_sales.range("A1").options(pd.DataFrame, index=False, expand="table").value 45 | 46 | # Initialize template 47 | doc = DocxTemplate(str(template_path)) 48 | 49 | # -- Create Barchart & Replace Placeholder 50 | barchart_name = "sales_by_subcategory" 51 | barchart_output = current_dir / f"{barchart_name}.png" 52 | create_barchart(df, barchart_output) 53 | doc.replace_pic("Placeholder_1.png", barchart_output) 54 | 55 | # -- Render & Save Word Document 56 | output_name = current_dir / f'Sales_Report_{context["month"]}.docx' 57 | doc.render(context) 58 | doc.save(output_name) 59 | 60 | # -- Convert to PDF [OPTIONAL] 61 | convert_to_pdf(str(output_name)) 62 | 63 | # -- Show Message Box [OPTIONAL] 64 | show_msgbox = wb.macro("Module1.ShowMsgBox") 65 | show_msgbox("DONE!") 66 | 67 | 68 | if __name__ == "__main__": 69 | xw.Book("word_automation.xlsm").set_mock_caller() 70 | main() 71 | -------------------------------------------------------------------------------- /word_automation.xlsm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sven-Bo/python-word-automation/19fc2ff12e2aee7c860d49351b5a5e62d52ff077/word_automation.xlsm --------------------------------------------------------------------------------