Pythonを使用してMicrosoft ExcelとWordを自動連係(2/3)

調査研究

1.Pythonを使用してMicrosoft ExcelとWordを自動連係(2/3)まとめ

・WindowsAPIを使ってExcelを起動してExcel内のグラフを画像として保存する方法
・pywin32(win32com.client)を使って表ありWordを自動生成したサンプルコードもあり
・WordがなくてもGoogleドキュメントから.docxとしてダウンロードする事でひな形は作れる

2.PythonからWindow API経由でExcelとWordを操作

以下、www.kdnuggets.comより「Automate Microsoft Excel and Word Using Python」の意訳です。元記事の投稿は2021年8月、Mohammad Khorasaniさんによる投稿です。

前回からの続きで
2)WindowsAPIを使ってExcelを起動してグラフを画像として保存する
の部分です。Microsoft Excel 2007以降がインストールされているWindows上でないと動かせません。WindowsのAnaconda環境で動かせる事を確認済です。

繰り返しになりますが、Anaconda環境で動かすためにはリポジトリにconda-forgeを追加して以下のパッケージをインストールする必要があります。
openpyxl 3.0.7
python-docx 0.8.9
pywin32 301
docxtpl 0.9.2
pillow 8.3.1

アイキャッチ画像のクレジットはPhoto by Mohammad Rezaie on Unsplash

チャートの抽出

グラフを生成したので、Wordレポートで使用できるように、グラフを画像として抽出する必要があります。 まず、Excelファイルの正確な場所と、出力されたグラフを画像として保存する場所を宣言します。


# 前回作成したExcelファイルがアカウントdev1のデスクトップ上に
# テストエクセルワークブック.xlsxと言う名称で置いてある前提なので
# パスは適宜書き換えてください

input_file = "C:/Users/dev1/Desktop/テストエクセルワークブック.xlsx"
output_image = "C:/Users/dev1/Desktop/chart.png"

その後、スプレッドシート内のすべてのグラフ オブジェクトを繰り返し処理(複数ある場合)し、次のように指定した場所にchart.pngとして保存できます。


import win32com.client
import PIL
from PIL import ImageGrab, Image

operation = win32com.client.Dispatch("Excel.Application")
operation.Visible = 0
operation.DisplayAlerts = 0
workbook_2 = operation.Workbooks.Open(input_file)
sheet_2 = operation.Sheets(1)

for x, chart in enumerate(sheet_2.Shapes):
    chart.Copy()
    image = ImageGrab.grabclipboard()
    image.save(output_image, 'png')

workbook_2.Close(True)
operation.Quit()

Webbigdataによるおまけ:

以下が、次回ひな形として使うWordファイルの内容です。Wordなんて持ってないぜ~、と言う方でも、以下をGoogle ドキュメントにコピペして、「ファイル」→「ダウンロード」→「Microsoft Word(.docx)」にすると、見栄えはヒドイ有様になりますが、動かせる事は確認済です。

——ひな形開始——

{{title}}
{{year}}/{{month}}/{{day}}

項番電力電流電圧

{%tr for item in table_contents %}

{{item.index}}{{item.power}}{{item.current}}{{item.voltage}}
{%tr endfor %}

{{image}}

——ひな形終了——

更に、上記のひな形をpywin32(win32com.client)を使って自動生成するサンプルコードが以下です。動かすにはWordがインストールされているWindows環境が必要です。pythonでwordやexcelを扱うパッケージは幾つかありますが、pywin32はVBAのコードをほぼそのまま参考に出来るので、「VBA word ~」で検索すると何らかのヒントが見つかる事が多いという利点があります。


import win32com.client

operation = win32com.client.Dispatch("Word.Application")
operation.Visible = 0
operation.DisplayAlerts = 0

objDoc = operation.Documents.Add()
objDoc.Content.InsertAfter(Text="{{title}}\r\n")
objDoc.Content.InsertAfter(Text="{{year}}/{{month}}/{{day}}\r\n")

# 末尾!
myRange = objDoc.Range(objDoc.Characters.Count -1 , objDoc.Characters.Count - 1)

# 表
tblNew = objDoc.Tables.Add(Range=myRange, NumRows=4, NumColumns=4)
tblNew.Cell(1, 1).Range.InsertAfter("項番")
tblNew.Cell(1, 2).Range.InsertAfter("電力")
tblNew.Cell(1, 3).Range.InsertAfter("電流")
tblNew.Cell(1, 4).Range.InsertAfter("電圧")

# セルの結合
tblNew.Cell(2, 1).Merge(MergeTo=tblNew.Cell(2, 4))
tblNew.Cell(2, 1).Range.InsertAfter("{%tr for item in table_contents %}")

# セルの配置を中央にする wdAlignParagraphCenter = 1 本当は定数を読み込む
tblNew.Cell(2, 1).Range.ParagraphFormat.Alignment = 1

tblNew.Cell(3, 1).Range.InsertAfter("{{item.index}}")
tblNew.Cell(3, 2).Range.InsertAfter("{{item.power}}")
tblNew.Cell(3, 3).Range.InsertAfter("{{item.current}}")
tblNew.Cell(3, 4).Range.InsertAfter("{{item.voltage}}")

tblNew.Cell(4, 1).Merge(MergeTo=tblNew.Cell(4, 4))
tblNew.Cell(4, 1).Range.InsertAfter("{%tr endfor %}")

objDoc.Content.InsertAfter(Text="\r\n{{image}}\r\n")
objDoc.SaveAs2("C:/Users/dev1/Desktop/テストワード2.docx")
operation.Quit()

 

3.Pythonを使用してMicrosoft ExcelとWordを自動化(2/3)まとめ

1)www.kdnuggets.com
Automate Microsoft Excel and Word Using Python

2)openpyxl.readthedocs.io
openpyxl – A Python library to read/write Excel 2010 xlsx/xlsm files

3)github.com
pywin32

4)python-docx.readthedocs.io
python-docx — python-docx 0.8.11 documentation

5)docxtpl.readthedocs.io
Welcome to python-docx-template’s documentation!

タイトルとURLをコピーしました