退屈なExcel作業をPythonにやらせるためのモジュールの選び方

# はじめに

しばらく前から少し大きい書店のIT関連の売り場では、平積みになっている「退屈なことはPythonにやらせよう ―ノンプログラマーにもできる自動化処理プログラミング」を見かけることがあります。タイトルが長いので、以下では「退屈本」と略させてもらいます。個人的には退屈なことの一つに、Excelでの報告書とかが思いつくんですけど、この本にもExcelの作業の自動化についても書かれています。

私もExcel作業の自動化について、以下の2件を投稿しました。

- [PythonでWordの差し込み印刷を自動処理](http://qiita.com/kubotama/items/94758ca93999b0700323)
- [PythonでExcelのセルの値を参照するときの注意点](http://qiita.com/kubotama/items/a8fc456ce51ac9aaa396)

上の2件では「退屈本」とはExcelへの対応方法を変えています。Excelの作業を自動化しようと思った人がモジュールを選択するときの参考にしてもらうために、対応方法を変更した理由をまとめました。

# Excelへの対応方法

Pythonを普通にインストールしただけではExcelのファイルを読み書きすることはできませんので、モジュールを追加することになります。このモジュールには大きく分けて2つのタイプがあります。一つ目のタイプは退屈本で紹介されている[openpyxl](https://pypi.python.org/pypi/openpyxl)のように、Excelのファイルを読み書きするモジュールです。このタイプのモジュールはアプリケーションごとに分かれているみたいで、Wordには[python-docx](https://pypi.python.org/pypi/python-docx)、Powerpointには[python-pptx](https://pypi.python.org/pypi/python-pptx)とかがあります。

もう一つのタイプは、上の2件の投稿で利用している[pywin32](https://pypi.python.org/pypi/pywin32)のように[Win32 API](https://msdn.microsoft.com/ja-jp/library/cc440903.aspx)を利用してExcelの機能を利用することでExcelファイルの読み書きします。こちらのタイプはアプリケーションが変わってもAPIさえ公開されていれば対応が可能です。

それぞれにメリットとデメリットが、お互いの裏表のような形でありますので、それをまとめました。

# Excelファイルを読み書きするモジュール

## メリット

Excelファイルを読み書きすることについてはモジュールだけで完結できます。つまり、このモジュールさえあれば、Excelがインストールされていない環境でもExcelファイルの読み書きが可能です。

## デメリット

Excelファイルの読み書き以外の、Excelのアプリケーションとして機能が利用できません。たとえば、Excelをアプリケーションとして利用する場合、ExcelファイルをPDF形式で保存することができますが、そういう機能は提供されていないモジュールが多いみたいです。少なくともopenpyxlには見当たりませんでした。Excelファイルを加工して最終的にPDFファイルとして出力するみたいな要件の自動化の場合には、困ってしまいます。

# Win32 APIを利用するモジュール

## メリット

MicrosoftのOfficeの場合、MicrosoftがAPIとして提供していますので、Excelがアプリケーションとして提供している機能を利用することが可能です。もしかしたらアプリケーションの機能としてはあるのにAPIが提供されていないこともあるかもしれませんが、いまのところは見つけていないです。そのため、Excelでの作業を自動化しようとしたときに、これはできない、ということが基本的にはありません。プログラミングが、どれだけ大変になるのかは別にすれば、ですけど。

## デメリット

Excelの機能を利用しますので、Excelがインストールされていることが前提になります。ExcelをインストールできないLinux環境では開発も実行もできないことになります。Macがどうなのかは申し訳ありませんがわからないです。

もう一つは、Excelをアプリケーションとして利用しているため、プログラムを実行する環境のExcelの利用に影響が出ます。たとえば、あるExcelファイルをオープンしたままでプログラムがエラーなどで終了してしまうと、そのExcelファイルはロックされたままになって、編集できなくなってしまうことがあります。その場合はタスクマネージャーでExcelのプロセスを探して終了させることになります。

他にも[Win32 API の利用方法](https://msdn.microsoft.com/ja-jp/library/cc440903.aspx)(たとえばExcelのオブジェクトモデルは[ここ](https://msdn.microsoft.com/ja-jp/library/fp179694.aspx))にOfficeなどをAPIから利用するためのオブジェクトモデルが書かれていますが、当然ながらPythonからのバインディングについては説明がありませんので、最初のうちは試行錯誤が必要だったりします。ググっても、Pythonのサンプルはあまり見つからないので、VBとかのサンプルから推測しています。

# 結論

結論ですが、既に投稿した2件に書いた通りに、Win32 APIを利用するpywin32を選びました。理由としては、[PythonでWordの差し込み印刷を自動処理](http://qiita.com/kubotama/items/94758ca93999b0700323)のように、差し込み印刷のような機能をプログラムから利用できることです。せっかく自動化しようするときに、なるべく出来ないことがないようにしたいと思ったからです。

上に書いたWin32 APIを利用するデメリットですが、業務の自動化を考えたときにExcelが入っていない環境で業務をしていることは少ないんじゃないかと思うので、インストールが必須なことはあまり気にしないことにしました。

エラーで異常終了するとロックしてしまうのは面倒ですけど、こういうことが発生するのは開発時のことで回避方法も明確なので、これも目をつぶりました。うまくクラスを定義すればエラーが発生しても自動的にクローズするようにも出来そうな気がして、今後の課題と考えています。

マニュアルとかの資料が少ないことも慣れの問題でもありますし、VBとかから推測できることが増えてきました。

# 余談

ここまで読まれて、スクリプト言語でWin32のAPIを呼び出すんだったら、いまさらVBとかはあれだけど、Powershellにすればいいんじゃないかと思った方がいるかもしれないので、一言、補足しておきます。

確かにPowershellであれば、もともとWindowsにインストールされていて、そのままでWin32 APIを利用するプログラムの開発が可能です。実行するために、一度だけ管理者権限での設定が必要ですが、これも問題になることはそれほど多くないと思いますので、Powershellを選んでもいいようですが、残念なことが一つあります。それはPowershellのプログラムはUTF16BEのエンコードでファイルに保存する必要があることです。このエンコードだとGitでテキストとして認識されないため、バージョン間で差分を見ることができません。Gitをちゃんと設定すればテキストとして認識されるようになるのかもしれませんが、うまい方法が見つからなかったので、PowershellではなくPythonを選びました。