Заполнение word документа python

Автоматическое заполнение файлами документов Word и подписей к ним с помощью Python и библиотеки docx

Рассмотрим пример простой программы на Python с помощью библотекы docx для автоматизации рабочего процесса, а именно автоматической вставки файлов (в данном случае изображений) и их подпись в документах Word (docx).

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

Я опишу свой максимально дубовый и непрофессиональный но простой код который Вы сможете повторить в своих проектах. (Полный код в низу статьи).

Цель

В жизни каждого инженера или аналитика или другого специалиста, наступает момент, когда нужно оформлять отчет. Часто это осциллограммы, графики, ВАХ или другие графические изображения. Отчет нужно оформить в вордовском файле, с приведением изображений и их подписью. Делать вручную это очень увлекательно и интересно долго, неэффективно, скучно и другие синонимы к етим словам.

Рассмотрим простой способ вставки изображений и их подписью в файл docx с помощью Python.

Начало написания программы

Сначала нам нужно добавить библиотеку docx для работы с файлами Word.

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

folder_doc = r'D:\PITON\Project' # Папка в которой docx файл name_doc = '\Report.docx' # Название doc файла folder_png = 'D:\PITON\Project\Png' # Папка в которой находятся графики

Далее добавим объект doc из библиотеки и укажем путь к файлу с названием документа.

doc = docx.Document(folder_doc + name_doc) # Указываем параметры которые задавали в коде раньше (путь и имя)

Формируем последовательность вставки файлов

Исходя из названия файлов (изображений) нам нужно определить в какой последовательности мы будем вставлять изображения в Word.
В моем случае ето: Test_number1_Outside_humidity_10_Outside_temperature_25. Отличие в названии файлов есть в числах возле названия параметра (их мы и будем менять в коде для автоматического заполнения файла).
Создаем массивы с значениями этих чисел:

test_number = [1, 2, 3, 4, 5] # Указываем номер теста outside_humidity = [10, 20, 30, 40, 50, 60, 70, 80, 90] # Указываем влажность outside_temperature = [25, 50, 75, 100] # Указываем температуру

Основная часть программы

После того как мы разобрались с тем, как мы будем идентифицировать изображение для последующей вставки, нам необходимо определиться в порядке в котором будут идти изображения. У меня все картинки будут идти в таком порядке: test_number, outside_humidity, outside_temperature. Вы же можете сделать произвольный порядок.

Для этой реализации используем цикл for , который будет перебирать все значение из массива по очереди.

for r in range(len(test_number)): for d in range(len(outside_humidity)): for i in range(len(outside_temperature)):

Далее стандартными средствами библиотеки добавляем картинки в файл и создаем подписи.
doc.add_picture — добавляет изображения в файл Word
folder_png — это путь к папке которую мы указывали вверху кода
После этого мы указываем точное название файлов в папке, но вместо значений которые меняются вставляем в фигурные скобки.
В функции .format указываем те значения переменных которые меняются в каждом файле и которые мы внесли в цикле for . Эти значения будут применяться к каждому файлу, где мы указывали фигурные скобки (в той же последовательности).

Для подписи файла используем такой же алгоритм.
doc.add_paragraph — используем для записи параграфу
doc.add_paragraph(» «) — делаем отступ

doc.add_picture(folder_png + '/Test_number<>_Outside_humidity_<>_Outside_temperature_<>.png' .format(test_number[r],outside_humidity[d], outside_temperature[i])) doc.add_paragraph("Figure <>, Test number <>, Outside humidity = <> %, Outside temperature = <> C;" .format(i + 1, test_number[r], outside_humidity[d], outside_temperature[i])) doc.add_paragraph(" ")
doc.save(folder_doc + name_doc)

Меняем параметры изображения

Изображение будем вставлять размером 13.33 х 10 см, для этого воспользуемся дополнительными возможностями библиотеки docx.
Сначала напишем функцию которая будет конвертировать размер с inch в см.

def inch_to_cm(value): return value / 2.54

Теперь добавим данные параметры к основному коду:

doc.add_picture(folder_png + '/Test_number<>_Outside_humidity_<>_Outside_temperature_<>.png' .format(test_number[r],outside_humidity[d], outside_temperature[i]), width=docx.shared.Inches(inch_to_cm(13.330)), height=docx.shared.Inches(inch_to_cm(9)))

Результат

В данной папке находится 180 изображений:

После запуска кода с помощью Python, в течение 5 секунд мы получаем следующий результат:

Вывод

Имея структурированные данные на базе данного кода с помощью Python и библиотеки docx можно в течение 10 минут написать свой код, который в течение нескольких секунд сделает всю грязную работу за Вас.

Разве не для этого придумывали компьютер?

Полный код программы

import docx folder_doc = r'D:\PITON\Project' # Папка в которой docx файл name_doc = '\Report.docx' # Название doc файла folder_png = 'D:\PITON\Project\Png' # Папка в которой находятся графики doc = docx.Document(folder_doc + name_doc) # Указываем параметры которые задавали в коде раньше (путь и имя файла) test_number = [1, 2, 3, 4, 5] # Указываем номер теста outside_humidity = [10, 20, 30, 40, 50, 60, 70, 80, 90] # Указываем влажность outside_temperature = [25, 50, 75, 100] # Указываем температуру def inch_to_cm(value): return value / 2.54 # Конвертируем в см for r in range(len(test_number)): for d in range(len(outside_humidity)): for i in range(len(outside_temperature)): # Test_number1_Outside_humidity_10_Outside_temperature_25 doc.add_picture(folder_png + '/Test_number<>_Outside_humidity_<>_Outside_temperature_<>.png'.format(test_number[r],outside_humidity[d], outside_temperature[i]), width=docx.shared.Inches(inch_to_cm(13.330)), height=docx.shared.Inches(inch_to_cm(9))) doc.add_paragraph("Figure <>, Test number <>, Outside humidity = <> %, Outside temperature = <> C;" .format(i + 1, test_number[r], outside_humidity[d], outside_temperature[i])) doc.add_paragraph(" ") doc.save(folder_doc + name_doc)

Источник

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

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

000-1.jpg

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

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

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

screenshot1.png

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

screenshot2.png

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

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.

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

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. Выводим принт, чтобы не было скучно. Он тут больше для декорации.

 for usr in user: print(f'\r[+] Заполняю: ', end='') data = <'manager': 'И. С. Иванов', 'reason': 'реструктуризацией и оптимизацией закваски', 'date': dt.strftime(dt.now(), '%d %B %Y'), 'fio': f' ' f'', 'post': usr['post'], 'first_middle': f' ', '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'  .docx'))

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

# 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[+] Заполняю: ', end='') data = <'manager': 'И. С. Иванов', 'reason': 'реструктуризацией и оптимизацией закваски', 'date': dt.strftime(dt.now(), '%d %B %Y'), 'fio': f' ' f'', 'post': usr['post'], 'first_middle': f' ', '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'  .docx')) def main(): filling_doc() print('\n[+] Все записи обработаны') if __name__ == "__main__": main()

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

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

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

Источник

Читайте также:  Cookie setting in php ini
Оцените статью