pythonでエクセルを操作を自動化する方法【初心者向け入門編】

Python
この記事は約9分で読めます。

Excelで自動化を考えるときに第一選択肢に出てくるのはVBAでしょう。

ただ、VBA私全くできません。。そして、全く学習する意欲が湧きません。。なんでしょう、なんか今からラダーやCやれって言われるよりなぜかやる気がおきませんw ディスってるわけでもないですし、実際に業務に利用されて活用されている方もよく知っているので、正直趣味の問題だとは思いますが。。

ということで、pythonを使ってエクセルを操作する方法を紹介していきます。利用するモジュールはOpenPyXLというエクセルを操作するためのモジュールです。

スポンサーリンク
もしも_楽天

OpenPyXLとは何か?

OpenPyXLはエクセルの読み込み・書き出しなどの操作をpythonでするためのモジュールです。

実際にできることは以下のような操作です。

OpenPyXLでできること
  • エクセルファイルを作成する
  • 既存のエクセルシートのデータを読み込む(セルの値を読み込む・書き込む)
  • 計算式を設定する
  • データのコピーをする
  • グラフを作成する
  • PandasやNumpyと連動させる

などなど、他にもフォーマット(style関係)やフィルターなんかも取り扱えます。あまり使わないですが、pivot-tableも読むことができます(作成はできません)

OpenPyXLで操作できるエクセルファイル

OpenPyXlは .xlsxフォーマットのエクセルファイルであれば対応可能です。フリーソフト系のlibra office とかでもxlsx形式で保存可能なので、要はファイルフォーマットが.xlsxになっていればいけます。

逆に、.xlsは対応できません。Excel2003以前の拡張子がExcelファイル(拡張子が.xls)を使いたいときはxlrdの利用を考えるべきですね。

というか、今時.xlsなんて残っているのかと言われますが、たまに私の手元に送られてくることもあり、まぁまだ生きてるんだろうなぁと思います。

早く消し去っ。。。(グサッ

OpenPyXLのインストール

pip( or pip3)でモジュール管理されている方は以下の形でインストしてください。

#pipの場合

pip install openpyxl

#pip3の場合

pip3 install openpyxl

Anaconda(conda)の場合は、最初から入っていた気もします。(この頃使ってないので、記憶が定かではありませんが)

OpenPyXLでエクセルファイルを読み込む

何はともあれ何かファイルを読み込んでみましょう。

ファイルを読み込んでシート名一覧を取得する

from openpyxl import load_workbook

path = "絶対Pathもしくは相対Pathを指定"
ss = load_workbook(path)
print(ss.sheetnames)

読み込みファイルの場所について

何個かサイトを調べていると、.xlsxファイルをPythonを動かしている環境と同じディレクトリに移動(コピー)する必要があると書いてあるサイトもありました。

そんなことはないかなと。絶対パスを通せば特段問題なく動作します。

.xlsxファイルをPythonを動かしている環境と同じディレクトリに移動(コピー)する必要がある

ワークブックの取得

openpyxl.load_workbook(file_path)

ワークブックの取得はload_workbookメソッドを利用します。引数にはpathやファイル名(同一フォルダに入れてある場合)です。

GASでいうところのスプレッドシートオブジェクト(openbyidメソッドなどで取得するオブジェクト)

シート名の取得

ワークブックobj.sheetnames

ワークブックオブジェクト(load_workbookで取得したオブジェクトです)に対して、sheetnamesプロパティを取ればシート名の一覧が配列で返されます。

レスポンスはこんな感じ

['sheet1', 'sheet2', 'sheet3']

たまに、get_sheet_namesメソッドでシート名一覧を取得することを紹介している記事(多分古い記事です)がありますが、現在get_sheet_namesメソッドは非推奨になっていますので、sheetnamesプロパティを使うのが基本です。

openpyxl.workbook.workbook module — openpyxl 3.1.2 documentation

シートの取得・追加・コピー・削除

基本的なシート系の操作についてです。

シートオブジェクトの取得

Workbookオブジェクトにシート名を指定して取得できます。

path = "絶対Pathもしくは相対Pathを指定"
ss = load_workbook(path)
sheet1 = ss['sheet1']

GASのシートオブジェクトと同様(getSheetByName()メソッドなどで取得するオブジェクト)

シートの追加

シート追加はWorkbookオブジェクトのcreate_sheetメソッドで追加できます。一つ目の引数にシート名、二つ目の引数にシートを挿入する位置をインデックスで指定可能。引数の指定はどちらも任意です。

ワークブックobj.create_sheet(‘シート名’, index)

path = "絶対Pathもしくは相対Pathを指定"
ss = load_workbook(path)
ss.create_sheet('Additional Sheet', 0)

シートのコピー

シートコピーはWorkbookオブジェクトのcopy_worksheetメソッドで可能。引数にコピー対象のWorksheetオブジェクトを指定します。

ワークブックobj.copy_worksheet(ワークシートobj)

path = "絶対Pathもしくは相対Pathを指定"
ss = load_workbook(path)
sheet1 = ss['sheet1']
sheet2 = ss.copy_worksheet(sheet1)

シートの削除

シート削除はWorkbookオブジェクトのremoveメソッドを利用します。引数は削除したいWorksheetオブジェクトを指定します。

ワークブックobj.remove(ワークシートobj)

path = "絶対Pathもしくは相対Pathを指定"
ss = load_workbook(path)
sheet1 = ss['sheet1']
sheet2 = ss.remove(sheet1)

単一セル・複数セルの取得・編集

単一セルの取得と値の取得

単一セルを取得した場合は、セル名称(A1ノーテ)で取得してやれば可能です。セルの値を取得する場合は、cell obj.valueで取得可能

path = "絶対Pathもしくは相対Pathを指定"
ss = load_workbook(path)
sheet1 = ss['sheet1']

b2_cell = sheet1['b2']
print(b2_cell.value)

単一セルの編集

単一セルが取得できれば、あとはvalueプロパティの置き換えで単一セルの編集は可能です。

path = "絶対Pathもしくは相対Pathを指定"
ss = load_workbook(path)
sheet1 = ss['sheet1']

b2_cell = sheet1['b2']
b2_cell.value = "added from openpyxl"
print(be_cell.value)

シートオブジェクトからcellメソッドで編集する

セルを指定して値を取得する方法以外に、シートオブジェクトからcellメソッドを利用することで、直接行・列を指定して値を取得することも可能です。

ワークシートobj.cell(row, column, value=”値”)

valueはオプショナルです。値を入れ込みたくなくて、セルオブジェクトを取得したい場合は、valueを指定せずにいけばOKです。

キーワード引数で設定すると間違いが起きなくておすすめです。

複数セルの取得と値の取得

セルの範囲指定は①A1ノーテーションで指定する②行・列範囲で指定する、の2つの方法があります。

①A1ノーテーションで指定する方法

path = "絶対Pathもしくは相対Pathを指定"
ss = load_workbook(path)
sheet1 = ss['sheet1']

B2toC5_cells = sheet1['b2':'c5']
for row in B2toC5_cells:
    for cell in row:
        print(cell.value)

②行・列範囲で指定する方法(値の取得は省略)

path = "絶対Pathもしくは相対Pathを指定"
ss = load_workbook(path)
sheet1 = ss['sheet1']
#行単位で指定
cells1 = sheet1[10]
cells2 = sheet1[5:10]
#列単位で指定
cells3 = sheet1['A']
cells4 = sheet1['A':'C']

複数セルの編集

下記スクリプトだと、全部一括で同じ値にしてしまいますが、イメージは以下です。実際は条件分岐を与えて実行していきます。

path = "絶対Pathもしくは相対Pathを指定"
ss = load_workbook(path)
sheet1 = ss['sheet1']

B2toC5_cells = sheet1['b2':'c5']
for row in B2toC5_cells:
    for cell in row:
        cell.value = "modified from openpyxl"

Excelファイルの保存

Workbookオブジェクトのsaveメソッドに保存先パスを指定。新規作成の場合は新しいパス、上書き保存の場合は既存のパスを指定してください。基本は絶対Pathで指定してもらったほうがいいかと思います。

ワークブックobj.save(‘path’)

まとめ

GASとpythonを少しでも触ったことがある人であれば、非常にイメージしやすかったのではないでしょうか。

SpreadsheetAppと作りが似ているのがGASユーザにはありがたいですね。

スプレッドシート使えばいいという話もあるかもしれませんが、スクレイピングなどGASよりpythonの方が相性のいい物もありますので、openpyxlでローカルエクセル利用できるようになるといいですね。

sheetAPIを利用すればエクセルファイルのuploadやデータの書き込みも可能ですし。興味があれば以下の記事もお読みください。