頑張らないために頑張る

ゆるく頑張ります

PythonとxlwingsでExcelファイルをいじる

Posted at — Sep 6, 2019

概要

xlwingsを利用して、PythonからExcelファイルをいじってみます。下記の例はインタプリタですが、*.py形式のファイルでも同様に利用できます。

環境

注意点として、xlwingsはExcelがインストールされている必要があります。そのため、WindowsかmacOSでないと動作しません。一応、Linuxでなんとかしたい先行者がいるようですが、自分は試していません_( _´ω`)_ペショ

新規でワークブックを作成する

空のワークブックを作成します。

>>> import xlwings as xw
>>> xb = xw.Book()
>>> xb.name
'Book1'

次の方法でも作成できます。上記の方法は明示的に「ワークブックを作成」しますが、こっちの方法はアプリケーション(Excel)を起動しつつ新規ワークブックをアプリケーションに作成させます。スタートメニューなどから単純にExcelを起動した場合、空っぽのファイルを開いた状態でExcelが起動しますが、あれの状態をプログラムで再現している感じ。

>>> import xlwings as xw
>>> app = xw.App()
>>> app.books[0].name
'Book1'

既存のファイルを開く

>>> xw.Book(r'C:\\app\\hoge.xlsx')

または

>>> app = xw.App()
>>> app.books.open(r'C:\\app\\hoge.xlsx')

ファイルを閉じる

すでにオープンしたExcelファイルを閉じます。保存はせず、確認メッセージも出力されません。

>>> xb = xw.Book()
>>> xb.close()

ちなみに、このコードはワークブックを閉じるだけなので、Excelのプロセスそのものは残ることに注意。

Excelを閉じる

Excelのプロセスそのものを閉じる場合は、killを利用します。

>>> app = xw.App()
>>> app.kill()

セルに値を設定・参照する

.valueを用いて値を設定あるいは参照します。文字列の場合はクオーテーションで囲います。

>>> xb = xw.Book()
>>> xw.Range((1,1)).value = "hoge"
>>> xw.Range((1,1)).value
'hoge'
>>> xb.sheets(1).range(1,1).value = 1
>>> xb.sheets(1).range(1,1).value
1

任意のセルを基準にして、配列形式で値を設定することもできます。

>>> xb.sheets(1).range(1,1).value = [["hoge", "fuga", "piyo"], [1, 2, 3]]

上記を実行するとワークシートには下記の状態でデータが格納されます。

行列 A列 B列 C列
1行目 hoge fuga piyo
2行目 1 2 3
>>> xb.sheets(1).range(1,1).value
'hoge'
>>> xb.sheets(1).range(1,2).value
'fuga'
>>> xb.sheets(1).range(2,3).value
3.0

逆に指定した範囲のデータを参照することもできます。

>>> xb.sheets(1).range((1,1), (2,3)).value
[['hoge', 'fuga', 'piyo'], [1.0, 2.0, 3.0]]
>>> xb.sheets(1).range("A1:C2").value
[['hoge', 'fuga', 'piyo'], [1.0, 2.0, 3.0]]
>>> xb.sheets(1).range("A1:B3").value
[['hoge', 'fuga'], [1.0, 2.0], [None, None]]

選択した範囲にデータが存在しない場合は、上記のとおりNone表示になります。

なお、App()を使用してインスタンスを生成した場合でも、基本的な考え方は同じ。

>>> app = xw.App()
>>> app.books[0].sheets[0].range(1,1).value = "hoge"
>>> app.books[0].sheets[0].range(1,2).value = 1

なお、Rangeクラスはいろんな指定の仕方があって、行と列を数字で指定する(Excel VBAのcellsみたいな)書き方もできるし、A1とかで指定する書き方も可能です。ただし、Rangeクラスを利用して行と列を数字で指定する場合はカッコを2重する必要があります。また、ぱっと見が似た要素のrange(全部小文字の方)はSheetクラスなのでsheets(1)などでシートを指定しないとエラーになります。

>>> wb = xw.Book()
>>> xw.Range('A1').value = [[None, 1], [2, 3]]
>>> xw.Range((1,1)).value = "fuga"
>>> xw.sheets(1).range(1,1).value = "hoge"
>>> xw.sheets(1).range("A1").value = "fuga"
>>> xw.Range(1,1).value = "hoge"    <-- カッコが2重でない
Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "C:\app\Continuum\anaconda3\lib\site-packages\xlwings\main.py", line 1005, in __init__
    raise ValueError("Invalid arguments")
ValueError: Invalid arguments
>>> xw.range(1,1).value = "hoge"    <-- シートが指定されていない
Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
AttributeError: module 'xlwings' has no attribute 'range'

セルに計算式を設定・参照する

>>> xb.sheets(1).range(1,3).formula = "=A1+B2"
>>> xb.sheets(1).range(1,3).formula
'=A1+B2'

.formulaを使用すれば計算式の設定および参照が可能。

セルの背景色を設定する

>>> xb.sheets(1).range(1,2).color = (255,0,0)

RGBで指定します。上記のコードだと背景色が赤になります。

選択されたセルの個数を調べる

>>> xb.sheets(1).range((1,1),(3,3)).count
9

.countを利用します。

最終列または最終行を調べる

>>> xs = xb.sheets(1)
>>> xs.range((1,1),(5,5)).value = "hoge"
>>> xs.range(1,1).end("down")
<Range [Book2]Sheet1!$A$5>
>>> xs.range(1,1).end("right")
<Range [Book2]Sheet1!$E$1>

.endを利用します。引き数には’up’、’down’、’right’、’left’のうちいずれかを指定します。Excelでの「CtrlEnd」などの操作と同様の挙動をします。なので、下記のような場合は上手く動作しません

>>> xs = xb.sheets(1)
>>> xs.range(1,3).value = 1
>>> xs.range(1,5).value = 1
>>> xs.range(1,1).end("right")
<Range [Book2]Sheet2!$C$1>

セル「1,5(E1)」に値がセットされているので、本来は.endright方向に最終列を調べるなら「E列」が返ってきてほしいところですが、C列とE列の間のD列は値がセットされていない列なので、「C列までデータがあるよ」としか返ってきてくれません。表形式ですべてのセルにデータの欠落のないことが保証されているなら、使ってもいいかもしれない。

保存する

>>> wb = xw.Book()
>>> wb.save()

あるいは

>>> wb.save(r'C:\\app\\new_file.xlsx')

とします。

comments powered by Disqus