Генерация документов Word через python-docx

Договоры, акты, письма по шаблону — идеальная рутина для автоматизации. Библиотека python-docx собирает .docx-документы из Python: заголовки, абзацы, таблицы.
Суть: Document() — новый документ, add_heading и add_paragraph добавляют текст, add_table — таблицу. Шаблон = текст с плейсхолдерами, которые вы подставляете.

Если ваша работа — каждый день делать однотипные документы (договоры, счета, письма), меняя в них пару полей, это прямой кандидат на автоматизацию. python-docx (ставится как pip install python-docx) создаёт и редактирует файлы .docx программно. Модель похожа на openpyxl: документ состоит из блоков — заголовков, абзацев, таблиц, — которые вы добавляете по очереди.

Самый частый сценарий — шаблон с подстановкой: берёте текст с метками вроде {name} и заменяете их реальными данными. Эта логика подстановки — чистый Python и прекрасно работает в браузере.

Попробуй сам ▶

# Шаблон письма с плейсхолдерами
template = '''Уважаемый(ая) {name}!

Подтверждаем заказ № {order} на сумму {amount} руб.
Дата доставки: {date}.

С уважением, отдел продаж.'''

# Данные для нескольких писем
clients = [
    {'name': 'Анна', 'order': '4821', 'amount': '15600', 'date': '25.06.2026'},
    {'name': 'Борис', 'order': '4822', 'amount': '7300', 'date': '26.06.2026'},
]

for c in clients:
    letter = template.format(**c)   # подстановка по именам
    print(letter)
    print('=' * 40)

Метод str.format(**data) подставляет значения словаря в плейсхолдеры по именам — распаковка ** превращает ключи словаря в именованные аргументы. Этот приём — ядро любой шаблонной генерации, будь то Word, письмо или HTML. Сборка самого .docx показана как нерабочая в браузере врезка.

from docx import Document

doc = Document()
doc.add_heading('Договор поставки', level=1)
doc.add_paragraph('Настоящий договор заключён между сторонами.')

# Таблица позиций
table = doc.add_table(rows=1, cols=2)
table.rows[0].cells[0].text = 'Товар'
table.rows[0].cells[1].text = 'Цена'
for name, price in [('Ноутбук', '75000'), ('Мышь', '1200')]:
    cells = table.add_row().cells
    cells[0].text = name
    cells[1].text = price

doc.save('contract.docx')
ГЕНЕРАЦИЯ DOCX ПО ШАБЛОНУ

  данные (dict)        шаблон
       |                 |
       +-------+---------+
               v
        format(**data)
               |
               v
  Document: heading + paragraph + table
               |
               v
          save() -> .docx

Для по-настоящему сложных шаблонов с условиями и циклами одного str.format мало — там на помощь приходят шаблонизаторы вроде docxtpl, надстройки над python-docx на движке Jinja2. В таком шаблоне прямо в Word-файле пишут конструкции вида «если клиент VIP — показать абзац» или «для каждой позиции — строка таблицы», а скрипт подставляет данные. Это позволяет дизайнеру оформить документ в самом Word, а программисту — лишь передать данные, не трогая вёрстку. Для типовых писем хватает и format, но знать про шаговое усложнение полезно: вы выберете инструмент по сложности задачи, а не возьмёте кувалду для гвоздя.

Как работает под капотом

Как и .xlsx, файл .docx — это zip-архив с XML внутри (формат Office Open XML). python-docx строит дерево XML-элементов, представляющих документ, и при save() упаковывает его в zip. Вот почему библиотека не требует установленного Word: она работает с форматом файла напрямую.

Распаковка словаря через ** в format(**data) — общий механизм Python: он превращает {'name': 'Анна'} в именованный аргумент name='Анна'. Тот же приём используют функции с гибкими параметрами. Поняв его один раз, вы будете применять его повсюду, далеко за пределами Word.

Частые ошибки

  • Отсутствующий ключ в шаблоне. Если в тексте есть {phone}, а в данных его нет, format упадёт с KeyError.
  • Путать python-docx и docx. Ставится пакет python-docx, а импортируется как from docx import Document.
  • Фигурные скобки в самом тексте. Литеральная { в шаблоне format ломает подстановку; её экранируют как {{.

Best practices

  • Держите шаблон отдельно от кода — так его правит даже не-программист.
  • Проверяйте, что все нужные ключи есть в данных, до подстановки.
  • Для массовой рассылки делайте цикл по данным, генерируя по документу на запись.

Итоги. python-docx собирает Word-документы из заголовков, абзацев и таблиц, а шаблоны с format(**data) автоматизируют типовые письма и договоры. Документы готовы — осталось научиться их рассылать. Переходим к email и веб-данным.

Проверьте себя
1. Что делает str.format(**data) с шаблоном 'Привет, {name}!'?
AУдаляет фигурные скобки
BПодставляет значение data['name'] вместо {name}
CВозвращает ошибку всегда
DСоздаёт файл .docx
2. Почему python-docx не требует установленного Microsoft Word?
A.docx — это zip-архив с XML, и библиотека пишет его напрямую
BWord встроен в Python
Cpython-docx запускает Word в фоне
DДокументы создаются только в облаке