Code

【Python】win32comでExcel操作する方法

Pythonのwin32comライブラリーでExcel操作する方法をまとめた記事です。

前半は基本的なコードの書き方、後半は実践的なサンプルコードを紹介します。

なお、win32comはWindows環境かつExcelインストール済み環境でのみ動作します。

Macなどで動かしたい場合はxlwingsやopenpyxlなどを使うことになりますのでご注意ください。

コードはExcel VBAが基本になっているので、書き方を体系的に学びたい方はパーフェクトExcel VBAがおすすめ。

【基本編】コードの書き方

win32comでExcel操作をするための基本的なコードを紹介します。

なお、win32comでは大文字・小文字を区別するのでご注意ください。

win32comライブラリのインストール

一般的なライブラリ同様、win32comもpip installでインストールできます。

pip install pywin32

コマンドプロンプト上で上記のコードを実行することで、Outlook操作に必要なwin32comライブラリのインストールができます。

なお、冒頭でもご説明の通りwin32comはWindowsのみ対応です。MacOS等をお使いの場合はxlwingsやopenpyxlなどを使います。

import/Excel Appのインスタンス化

import win32com.client

# ExcelAppのインスタンス化
excel = win32com.client.Dispatch("Excel.Application")
# バックグラウンド
excel.Visible = False
# 警告非表示
excel.DisplayAlerts = False

VisibleFalseにするとExcelの画面を表示されなくなるため、誤作動を防ぎたい場合に有効です。逆に挙動を確認したい場合はTrueにします。

また、「ブックを保存しますか?」などの警告を出したくない場合はDisplayAlertsFalseにします。

ブックを開く

# ブックを開く
wb = excel.Workbooks.Open(book_path)

既存のブックを操作する場合には、まずブックを開きます。

ここで作成した変数wbは、シートをセットする際に使います。

シートをセット

# シートをセット
ws = wb.Worksheets(sheet_name)

sheet_nameには操作したいシート名を文字列で渡せばOKです。

セル番地で値を取得・入力

# 値を入力
ws.Range("A1").Value = "A1に入力"
# 値を取得
var = ws.Range("A1").Value

セル番地を指定して値を出し入れする場合はRangeメソッドを使います。

行・列番号で値を取得・入力

# 値を入力
ws.Cells(1, 1).Value = "A1に入力"
# 値を取得: A2セル
var = ws.Cells(2, 1).Value

変数で操作するセルを可変的にしたい場合はCellsの方が扱いやすいです。

関数の入力

# 関数を入力
ws.Range("A1").Formula = "=SUM(A2:A10)"

Valueを使ってしまうと文字列が入ってしまうのでFormulaを使います。

最終行の取得

# 最終行を取得(1列目)
endRow = ws.Cells(ws.Rows.Count, 1).End(-4162).Row

Cellsの第二引数(列番号)を1としているので、1列目の最終行を取得します。

なお-4162は何かというと、Ctrlを押したままキーを押す挙動を表します。(VBAでいうところのxlUp

今回は最終行の取得なのでキーにしましたが、他の番号が知りたい方はWindowsの公式ドキュメントを参照してみてください。

セル範囲をリストに格納

# 空のリストを用意
array = []
# A1からB4セルをリストとして取得
array = ws.Range("A1:B4").Value

# リスト化
array = [list(map(int, row)) for row in array]

リストの中身はタプルになるので、純粋なリストに直す場合はリスト内包表記などで対応します。

最終行の取得と組み合わせるのも有効です。

すべてのセルをリストに格納

# すべてのセルをリストに格納
array = ws.UsedRange.Value

セル範囲を指定せずにすべてのセルを取得する場合は、UseRangeが使えます。

とはいえこの方法はごっそりと取得してきてしまって使いづらいので、Pandasのread_excelの方が扱いやすいです。

すべてのシートをA1セル選択状態にする

### すべてのシートをA1セル選択状態にする
# シート数を取得
sheet_num = wb.Worksheets.Count
# 後ろのシートから順に開く
for i in range(sheet_num, 0, -1):
    ws = wb.Worksheets(i)
    # シートをアクティブにする
    ws.Activate
    # A1セルをアクティブにする
    ws.Cells(1, 1).Activate

列幅を自動調整

# 列幅を自動調整
ws.Columns("A:G").AutoFit()

列を隠す

# 列を隠す
ws.Columns("A:G").EntireColumn.Hidden = False

シートを追加

# 新しいシートを追加する
wb.Sheets.Add()

指定したシートの前にシートを追加

# wsの前に新規シートを追加
excel.Sheets.Add(Before=ws)

指定したシートの後にシートを追加

# wsの後に新規シートを追加
excel.Sheets.Add(Before=None, After=ws)

余談ですが、excel.Sheets.Add(After=ws)のようにBeforeを省略すると動作しません。

このようにwin32comでは名前つき引数が正常に動作しないことがあります。

シートの削除

# wsを削除
ws.Delete()

シート名の変更

# wsのシート名を変更
ws.Name = "new_name"

ブックを上書き保存する

# 上書き保存
wb.Save()

ブックを名前をつけて保存

# 名前をつけて保存
wb.SaveAs(output_path)

ブックを閉じる

# ブックを閉じる
wb.Close()

シートをPDF化する

# wsをPDF化する
ws.ExportAsFixedFormat(0, output_path)

複数シートをPDF化する

# sheet1,sheet2を選択する
wb.Worksheets(["sheet1", "sheet2"]).Select()
# 選択したシートをPDF化する
wb.ActiveSheet.ExportAsFixedFormat(0, output_path)

PDF化したいシートを選択した状態でExportAsFixedFormatを使います。

全シートをPDF化する

# 空のリストを準備
array = []
# 全シートをsheet_listに格納
for sheet_name in wb.Sheets:
    array.append(sheet_name)

# 全シートを選択
wb.Worksheets(array).Select()
# 選択されたシートをPDF化
wb.ActiveSheet.ExportAsFixedFormat(0, output_path)

すべてのシートをPDF化する場合も考え方は同じです。

【実践編】サンプルコード

【基本編】で紹介したコードを使ったサンプルコードを公開します。

「こんなサンプルコードを掲載してほしい!」という要望がありましたらコメント欄に書き込みをお願いいたします!

ブック内の全シートをPDF化する

import getpass
import win32com.client

user_name = getpass.getuser()
book_path = rf"/Users/{user_name}/Desktop/excel.xlsx"
sheet_name = r"sheet1"

# ExcelAppのインスタンス化
excel = win32com.client.Dispatch("Excel.Application")
excel.Visible = False
excel.DisplayAlerts = False

# ブック、シートのセット
wb = excel.Workbooks.Open(book_path)
ws = wb.Worksheets(sheet_name)

# 空のリストを準備
array = []
# 全シートをsheet_listに格納
for sheet_name in wb.Sheets:
    array.append(sheet_name)

# 全シートを選択
wb.Worksheets(array).Select()
# 選択されたシートをPDF化
wb.ActiveSheet.ExportAsFixedFormat(0, output_path)

# ブックを閉じる
wb.Close()
# Excel Appを終了
excel.Quit()

まとめ

Windows以外のOSでは使えないというデメリットはあるものの、動作の安定性としてはwin32comが一番だと思います。

より高速な動作を求めるならopenpyxlを、Macで安定した動作を求めるならxlwingsの導入も検討してみてください。

COMMENT

メールアドレスが公開されることはありません。