Автоматизация индивидуальной нарезки файлов Excel и распространения их с помощью Pandas и Outlook

Мне нравится, когда получая отзывы от читателей этого блока в части заметок о Python и ресурса «Python — курс молодого бойца» для студентов ЮУрГУ по направлению Бизнес-информатика, я убеждаюсь в полезности своих материалов. Меня всегда удивляют примеры, в которых всего несколько строк кода Python решают реальную бизнес-задачу и экономят массу времени и денег. А люди, которые делают это без формального обучения и добиваются результата только довольно тяжелой работой и готовностью упорно наращивать свои компетенции вызывают уважение.

Вот один из таких примеров. Начнём с предыстории нашего выпускника бакалавриата:

Я использую (изучаю) Python около 3 лет исключительно для автоматизации бизнес-процессов и составления отчетность в своей конторе. У меня не было специальных курсов Python и в те времена, когда я учился в университете про Python нам не рассказывали. Однако, со временем я понял, что это надежный инструмент, который частенько помогает мне в работе.

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

Вот проблема:

Есть бизнес-потребность в рассылке электронных писем с вложениями Excel по списку из ~500 клиентов, что поставило нас перед большой задачей, которую всегда решали вручную. Эта задача усложнялась тем, что надо разделять данные между клиентами из основного файла Excel, чтобы создать для каждого собственный конкретный файл, а затем отправлять этот файл по электронной почте. Представьте себе время, которое потребуется для ручной фильтрации, нарезки нужных для клиента строк и вставки их в персональный файл, а затем сохранить его и отправить по электронной почте -500 раз! Python помог мне автоматизировать весь процесс и сэкономить драгоценное время.

На своем опыте я неоднократно сталкивался с подобными проблемами. Если у вас нет опыта программирования, это может показаться сложным. Этот утомительный процесс вполне реально автоматизировать с Python. Иллюстрацию процесса можете посмотреть на рисунке в заголовке статьи.

Решение проблемы

Первый шаг — импорт:

import datetime
import os
import shutil
from pathlib import Path
import pandas as pd
import win32com.client as win32

Теперь запишем несколько строк для формирования своей структурой каталогов с учетом текущей даты:

## Установить формат даты
today_string = datetime.datetime.today().strftime('%m%d%Y_%I%p')
today_string2 = datetime.datetime.today().strftime('%b %d, %Y')

## Установка имен папок для вложений и архивирования
attachment_path = Path.cwd() / 'data' / 'attachments'
archive_dir = Path.cwd() / 'archive'
src_file = Path.cwd() / 'data' / 'Example4.xlsx'

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

df = pd.read_excel(src_file)
df.head()

Следующий шаг — сгруппировать все транзакции, относящиеся к клиентам по их CUSTOMER_ID, вместе. Начнем с создания группы по CUSTOMER_ID.

customer_group = df.groupby('CUSTOMER_ID')

Вам может быть не очевидно, что такое customer_group в этом случае. Цикл показывает, как мы можем обработать этот сгруппированный объект:

for ID, group_df in customer_group:
    print(ID)

Вот и получились группы:

A1000
A1001
A1002
A1005

Вот последний файл group_df, который показывает все транзакции для клиента A1005:

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

## Запишите каждый идентификатор, группу в отдельные файлы Excel и используйте идентификатор,
## чтобы назвать каждый файл с сегодняшней датой
attachments = []
for ID, group_df in customer_group:
    attachment = attachment_path / f'{ID}_{today_string}.xlsx'
    group_df.to_excel(attachment, index=False)
    attachments.append((ID, str(attachment)))

Список вложений содержит идентификатор клиента и полный путь к файлу:

[('A1000',
'c:\\Users\\chris\\notebooks\\2020-10\\data\\attachments\\A1000_01162021_12PM.xlsx'),
('A1001',
'c:\\Users\\chris\\notebooks\\2020-10\\data\\attachments\\A1001_01162021_12PM.xlsx'),
('A1002',
'c:\\Users\\chris\\notebooks\\2020-10\\data\\attachments\\A1002_01162021_12PM.xlsx'),
('A1005',
'c:\\Users\\chris\\notebooks\\2020-10\\data\\attachments\\A1005_01162021_12PM.xlsx')]

Чтобы упростить обработку, мы преобразуем список в DataFrame:

df2 = pd.DataFrame(attachments, columns=['CUSTOMER_ID', 'FILE'])

Заключительный этап подготовки данных — это создание списка файлов с адресами для их рассылки по электронной почты путем объединения DataFrame:

email_merge = pd.merge(df, df2, how='left')
combined = email_merge[ ['CUSTOMER_ID', 'EMAIL', 'FILE'] ].drop_duplicates()

Вот получился объединенный DataFrame:

Мы собрали список клиентов с их адресами электронной почты и именами прикрепляемых файлов. Теперь нам нужно отправить электронное письмо с помощью почтового клиента, например, Outlook. Обратитесь к этой статье за ​​дополнительным объяснением этого кода:

# Отправка индивидуальных отчетов по электронной почте соответствующим получателям
class EmailsSender:
    def __init__(self):
        self.outlook = win32.Dispatch('outlook.application')

    def send_email(self, to_email_address, attachment_path):
        mail = self.outlook.CreateItem(0)
        mail.To = to_email_address
        mail.Subject = today_string2 + ' Report'
        mail.Body = """Please find today's report attached."""
        mail.Attachments.Add(Source=attachment_path)
        # Используйте это, чтобы показать электронную почту
        #mail.Display(True)
        # Раскомментировать для отправки
        #mail.Send()

Мы можем использовать этот простой класс EmailsSender для создания электронных писем и прикрепления файла Excel.

email_sender = EmailsSender()
for index, row in combined.iterrows():
    email_sender.send_email(row['EMAIL'], row['FILE'])

Кроме того, рекомендую проработать урок Как отправлять электронные письма с Python, если вместо почтового клиента локального компьютера Outlook захотите использовать почтовые сервера Google или Yandex.

Последний шаг — переместить файлы в наш архивный каталог:

# Переместить файлы в архив
for f in attachments:
    shutil.move(f[1], archive_dir)

Резюме

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

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

Использованы материалы Case Study: Automating Excel File Creation and Distribution with Pandas and Outlook

Print Friendly, PDF & Email

CC BY-NC 4.0 Автоматизация индивидуальной нарезки файлов Excel и распространения их с помощью Pandas и Outlook, опубликовано К ВВ, лицензия — Creative Commons Attribution-NonCommercial 4.0 International.


Респект и уважуха

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