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

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

Если проводить эту операцию вручную, то придется потратить достаточное количество своего времени, а если файл будет содержать информацию не о 10 клиентах, как в моем случае, а о 1000, то это уже будет огромной проблемой. Но ее можно будет решить с помощью Python. Первым делом, как всегда, необходимо выполнить импорт библиотек (некоторые из них необходимо будет установить через pip):

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

Далее, в папке с проектом мы создаем несколько папок, а именно: archive и data, в которую кладем файл с исходными данными, в моем случае – customers.xlsx и в ней же создаем папку attachments, в которую у нас будут сохраняться наши новые файлы. После этого пишем следующий код:

## Установить формат даты
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' / 'customers.xlsx'
Давайте посмотрим на основной файл данных, который нужно обработать и который является источников множества файлов для клиентов:
df = pd.read_excel(src_file)
df.head()

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

customer_group = df.groupby('CUSTOMER_ID')
for ID, group_df in customer_group:
    print(ID)

Результат:

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

## Запишите каждый идентификатор, группу в отдельные файлы 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)))
df2 = pd.DataFrame(attachments, columns=['CUSTOMER_ID', 'FILE'])

Результат:


В ходе всех этих проделанных действий мы собрали список клиентов с их адресами электронной почты и именами прикрепляемых файлов. Теперь нам нужно отправить электронное письмо с помощью почтового клиента. Лично я, буду использовать 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'])

Результат:

Ну и завершающим этапом будет перемещение всех этих созданных файлов в архивный каталог:

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

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

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

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