skc

pythonのopenpyxlモジュールを使ってエクセル操作【5時間目:rows, columns】

iter_cols()とiter_rows()メソッドで全部セルを取る

あまり使い道はわからないですが、iter_cols()とiter_rows()メソッドがあります。この構文を実行したらわかりますが、両者の違いは、値を取る順番が違うということです。引数に範囲を指定すればその分だけ取ります。何も引数を指定しなければ全部をとってきます。

iter_rows()は行を全部とってから次の列に、iter_cols()は列の値を全部取ってから次の行にうつります。forを2回使う理由はcellオブジェクトをとってくるためです。こうしないと.valueが使えないです。

ためしにコード中に含まれるcolはなんなのか調べてみましょう。

print(type(col))#<class 'tuple'>

結果tuple型になっています。tuple.valueとしてもセルの値は参照できないです。オブジェクトは流れがよく見えないのが辛いですが、一応type()メソッドを使えばそれがなんなのかがわかるようになります。もしくはspyderだったら変数エクスプローラーを使えば、そこに何が入っているか見ることができます。
 

import openpyxl, os
wb = openpyxl.load_workbook('example.xlsx')
sheet = wb.get_sheet_by_name('Sheet1')

for col in sheet.iter_cols(min_row=1, max_col=3, max_row=5):
 for cell in col:
 print(cell.value)
print('\n')

for row in sheet.iter_rows(min_row=1, max_col=3, max_row=5):
 for cell in row:
 print(cell.value)
print('\n')

 

sheet.columnsとsheet.rows

実は似たような機能をもつものにcolumnsとrowsというのがあります。しかしこのメソッドは上のメソッドとほぼ同じ動きをします。しかも引数は使えないので、同じようにforループで回すと全てをとってくるだけのメソッドです。

昔のバージョンですと、columns[1]とすることで特定の列を取ってくることが可能だったようです。(よい機能だったのになんで消した?)openpyxlはモジュールです。現在も常にバグ取りなどで、更新・改良を重ねているようです。

columnsとrowsにかんしては、他にも色々使い方はあるかもしれませんが、初心者のため確認事項だけしかお伝え出来ません。

一応リファレンスっぽいサイトもあります。公式かどうかはよくわかりませんが。この記事をまとめている時点ですとopenpyxlのバージョンは2.4.9でした。

最後にリファレンスっぽいサイトがあったのでリンクを貼っておきます。英語なので辛いですが、翻訳機能などを使って読むと色々わかるかもしれないです。

http://openpyxl.readthedocs.io/en/default/index.html

 

 

 

pythonのopenpyxlモジュールを使ってエクセル操作【4時間目:もっとセル操作】

列の文字と番号を相互変換する

列はA,B,C,D,E。というようになっていると思います。これを番号に変換できるし、もしくは、番号を列記号に置き換えることもできます。相互変換を行うには

  • column_index_from_string() → 列記号から番号に変換
  • get_column_letter → 番号から列記号に変換

を使う必要があります。またポイントして

from openpyxl.utils import get_column_letter, column_index_from_string というimport構文を書きます。この構文は書籍と違う場合もあります。openpyxlモジュールが進化を続けているからです。以下にサンプルコードをのせておきます。

import openpyxl, os
from openpyxl.utils import get_column_letter, column_index_from_string
wb = openpyxl.load_workbook('example.xlsx')
sheet = wb.get_sheet_by_name('Sheet1')
print(get_column_letter(sheet.max_column))#C
print(column_index_from_string('A'))#1

 

シートから複数の行と列を取得する

sheetをスライスするとtupleで表示されます。tupleは値の変更できないリストです。(スライスに関してはリストのスライスで検索)ポイントは1行ごとに順番で入っているということでしょうか。

import openpyxl, os
from openpyxl.utils import get_column_letter, column_index_from_string
wb = openpyxl.load_workbook('example.xlsx')
sheet = wb.get_sheet_by_name('Sheet1')
print(tuple(sheet['A1':'C3']))
'''
((&lt;Cell 'Sheet1'.A1&gt;, &lt;Cell 'Sheet1'.B1&gt;, &lt;Cell 'Sheet1'.C1&gt;), 
 (&lt;Cell 'Sheet1'.A2&gt;, &lt;Cell 'Sheet1'.B2&gt;, &lt;Cell 'Sheet1'.C2&gt;), 
 (&lt;Cell 'Sheet1'.A3&gt;, &lt;Cell 'Sheet1'.B3&gt;, &lt;Cell 'Sheet1'.C3&gt;))
'''

forループで回すと各セルの値を表示できます。ポイントは外側のforループが行を、内側のforループが列を処理していることでしょうか。

for row_cell in sheet['A1':'C3']:
 for cell in row_cell:
 print(cell.coordinate, cell.value)
 print('-------')
'''
A1 2015-04-05 13:34:02
B1 Apples
C1 73
-------
A2 2015-04-05 03:41:23
B2 Cherries
C2 85
-------
A3 2015-04-06 12:46:51
B3 Pears
C3 14
-------
'''

 

次は「pythonのopenpyxlモジュールを使ってエクセル操作【5時間目:rows, columns】」です。