• 15 апреля стартует «Курс «SQL-injection Master» ©» от команды The Codeby

    За 3 месяца вы пройдете путь от начальных навыков работы с SQL-запросами к базам данных до продвинутых техник. Научитесь находить уязвимости связанные с базами данных, и внедрять произвольный SQL-код в уязвимые приложения.

    На последнюю неделю приходится экзамен, где нужно будет показать свои навыки, взломав ряд уязвимых учебных сайтов, и добыть флаги. Успешно сдавшие экзамен получат сертификат.

    Запись на курс до 25 апреля. Получить промодоступ ...

Статья Автоматизация рутинной работы. Заполняем документы .docx с помощью Python

Как часто вы заполняете документы по шаблону? Я не особо, но если вам приходиться заполнять одни и те же данные в шаблонный документ, то в этом рутинном деле может помочь Python. И в значительной мере, буквально несколькими строчками кода облегчить работу, которая выполниться в считанные секунды, вместо потраченного дня. Давайте сделаем небольшой скрипт, который поможет автоматизировать рутинный процесс.

000-1.jpg


В принципе, я могу представить, кому и когда требуется выполнять работу по заполнению шаблонных документов. Например, юристам. Различные уведомления, постановления и прочие документы, с которыми они работают. Или кадровикам. Если нужно, к примеру, сделать большое количество однотипных уведомлений, где меняется только Ф.И.О., должность и подразделение. Да мало ли где. Давайте приступим к написанию кода.


Что понадобиться?

В этот раз понадобиться не особо много, а точнее, нужно будет установить всего лишь одну библиотеку docxtpl, с помощью которой и будет заполняться документ. Пишем в терминале:

pip install docxtpl

Понадобиться шаблон документа, в котором будут указаны места, куда нужно вставлять переменные. Места для вставки указываются с помощью двойных парных скобок: {{date}}, где дата, это та переменная, что будет заменена на нужное значение. Я скачал какое-то уведомление об изменении условий трудового договора, и расставил в него переменные:

screenshot1.png

И еще вам понадобится база данных работников или файл Excel с заполненными данными. С ним тоже можно работать. Я для примера использовал json-файл, в который внес некоторые данные. Этот файл, может быть выгружен из реальной программы по учету персонала. Не суть, какой формат файла вы выберете. Главное, чтобы вы смогли прочитать из него данные.

screenshot2.png


Заполнение данных

Импортируем в скрипт все библиотеки, что нам необходимы:

Python:
import json
import locale
import os

from datetime import datetime as dt
from docxtpl import DocxTemplate

Я создал небольшую функцию filling_doc(). Здесь в нее ничего не передается и не возвращается. Просто обрабатываются и сохраняются файлы. Но, если у вас есть база и несколько шаблонов с похожими данными, то можно запрашивать у пользователя путь к шаблону и базе. И передавать их в функцию. Здесь же, для демонстрации работы это не требуется.

Для того, чтобы заполнение даты в документе не выглядело совсем уж печально, я решил, что надо переводить дату в формат вида: 12 января 1970. Но, у питона с русской локалью оказалась беда. И системную локаль он просто так не подхватывает. Потому вызываем функцию setlocale(locale.LC_ALL, '') модуля locale.

locale.setlocale(locale.LC_ALL, '')

Следующим шагом будет загрузить файл шаблона, загрузить файл БД или json, с которым вы работаете, а также создать папку для сохранения результатов заполнения. Ведь мы их все будем сохранять под разными именами.

Python:
doc = DocxTemplate("template.docx")
user = json.load(open(os.path.join(os.getcwd(), 'user_info.json'), encoding='utf-8'))
if not os.path.isdir(os.path.join(os.getcwd(), 'personal')):
    os.mkdir(os.path.join(os.getcwd(), 'personal'))

Затем запускаем цикл по файлу json. Выводим принт, чтобы не было скучно. Он тут больше для декорации.

Python:
    for usr in user:
        print(f'\r[+] Заполняю: {usr["last_name"]}', end='')
        data = {'manager': 'И. С. Иванов', 'reason': 'реструктуризацией и оптимизацией закваски',
                'date': dt.strftime(dt.now(), '%d %B %Y'), 'fio': f'{usr["last_name"]} {usr["first_name"]} '
                                                                  f'{usr["middle_name"]}', 'post': usr['post'],
                'first_middle': f'{usr["first_name"]} {usr["middle_name"]}',
                'contract_date': dt.strftime(dt.strptime(usr['contract_date'], "%d.%m.%Y"), '%d %B %Y'),
                'contract_num': usr['contract_num'], 'day_x': '01.07.2021'}
        doc.render(data)
        doc.save(os.path.join(os.getcwd(), 'personal',
                              f'{usr["last_name"]} {usr["first_name"]} {usr["middle_name"]}.docx'))

Заполняем словарь необходимыми значениями для подстановки. Значения должны иметь такие же названия, как и в шаблоне. С помощью render заполняем данные и сохраняем файл с Ф.И.О. человека, на которого заполнялся шаблон.

Python:
# pip install docxtpl
import json
import locale
import os

from datetime import datetime as dt
from docxtpl import DocxTemplate


def filling_doc():
    locale.setlocale(locale.LC_ALL, '')
    doc = DocxTemplate("template.docx")
    user = json.load(open(os.path.join(os.getcwd(), 'user_info.json'), encoding='utf-8'))
    if not os.path.isdir(os.path.join(os.getcwd(), 'personal')):
        os.mkdir(os.path.join(os.getcwd(), 'personal'))
    for usr in user:
        print(f'\r[+] Заполняю: {usr["last_name"]}', end='')
        data = {'manager': 'И. С. Иванов', 'reason': 'реструктуризацией и оптимизацией закваски',
                'date': dt.strftime(dt.now(), '%d %B %Y'), 'fio': f'{usr["last_name"]} {usr["first_name"]} '
                                                                  f'{usr["middle_name"]}', 'post': usr['post'],
                'first_middle': f'{usr["first_name"]} {usr["middle_name"]}',
                'contract_date': dt.strftime(dt.strptime(usr['contract_date'], "%d.%m.%Y"), '%d %B %Y'),
                'contract_num': usr['contract_num'], 'day_x': '01.07.2021'}
        doc.render(data)
        doc.save(os.path.join(os.getcwd(), 'personal',
                              f'{usr["last_name"]} {usr["first_name"]} {usr["middle_name"]}.docx'))


def main():
    filling_doc()
    print('\n[+] Все записи обработаны')


if __name__ == "__main__":
    main()

Вот так вот, достаточно просто и быстро можно избавить себя от кучи рутинной работы. Единственное, на что здесь, именно в этом коде нужно обратить внимание, это на склонения названий месяцев. То есть, нужно или найти библиотеку, которая переводит данное название в нужное склонение, или написать функцию, которая это будет делать в коде. Я этого здесь делать не стал. Но, для использования на реальных датах, думаю, что может понадобиться.

В прикрепленных файлах, если понадобиться, шаблон документа и json с данными. Чтобы можно было попробовать сразу, как работает скрипт.

А на это, пожалуй, все.

Спасибо за внимание. Надеюсь, что данная информация будет полезна
 

Вложения

  • files.zip
    15,9 КБ · Просмотры: 367

Dmitrii Ivanov

New member
09.04.2023
1
1
BIT
0
Спасибо за материал. Недавно нудно было заполнить кучу однотипных документов. В итоге пришел к тому, что эта функция есть и в самом MS Word, причем реализована достаточно хорошо. Нужный функционал во Вкладке "рассылка"
 
  • Нравится
Реакции: solovievv

aiden1973

New member
04.05.2023
1
0
BIT
0
Здравствуйте. Подскажите, пожалуйста, где найти измененный файл после срабатывания скрипта?
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!