Как стать автором
Обновить

Два пути к автоматизации: как создавать отчеты в Word массово

Уровень сложностиПростой
Время на прочтение3 мин
Количество просмотров515

Однажды мне понадобилось создать документы для отчетности, все они были однотипные, менялись лишь даты, ФИО, должности и списки работ. Я нашла 2 способа это автоматизировать:

  • при помощи функции «слияния» в ворде

  • при помощи Python

Автоматизация с помощью "слияния" в ворде

Самый простой способ - воспользоваться функцией «слияния» в ворде. Подробнее о том, как сделать слияние, можно посмотреть в инструкции. Здесь я сделаю краткий обзор и напишу, почему мне оно не подошло.

Для слияния нужно:

  1. создать табличку в Excel

  2. заполнить ее данными (ФИО, должностями и пр.):

    Табличка с переменными данными
    Табличка с переменными данными
  3. открыть вордовский файл с шаблоном отчета:

    Шаблон
    Шаблон

  4. вставить в места, где данные разнятся, названия соответствующих полей из эксельки

    Шаблон со вставленными полями из Excel
    Шаблон со вставленными полями из Excel
  5. нажать чудо-кнопку

    генерация отчетов
    генерация отчетов

и дальше чудо-функция генерила столько отчетов, сколько строк в эксельке.

Есть одно но: все отчеты сохраняются в виде одной большой pdf-ки, что совершенно не годилось: мне они нужны были в формате ворд, каждый отдельным файлом.

Один из способов получить отчеты в нужном формате - создать столько копий файла-шаблона, сколько нужно отчетов:

копирование шаблона
копирование шаблона

затем каждый поочередно открыть, включить режим предпросмотра:

режим предпросмотра
режим предпросмотра

прокрутить до нужного "образца" (номера строки Excel, из которой были взяты данные):

прокрутка до нужного "образца"
прокрутка до нужного "образца"

затем сохранить в таком виде и закрыть. И так для каждого отчета по порядку. Хлопотно, но возможно.

Примечание. Как видите, список работ вставляется корректно, заданное в шаблоне форматирование сохраняется. Чтобы каждый пункт списка был с новой строки, достаточно в Excel написать его с новой строки:

список в Excel
список в Excel

Также можно было конвертировать pdf-ку в ворд и разбить на файлы, но я не нашла конвертер, после которого бы не слетали шрифты и форматирование, что для меня было критично.

Автоматизация с помощью Python

Я стала искать другой способ, и мне помогла статья на Хабре про автоматизацию с помощью Python. Я очень рекомендую с ней ознакомиться для полноты картины. В ней был приведен скрипт, который делает то же самое, что и “слияние”, но каждый отчет кладет в отдельный ворд. Я немного доработала его под свои нужды:

  • Так как в эксельке я использовала формулы для заполнения таблички, мне нужно было чтоб скрипт брал из ячеек не сами формулы, а результат их выполнения. Для этого я добавила параметр data_only=True в функцию которая считывает эксельку:

    wb = openpyxl.load_workbook(filename='данные для слияния.xlsx', data_only=True)

    Если не вставить этот параметр, то вот какой отчет вы можете получить:

    Исходная таблица. Даты вычисляются с помощью формул
    Исходная таблица. Даты вычисляются с помощью формул
    Формулы вместо значений
    Формулы вместо значений
  • Чтобы корректно вставить список, воспользовалась классом Listing:

    listTO = Listing(sheet['D'+str(num)].value.replace('\n', '\a'))

    Он преобразует строку в список, в качестве разделителя пунктов списка использует "\a". Поэтому я заменила перенос строки в исходном тексте "\n" на "\a". Если не сделать это преобразование, список вставится одним куском:

    Список, вставленный без использования Listing
    Список, вставленный без использования Listing
  • Вы могли заметить, что вместе с датой выводится еще и время:

    Вывод даты
    Вывод даты

    Чтобы оставить только дату, можно воспользоваться классом datetime:

    date = datetime.date(sheet['A'+str(num)].value)

Примечание. Если заполнить таблицу Excel, а потом удалить часть строк снизу, Python всё равно “увидит” их как пустые ячейки. Поэтому при генерации отчётов скрипт создаст лишние документы с пропусками вместо данных, либо выдаст ошибку такого вида:

Ошибка при попытке применить метод replace к пустому месту
Ошибка при попытке применить метод replace к пустому месту

Чтобы это исправить, можно:

  1. Создать новый лист в Excel

  2. Скопировать туда все данные со старого листа

  3. Использовать новый лист для работы скрипта

Это решит проблему и скрипт будет обрабатывать только заполненные строки с данными.

Итоговый код:

import openpyxl
from docxtpl import DocxTemplate
from docxtpl import Listing
from datetime import datetime

wb = openpyxl.load_workbook(filename='данные для слияния.xlsx', data_only=True)
sheet = wb['Лист1']

doc = DocxTemplate('шаблон.docx')

for num in range(2,len(list(sheet.rows))+1):

    date = datetime.date(sheet['A'+str(num)].value)
    FIO = sheet['B'+str(num)].value
    position = sheet['C'+str(num)].value
    listTO = Listing(sheet['D'+str(num)].value.replace('\n', '\a'))

    context = {  
    'date': date,
    'FIO': FIO,
    'position': position,
    'listTO': listTO,
    }
 
    doc.render(context)
    doc.save(f"Отчет о ТО {num}.docx")

Теги:
Хабы:
+1
Комментарии1

Публикации

Истории

Работа

Data Scientist
49 вакансий

Ближайшие события

25 – 26 апреля
IT-конференция Merge Tatarstan 2025
Казань