Автоматизация для приложений Windows с помощью COM

Введение

Python имеет множество возможностей для создания стандартных типов файлов Microsoft Office, включая Excel, Word и PowerPoint. Однако в некоторых случаях может оказаться слишком сложно использовать чистый подход Python для решения проблемы. К счастью, для python есть пакет “Python for Windows Extensions” (Python для расширений Windows), известный как pywin32, который позволяет нам легко получить доступ к Component Object Model (COM), компонентной объектной модели Windows, и управлять приложениями Microsoft через python. В этой статье будут рассмотрены некоторые базовые сценарии использования этого типа автоматизации и рассказывается о том, как приступить к работе с некоторыми полезными скриптами.

Что такое COM?

С веб-сайта Microsoft о модели компонентных объектов (COM):

Платформенно-независимая распределенная объектно-ориентированная система для создания двоичных программных компонентов, которые могут взаимодействовать. COM является базовой технологией для технологий Microsoft OLE Automation (составные документы) и ActiveX (компоненты с доступом в Интернет). COM-объекты могут быть созданы с помощью множества языков программирования.

Эта технология позволяет нам управлять приложениями Windows из другой программы. Многие из читателей этого блога, вероятно, видели или использовали VBA для некоторой автоматизации задачи Excel. COM — это основополагающая технология, поддерживающая VBA.

pywin32

Пакет pywin32 существует уже очень давно. Фактически, книга, посвященная этой теме, была опубликована в 2000 году Марком Хаммондом и Энди Робинсоном. Несмотря на то, что с тех пор уже прошло много лет (что заставляет меня чувствовать себя действительно старым), лежащие в основе технологии и концепции работают и сегодня. Pywin32 — это, по сути, очень тонкая оболочка python, которая позволяет нам взаимодействовать с COM-объектами и автоматизировать приложения Windows с помощью python. Сила этого подхода заключается в том, что вы можете делать практически все, что может делать приложение Microsoft, через python. Обратной стороной является то, что вам придется запускать это в системе Windows с установленным Microsoft Office. Прежде чем мы рассмотрим несколько примеров, убедитесь, что в вашей системе установлен pywin32 с помощью pip или conda.

Еще одна рекомендация: держите под рукой ссылку на страницу Тима Голдена. На этом ресурсе есть еще много подробностей о том, как использовать python в Windows для автоматизации и других административных задач.

Начиная

Все наши приложения начинаются с одинакового импорта и процесса активации приложения. Вот очень короткий пример открытия Excel:

import win32com.client as win32
excel = win32.gencache.EnsureDispatch('Excel.Application')

excel.Visible = True
_ = input("Press ENTER to quit:")

excel.Application.Quit()

Как только вы запустите скрипт из командной строки, то должны увидеть, как открывается Excel. Когда вы нажмете ENTER, приложение закроется. Прежде чем мы действительно сделаем это приложение более полезным, необходимо изучить несколько ключевых концепций.

Первый шаг — импортировать клиента win32. Я использовал соглашение об импорте его как win32, чтобы сделать фактический код отправки немного короче.

Магия этого кода заключается в использовании EnsureDispatch для запуска Excel. В этом примере я использую gencache.EnsureDispatch для создания статического прокси. Я рекомендую прочитать эту статью, если вы хотите узнать больше о статических и динамических прокси. Мне посчастливилось использовать этот подход для примеров, включенных в эту статью, но буду честен — я не слишком много экспериментировал с различными подходами к диспетчеризации.

Теперь, когда объект excel запущен, нам нужно явно сделать его видимым, установив excel.Visible = TrueКод.

win32 довольно умен и закроет Excel после завершения работы программы. Это означает, что если мы просто оставим код работать самостоятельно, вы, вероятно, не увидите Excel. Я включаю фиктивную подсказку, чтобы Excel оставался видимым на экране, пока пользователь не нажмет ENTER.

Я включаю последнюю строку excel.Application.Quit(), как немного ремня и подтяжек. Строго говоря, win32 должен закрыть Excel, когда программа будет завершена, но я решил включить excel.Application.Quit(), чтобы показать, как принудительно закрыть приложение.

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

Открыть файл в Excel

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

Вот полный пример:

import win32com.client as win32
import pandas as pd
from pathlib import Path

# Read in the remote data file
df = pd.read_csv("https://github.com/chris1610/pbpython/blob/master/data/sample-sales-tax.csv?raw=True")

# Define the full path for the output file
out_file = Path.cwd() / "tax_summary.xlsx"

# Do some summary calcs
# In the real world, this would likely be much more involved
df_summary = df.groupby('category')['ext price', 'Tax amount'].sum()

# Save the file as Excel
df_summary.to_excel(out_file)

# Open up Excel and make it visible
excel = win32.gencache.EnsureDispatch('Excel.Application')
excel.Visible = True

# Open up the file
excel.Workbooks.Open(out_file)

# Wait before closing it
_ = input("Press enter to close Excel")
excel.Application.Quit()

Вот результат в Excel:

Этот простой пример расширяет предыдущий, показывая, как использовать объект Workbooks для открытия файла.

Прикрепите файл Excel к Outlook

Другой простой сценарий, в котором полезен COM, — это когда вы хотите прикрепить файл к электронному письму и отправить его в список рассылки. В этом примере показано, как выполнять некоторые манипуляции с данными, открывать электронную почту Outlook,прикрепите файл и оставьте его открытым для дополнительного текста перед отправкой.

Вот полный пример:

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


to_email = """
Lincoln, Abraham <>; 
"""

cc_email = """
Franklin, Benjamin <>
"""

# Read in the remote data file
df = pd.read_csv("https://github.com/chris1610/pbpython/blob/master/data/sample-sales-tax.csv?raw=True")

# Define the full path for the output file
out_file = Path.cwd() / "tax_summary.xlsx"

# Do some summary calcs
# In the real world, this would likely be much more involved
df_summary = df.groupby('category')['ext price', 'Tax amount'].sum()

# Save the file as Excel
df_summary.to_excel(out_file)

# Open up an outlook email
outlook = win32.gencache.EnsureDispatch('Outlook.Application')
new_mail = outlook.CreateItem(0)

# Label the subject
new_mail.Subject = "{:%m/%d} Report Update".format(date.today())

# Add the to and cc list
new_mail.To = to_email
new_mail.CC = cc_email

# Attach the file
attachment1 = out_file

# The file needs to be a string not a path object
new_mail.Attachments.Add(Source=str(attachment1))

# Display the email
new_mail.Display(True)

Этот пример немного усложняется, но основные концепции те же. Нам нужно создать наш объект (в данном случае Outlook) и создать новое электронное письмо. Одним из сложных аспектов работы с COM является отсутствие согласованного API. Создание такого электронного письма не является интуитивным: new_mail = outlook.CreateItem (0) Обычно требуется немного поисков, чтобы выяснить точный API для конкретной проблемы. Google и stackoverflow — ваши друзья.

После создания объекта электронной почты вы можете добавить получателя и список CC, а также прикрепить файл. Когда все сказано и сделано, это выглядит так:

Электронное письмо открыто, и вы можете добавить дополнительную информацию и отправить ее. В этом примере я решил не закрывать Outlook и позволить python обрабатывать эти детали.

Последний пример является наиболее сложным, но иллюстрирует мощный подход к объединению анализа данных Python с пользовательским интерфейсом Excel.

С помощью pandas можно создать сложный Excel, но такой подход может быть очень трудоемким. Альтернативным подходом было бы создание сложного файла в Excel, затем выполните манипуляции с данными и скопируйте вкладку данных в окончательный вывод Excel.

Вот пример панели инструментов Excel, которую мы хотим создать:

Да, я знаю, что круговые диаграммы ужасны, но я могу почти гарантировать, что кто-то попросит вас поместить их на панель инструментов в какой-то момент! Кроме того, в этом шаблоне была круговая диаграмма, и я решил оставить ее в окончательном виде вместо того, чтобы пытаться вычислить другую диаграмму. Было бы полезно сделать шаг назад и посмотреть на основной процесс, которому будет следовать код:

Приступим к работе с кодом.

import win32com.client as win32
import pandas as pd
from pathlib import Path

# Read in the remote data file
df = pd.read_csv("https://github.com/chris1610/pbpython/blob/master/data/sample-sales-tax.csv?raw=True")

# Define the full path for the data file file
data_file = Path.cwd() / "sales_summary.xlsx"

# Define the full path for the final output file
save_file = Path.cwd() / "sales_dashboard.xlsx"

# Define the template file
template_file = Path.cwd() / "sample_dashboard_template.xlsx"

В этом разделе мы выполнили импорт, прочитали данные и определили все три файла. Следует отметить, что этот процесс включает в себя этап суммирования данных с помощью pandas и сохранения данных в файле Excel. Затем мы повторно открываем этот файл и копируем данные в шаблон. Это немного запутано, но это лучший подход, который я мог придумать для этого сценария.

Далее выполняем анализ и сохраняем временный файл Excel:

# Do some summary calcs
# In the real world, this would likely be much more involved
df_summary = df.groupby('category')['quantity', 'ext price', 'Tax amount'].sum()

# Save the file as Excel
df_summary.to_excel(data_file, sheet_name="Data")

Теперь мы используем COM, чтобы объединить временный выходной файл с нашей вкладкой панели управления Excel и сохранить новую копию:

# Use com to copy the files around
excel = win32.gencache.EnsureDispatch('Excel.Application')
excel.Visible = False
excel.DisplayAlerts = False

# Template file
wb_template = excel.Workbooks.Open(template_file)

# Open up the data file
wb_data = excel.Workbooks.Open(data_file)

# Copy from the data file (select all data in A:D columns)
wb_data.Worksheets("Data").Range("A:D").Select()

# Paste into the template file
excel.Selection.Copy(Destination=wb_template.Worksheets("Data").Range("A1"))

# Must convert the path file object to a string for the save to work
wb_template.SaveAs(str(save_file))

Код открывает Excel и удостоверяется, что его не видно. Затем он открывает шаблон панели мониторинга и файлы данных. Он использует Range("A: D").Select() для выбора всех данных, а затем копирует их в файл шаблона.

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

Заключение

Я предпочитаю стараться как можно больше придерживаться python для повседневного анализа данных. Однако важно знать, когда другие технологии могут упростить процесс или повысить эффективность результатов. Технология Microsoft COM является зрелой технологией, и ее можно эффективно использовать через Python для выполнения задач, которые в противном случае были бы слишком сложными. Надеюсь, эта статья дала вам несколько идей о том, как включить эту технику в свой рабочий процесс. Если у вас есть какие-либо задачи, для которых вы хотите использовать pywin32, сообщите нам об этом в комментариях.

По материалам Automating Windows Applications Using COM

Print Friendly, PDF & Email

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


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

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