python-docx-template: Construct Word table in python and place into a specific location in a Word template

1.7k Views Asked by At

I wish to construct a Microsoft Word table using Python and then place it into a location marked by a placeholder in the Word template. Is this possible to do using docx and docx template?

The code below is a basic example of what I'm trying to do, but I'm unsure of how to place the table into the word template.

I know I can create a basic table using Jinja2 tags and add rows to the table using the render method, but the table creation logic is a bit involved (merging of certain cells, and empty spaces to separate related rows), so I'd prefer to construct the table using Python, and not have to use Jinja2 for that. Any help is appreciated!

from docxtpl import DocxTemplate
from docx.table import Table

doc = DocxTemplate('template.docx')

items = [
    {'column1': 'Item 1-1', 'column2': 'Item 1-2', 'column3': 'Item 1-3'},
    {'column1': 'Item 2-1', 'column2': 'Item 2-2', 'column3': 'Item 2-3'},
    {'column1': 'Item 3-1', 'column2': 'Item 3-2', 'column3': 'Item 3-3'}
]

rows = []
for item in items:
    row = [item['column1'], item['column2'], item['column3']]
    rows.append(row)

table = Table(len(rows)+1, 3)  # Create a new table with the correct number of rows and columns
table.cell(0, 0).text = 'Column 1'  # Add the column headers to the first row
table.cell(0, 1).text = 'Column 2'
table.cell(0, 2).text = 'Column 3'
for i, row in enumerate(rows):
    table.cell(i+1, 0).text = row[0]  # Add the row data to the table
    table.cell(i+1, 1).text = row[1]
    table.cell(i+1, 2).text = row[2]

# Code required here to place the table in the word template at a specific placeholder location.

doc.save('output.docx')
1

There are 1 best solutions below

4
Sergey Zaykov On

I'm sorry.

This is an example of constructing a table by Python docx package and placing it into a specific location in a Word template.

Inserting table does via saving temporary file named demo.docx.

"""Tesing subdoc."""

from docx import Document

from docxtpl import DocxTemplate


def make_table(name):
    """Make table document."""
    sd = Document()

    items = [
        {"column1": "Item 1-1", "column2": "Item 1-2", "column3": "Item 1-3"},
        {"column1": "Item 2-1", "column2": "Item 2-2", "column3": "Item 2-3"},
        {"column1": "Item 3-1", "column2": "Item 3-2", "column3": "Item 3-3"},
    ]

    rows = []
    for item in items:
        row = [item["column1"], item["column2"], item["column3"]]
        rows.append(row)

    table = sd.add_table(
        rows=4, cols=3
    )  # Create a new table with the correct number of rows and columns
    table.cell(0, 0).text = "Column 1"  # Add the column headers to the first row
    table.cell(0, 1).text = "Column 2"
    table.cell(0, 2).text = "Column 3"
    for i, row in enumerate(rows):
        table.cell(i + 1, 0).text = row[0]  # Add the row data to the table
        table.cell(i + 1, 1).text = row[1]
        table.cell(i + 1, 2).text = row[2]

    sd.save(name)


make_table("demo.docx")  # create document with tricks table
doc = DocxTemplate("template.docx")  # do docxtpl template for main document
sd = doc.new_subdoc("demo.docx")  # do subdocument
# place the table in the word main document at a specific placeholder location.
context = {
    "mysubdoc": sd,
}

doc.render(context)

doc.save("output.docx")

Sourses and docs: