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

от автора

Однажды мне понадобилось создать документы для отчетности, все они были однотипные, менялись лишь даты, ФИО, должности и списки работ. Я нашла 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") 


ссылка на оригинал статьи https://habr.com/ru/articles/888510/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *