MENU
\ お問い合わせはこちら! /

【Python × Excel自動化】openpyxlでグラフが消える問題を解決|win32comで書式を保持して操作する方法

Python の Excel 系ライブラリは openpyxl が有名です。

ところが、openpyxl はグラフや罫線などが消えてしまう不具合があり、クライアントワークなどで安全に自動化したい場合はちょっと怖い面も。

そこで便利なのが win32com というライブラリ。

win32com は Excel のマクロと同じくらいの安定性があるので安心です。

注意点としては、Excel (Office)のインストールが必須なことと、openpyxl に比べて速度は遅めな点。

また、macOS では動作しません。
macOS で安全に Excel 操作をしたい場合には xlwings というライブラリを使うことになります。

ちなみに win32com を使うと Outlook の自動化もできます。

今回ご紹介する Excel 操作のコードは、Excel VBA のものとほぼ同じです。

win32comでExcel操作をする流れとサンプルコード

細かい実装方法の前に、win32com を使って Excel を自動化する際の全体像からお見せしたいと思います。

全体の流れは次の通りです。

  1. win32comライブラリのインストール
  2. インポート
  3. Excelアプリケーションの呼び出し
  4. ブックの呼び出し
  5. シートの呼び出し
  6. 自動化したい操作

まずはステップ①として、以下のコードをコマンドプロンプト上(または仮想環境上)で実行して、win32com ライブラリをインストールします。

あとは実装したい内容に即してコードを書いていくだけです。

まずは簡単な例として、A1 セルに「テスト」という文字列を入力して保存するコードをご紹介します。

では、詳細の説明に入っていきます。

事前準備

win32com を使う準備として、大きく3ステップがあります。

  • ライブラリのインストール(コンソール上)
  • インポート
  • Excel APPの呼び出し

お気づきの方もいらっしゃるかもですが、一般的なライブラリの使い方と同じです。

Python 環境は構築済みであることが前提です。

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

プロジェクトの最初に一度だけ、以下のコマンドを実行してください。

もしバージョン管理ツールのpoetryを使いたい場合にはpoetry add pywin32とします。

poetryを使ってみたい!という方は以下の記事も参考にしてみてください。僕は通常pipではなく、poetryを使っています。

ライブラリ名は win32com ではなく、pywin32 なのでお間違いなきよう!

インポート

続いてインポートです。
Excel 自動化の際にはwin32com.clientをインポートしておくと便利です。

上記だけで動かない場合には、追加でpythoncomを呼び出すと動く場合があります。

pythoncom は Python 上から COM オブジェクトを操作するのに必要な機能を提供するものです。その意味では呼び出し必須…とも思えるのですが、なぜか僕の環境では pythoncom なしで動きます。

win32com.client 単体で動かなければ pythoncom を呼び出す、くらいに考えておけば良いと思います。

Excel APP の呼び出し

続いてExcel アプリケーションを呼び出します。

上記の例では Excel アプリケーション呼び出しと同時に、自動処理中の画面の非表示と警告の非表示(「保存しますか?」などと聞かれるダイアログを無効化)を加えています。

こちらは必要に応じて True、False を切り替えてお使いください。

コードの最後には Excel アプリケーションを終了するため、次のコマンドを書いておきます。

終了処理は意外と見落としがちですが、これがないと Excel アプリケーションがバックグラウンドで起動しっぱなしになり、色々不都合が出るので必須です。

途中でエラーが起こりそうなら、finally として Quit 文を追加しておくことも多いです。

ブックの操作

ブック / シートの操作は次のような種類があります。

  • 開く
  • 新規作成
  • 保存
  • 削除
  • 閉じる

ブックを開く

基本の開き方は以下の通りです。

引数を設定することで「パスワード保護」「読み取り専用」「外部参照リンクの更新」などのオプションも細かく指定できます。

詳しくは公式ドキュメントをご参照ください。

公式ドキュメント

ブックを新規作成する

Addをしただけでは実際のファイルは作成されません。
そのため、xlsxファイルとして保存する際にはSaveAsを使います。

ブックを保存する

保存には「上書き保存」と「名前をつけて保存」の2パターンがあります。

SaveAsの場合は保存先のパスを引数に渡します。

ブックを削除する

ブックごと削除する場合はosライブラリのremoveを使います。

ブックを閉じる

開いたファイルは、最終的に閉じましょう。

Save等で保存した後にも忘れずに閉じるようにします。

シートの操作

シート操作には次のようなものがあります。

    • 開く
    • 追加
    • シート名変更
    • 削除
    • 全シートを取得

シートを開く

シート名、またはシート番号から操作したいシートを選択します。

シート番号から指定する場合、一番左のシートは1です。(Pythonのように0始まりではないので注意)

シートを追加する

シートを追加する場合、新しいシートの追加位置を指定します。

あるシートの右側に新しいシートを追加したい場合には、次のように書きます。

ここでBefore=Noneを書かないとうまく動作しないので注意が必要です。

通常は名前付き引数としてAfterとしているので動作するはずですが、win32comでは名前付き引数がうまく機能しないので上記のような配慮が必要になります。

シート名を変更する

シートを追加すると同時にシート名を変更することが多いです。

シートを削除

ブック内の全シートを取得

全シートを取得するには、Worksheetsを使います。

もう少しスッキリ書くならリスト内包表記を使いましょう。

もちろん、if文を組み合わせて条件に応じて操作方法を分けるといった方法も有効です。

セルの操作方法

Excelのセル操作とは、例えば次のようなものです。

  • 値を入力 / 取得する
  • セルの書式設定をする
  • 背景色や文字色などを変更する

コードの書き方としてはそこまで難しいものではないので、一つずつ丁寧に解説していきます。

セルに値を入力する

まずはA1セルに「テスト」という文字列を入力する例を見ていきます。

直感的にわかりやすいのはRangeメソッドを使った方法です。

上記の他に、win32com(VBA)ではCellsメソッドも用意されており、次のように書くとA1セルに「テスト」という文字列を入力できます。

Cellsの第一引数に行番号を、第二引数に列番号を渡します。

直感的にはRangeの方がわかりやすいものの、次のような変数を使って入力先のセルを動的に変化させたい時にはCellsメソッドの方が便利です。

複数セルに値を入力する

特定の範囲内のセルに「同じ値」を入力したい場合は以下のようにします。

各セルに違う値を入力したい場合には、次のような感じでリスト型として渡せばOKです。

また、セル範囲の指定に変数を使いたい場合は以下のようにRangeとCellsを組み合わせて使うと簡単です。

関数を入力する

関数を入力する場合は、Valueの代わりにFormulaにします。

セルの書式設定

表示形式を変えたり罫線や色を変更する方法を紹介します。

フォントの設定

Excel の定数をインポートする

Excel の定数はインポートができます。

VBAでお馴染みのxlUp / xlDown / xlYes / xlContinuous などをそのまま使えます。

ただし定数をPython用に変換する処理が入るので、初回実行に少し時間がかかることもあります。
パフォーマンス重視なら、constantsを使わないという考え方もありです。

定数をインポートする理由

可読性が上がるためです。

定数を使わない場合には、次のようなコードになります。

Python
ws.Cells(ws.Rows.Count, 1).End(-4162).Row

これでは-4162が何を表すのかが一目でわかりません。

一方でconstantsを使うと、次のようにわかりやすくなります。

Python
ws.Cells(ws.Rows.Count, 1).End(constants.xlUp).Row

基本的な書き方

Python
import win32com.client as win32
from win32com.client import constants

excel = win32.Dispatch("Excel.Application")
wb = excel.Workbooks.Open("sample.xlsx")
ws = wb.Worksheets(1)

# 最終行を取得(VBAと同じ書き方)
last_row = ws.Cells(ws.Rows.Count, 1).End(constants.xlUp).Row

print(last_row)

よく使うExcelの定数一覧

定数名用途
constants.xlUp上方向に移動
constants.xlDown下方向に移動
constants.xlToLeft左方向
constants.xlToRight右方向
constants.xlYesヘッダーあり
constants.xlNoヘッダーなし
constants.xlContinuous実線の罫線
constants.xlEdgeBottom下罫線
constants.xlCenter中央揃え

まとめ

冒頭でも説明した通り、openpyxlでは罫線やグラフが消えてしまうので、win32comを使うのがおすすめです。

この記事が気に入ったら
フォローしてね!

シェア・記事の保存はこちら!

この記事を書いた人

基本、書くことで生計を立てています。
ITエンジニア歴は約5年ほど。
Pythonを書くことが多いですが、雑食です。
基本情報技術者試験合格。

コメント

コメントする

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)