0
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[openpyxl]PythonでExcelファイルのデータを処理する

Last updated at Posted at 2021-02-22

はじめに

Excelファイルに入力されたデータを抽出して色々処理する必要があったので、PythonでExcelファイルを操作できるモジュールopenpyxlの使い方についての簡単なメモ

準備など

  • 動作環境
    • Python 3.6.1
    • openpyxl 3.0.5

普通にpipコマンドでインストールします

pip install openpyxl

データの読み書き

こういうExcelファイルがあったとします

とりあえず、入力されてるセルから適当な値を取り出してみます

import openpyxl as ex

wb = ex.load_workbook("./data.xlsx")    # Excelファイル選択
ws = wb["Sheet1"]                       # シート名選択
read_value = ws["A2"].value             # セル座標選択、値を取得

print(read_value)
田村 奈央

Sheet1A2セルに入力されている田村 奈央という値が出力されました

5行目、value = ws["A2"].valueのところをvalue = ws["A2"]とすると
値ではなくCellオブジェクトの取得になるので、print文で表示させたい時はフィールドであるvalueを持ってきてください

次は書き込みをやってみます

wb = ex.load_workbook("./data.xlsx")    # Excelファイル選択
read_value = wb["Sheet1"]["A2"].value   # シート、セル座標選択、値を取得

wb["Sheet2"]["B1"] = read_value         # 書き込み
wb.save("./data.xlsx")                  # 保存

上半分はさっきとほぼ同じです
まっさらなシート"Sheet2"を用意しておき、B1セルに書き込みます

最終行、saveメソッドで上書き保存するのを忘れずに
(この部分の処理が無いとExcelファイルに反映されません)

当然ですが、その部分にあった入力値は消えてしまいます。不安な方は別名で保存しておきましょう

行列番号でのセル座標指定

アドレスでのセル番地指定(先程までの座標指定方法)だと、loop処理などで扱いにくいケースが出てきます
そこで、行番号と列番号での座標指定を行ってみます

wb = ex.load_workbook("./data.xlsx")
ws = wb["Sheet1"]

read_value_01 = ws["A2"].value      # セル番地指定
read_value_02 = ws.cell(2,1).value  # 行列番号指定

print(read_value_01, read_value_02)
田村 奈央 田村 奈央

forでインデックスを指定する時などはこっちの方が扱いやすい気がします
自分は行と列がいつもごっちゃになってしまうのでラッパーを作ったりしています

行と列共にインデックスは「1」からのスタートとなっているので注意
(「0」以下の値を指定するとERRORになる)

注意点

関数を入力しているセルの読み込み

先程と同じシートにおいて、
「年齢」列のデータの読み込みを行ってみます

wb = ex.load_workbook("./data.xlsx")
ws = wb["Sheet1"]

read_value = ws["E2"].value
print(read_value)
=DATEDIF(D2,$G$2,"Y")

表示されている38という値を取ってきてほしいのに、数式を取得してしまいました

このように、関数によって値を算出しているセルの場合
算出された値ではなく、入力されている関数が読み込まれます

もし値そのものを読み込みたい場合は
load_workbookメソッド内の引数data_onlyの値をTrueにしてExcelファイルをロードしておきましょう

wb = ex.load_workbook("./data.xlsx", data_only=True) # 表示されている値として取得
ws = wb["Sheet1"]

read_value = ws["E2"].value
print(read_value)
38

結合セルの扱い

Excelにはセル結合という忌まわしき機能が存在します
シートの見栄えは良くなるのですが、結合セルの値は左上部分の座標のみに記録されているため、データとして処理する際には困ります

具体例を見てみましょう

上述のようなシートにおいて、データを人数分出力するコードを書いてみます

wb = ex.load_workbook("./data.xlsx", data_only=True)
ws = wb["Sheet1"]

for row in range(2, 19+1):
    for colmun in range(1, 5+1):
        print(ws.cell(row, colmun).value, end=", ")
    print() # 改行
男, 安井 人志, やすい ひとし, 1960-01-30 00:00:00, 61,
None, 中山 寿明, なかやま としあき, 1999-12-04 00:00:00, 21,
None, 岩田 一徳, いわた いっとく, 1945-06-28 00:00:00, 75,
None, 重松 真一, しげまつ しんいち, 1960-12-13 00:00:00, 60,
None, 高山 雅彦, たかやま まさひこ, 1982-11-27 00:00:00, 38,
None, 相田 幸平, あいだ こうへい, 1967-04-09 00:00:00, 53,
None, 三原 丈史, みはら たけし, 1974-03-31 00:00:00, 46,
None, 中岡 将也, なかおか まさや, 1976-02-25 00:00:00, 44,
None, 徳永 明慶, とくなが あきよし, 1978-11-22 00:00:00, 42,
女, 及川 えみ, おいかわ えみ, 1980-05-31 00:00:00, 40,
None, 小野寺 淳子, おのでら あつこ, 1944-04-14 00:00:00, 76,
None, 布川 怜奈, ふかわ れいな, 1961-08-04 00:00:00, 59,
None, 瀬戸 かおり, せと かおり, 1950-03-12 00:00:00, 70,
None, 長崎 路子, ながさき みちこ, 1974-03-08 00:00:00, 46,
None, 滝 奈央, たき なお, 1954-02-09 00:00:00, 67,
None, 小野 あおい, おの あおい, 1974-04-14 00:00:00, 46,
None, 竹下 恵梨香, たけした えりか, 1988-05-28 00:00:00, 32,
None, 本村 紗季, ほんむら さき, 1955-05-30 00:00:00, 65,

性別の出力に注目してみてください

値がある人とない人がいることがわかります
これは結合セルの左上部分以外の座標には、内部的に値が存在しないことによる現象です

結合セルを含んだシートを処理する場合は十分に気をつけてください
一番良いのは、結合セルを使わないことです

リンクなど

0
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?