PythonからExcelブックに対して、データを読み書きしたり罫線やフォントを設定するライブラリはいくつかありますが、今回は Anaconda に標準搭載されている xlwings 使い方 について、使い方を解説したいと思います。
他のサイトの記事には断片的な解説が多いので、はじめてxlwingsを使う方は色々なサイトから情報を集めなければなりません。
この記事では、そのような事が無いよう、実用的に使う上で知っておくべき知識を一通り網羅しています。
xlwings の特徴
PytonからEXCELファイルを読み書きする方法として、openpyxl ライブラリ がありますが、両者には以下の違いがあります。
比較項目 | xlwings | openpyxl |
---|---|---|
動作環境 | Windows/MacOS | Windows/MacOS/Linux |
Excelのインストール | 必要 | 不要 |
サポートしているファイル形式 | Excelがサポートする形式全て | Excel 2010以降のxlsx/xlsm/xltx/xltm |
Excelとの互換性 | 〇 | △ |
Excelマクロの呼び出し | 〇 | × |
ExcelからPython関数呼び出し | 〇 | × |
処理速度 | 遅い | 速い |
Python対応バージョン | Python 3.6以上 | Python 3.6以上 |
ライセンス | OSS (BSD3条項ライセンス) | OSS (MIT Expat License) |
公式サイト | xlwingsクイックスタート | openpyxlチュートリアル |
比較表の中で一番気になるのが、openpyxl における互換性の問題です。
- openpyxl が対応していない計算式が存在する。
- 対応していない計算式を含むブックを読み込んで保存すると、その計算式が消える
- 行挿入の挙動がEXCELと異なる(属性が引き継がれず、下段の計算式が狂う)
上記の様に、計算式に関する部分は欠落する可能性があるため、特に第三者が作成したEXCELブックにデータを流し込むようなケースでは、予期せぬ事態に発展する可能性があります。
一方、速度については openpyxl の方が圧倒的に早い(8倍程度)という書き込みがありましたが、これは大量データをループ処理で書き込んだ場合です。
幸いなことに、xlwings では range メソッドを使った一括書き込みが可能で、これを使えば openpyxl と遜色が無いくらい速くなります。
上記のことから、Linuxで使う場合は openpyxl 一択になりますが、WindowsやMacOSで使うのであれば、xlwings が安心です。
インストール方法
xlwings は Anaconda でPythonをインストールすると標準でインストールされています。
もしインストールされていない場合は、以下の手順に従ってください。
Anaconda 又は Miniconda でPythonをインストールしている場合は
1 |
conda install xlwings |
Python公式サイトからPython をインストールしている場合は
1 |
pip install xlwings |
更に詳しい情報については、こちらの公式サイトに記載されています。
xlwings の使い方
xlwings を使うには import が必要です。
プログラムの先頭に下記の 1行を記述して下さい。
1 |
import xlwings as xw |
使い方は非常に簡単で、以下の手順でメソッドを呼び出せばExcelブックが作成できます。
xlwings の仕組みとExcelブックが削除できなくなった時の対処方
xw.Book() を実行するとExcelアプリケーションが起動し、以降の操作はそのExcelアプリケーションを通して実行されます。
そして、Close() を実行することでExcelアプリケーションが終了します。
xlwings はExcelと高い互換性がありますが、その理由はExcelアプリケーションそのものを使っているからです。
もし Close() をし忘れると起動したExcelがいつまでもタスクに残ったままになり、保存したExcelブックも掴まれたままになります。
以上の理由から、プログラムが何らかの原因で異常終了した場合、そのExcelブックは消せなくなります。
そんな場合は、タスクスケジューラ残っているExcelを削除することで、そのExcelブックも削除できるようになります。
Microsoft Excel の行をクリックし、DELキーを押すとタスクから削除可能です。
新規にExcelブックを作成するには
新規でExcelブックを作成する場合は、下記の手順になります。
Excelブックを新規作成した場合、「Sheet1」というシートが自動的に作成されています。
また、sheets.add() を実行すると、左側に新しいシートが追加されます。
下記は新規作成したExcelブックにシートを追加し、そのシートに値を書き込んでファイルに保存するサンプルプログラムです。
xw.App(visible=False) は、xlwings がExcelブックを開いた時に画面に表示されるのを防ぐためのものです。
デバッグ中は visible = True にしておくことで動画が画面で確認できるので便利ですが、本稼働で使う場合にいちいちExcelが表示されるとうっとおしいので、ここでは visible = False にしています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
import numpy as np import pandas as pd import xlwings as xw #シートに書き込む値を準備 data = [[1,2],[3,4],[5,6],[7,8]] ar = np.array(data) df = pd.DataFrame(data,columns = ['Col1','Col2']) #Excelが画面に表示されないようにする xw.App(visible=False) #Excelブックを新規作成し、シートに値を書き込む wb = xw.Book() sheet = wb.sheets.add('テスト') sheet.range('A1').value = data sheet.range('D1').value = ar sheet.range('G1').options(index=False,header=True).value = df #ファイルの保存とブックのクローズ wb.save('d:/sample.xlsx') wb.close() |
上記のプログラムを実行すると、次のExcelブックが保存されます。
rangeメソッドの引数にはセル位置を指定しますが、データが2次元配列(ndarray、DataFrame含む)の場合は一覧形式で書き込んでくれます。
尚、DataFrameはカラムとインデックスを持っていますので、options を使ってインデックスは書き込まないようにしています。
セルの指定は、’A1’ の他、行番号と列番での指定が可能です。
セルの範囲を指定する場合 'A1:C7' という記述をします。
1 2 3 4 5 6 7 8 |
#アルファベットと数値でセルを指定する sheet.range('A1') #3行5列のセルを指定する sheet.range(3,5) #範囲を指定する sheet.range('A1:C7') |
既存のExcelブックを開いて、中身を書き換えて保存するには
既存のExcelブックを開いて中身を編集する場合は、下記の手順になります。
下記は、前述のサンプルプログラム で作成したExcelブックを読み込み、シート1に転記するサンプル プログラム です。
シートは ws.sheets[0] のように番号で指定することも可能ですが、sheets.add() で追加したシートは左端に追加されていくため、書き込みたいシートが0番目ではい可能性があります。
そのため、あえてシート名を使って転記先のシートを指定しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
import numpy as np import pandas as pd import xlwings as xw #ブックのオープン xw.App(visible=False) wb = xw.Book('d:/sample.xlsx') #「テスト」シートから値を取得 sheet = wb.sheets['テスト'] data2 = sheet.range('A1:B4').value ar2 = sheet.range('D1').options(np.array, expand='table').value df2 = sheet.range('G1:H5').options(pd.DataFrame).value #「Sheet1」シートに転記 sheet = wb.sheets['Sheet1'] sheet.range('A3').value = data2 sheet.range('D3').value = ar2 sheet.range('G3').value = df2 #ファイルの保存とブックのクローズ wb.save() wb.close() |
上記のプログラムを実行すると、以下の結果になります。
セルの属性(背景色、罫線、フォントなど)を設定するには
セルに背景色、罫線、フォントなどの属性を指定するには、その範囲を range で指定し、そこに対して必要な属性を設定していきます。
api には様々なものが用意されていますので、詳しくはこちらの公式サイトをご確認下さい。
下記は、指定した範囲に属性を設定するサンプルソースです。
1 2 3 4 5 6 7 8 9 10 11 |
range = sheet.range('A3:B6') range.color = 251, 251, 180 # 背景色のRBG range.api.Font.ColorIndex = 5 # 文字のカラーインデックス range.api.Font.Size = 12 # フォントサイズ range.api.Font.Bold = True # 太字 range.api.HorizontalAlignment = -4108 # 文字の横配置(中央揃え) range.api.VerticalAlignment = -4108 # 文字の縦配置(中央揃え) range.api.Borders(11).LineStyle = 5 # 罫線(内側の左右)の種類 range.api.Borders(11).Weight = 1 # 罫線(内側の左右)の太さ range.api.Borders(12).LineStyle = 3 # 罫線(内側の上下)の種類 range.api.Borders(12).Weight = -4138 # 罫線(内側の上下)の太さ |
このプログラムを実行すると、下記の様になります。
設定している値が数値ばかりでマイナスの値も含まれていたり、色の指定は番号やRGBの数値だったりと、非常に分かり難い値を設定しなければなりません。
ただ、これは xlwings が悪いのではなく、Excelの仕様がこうだからです。
VBAでも同様のことができますが、VBAから属性を設定する時も、この値を使います。
あまりに分かり難いので Python 用の定数を作ってみました。
各行のコメントの位置がバラバラで見難いかもしれませんが、これは本サイトのフォントの問題なので、テキストエディタやVisual Studio Code などに張り付けると、ちゃんと揃っています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
#--------------------------------------------- # 罫線の種類 LineStyle #--------------------------------------------- XLCONTINUOUS = 1 # 実線 XLDASH = -4115 # 破線 XLDASHDOT = 4 # 一点破線 XLDASHDOTDOT = 5 # 二点破線 XLDOT = -4118 # 点線 XLDOUBLE = -4119 # 二重線 XLLINESTYLENONE = -4142 # 罫線なし XLSLANTDASHDOT = 13 # 斜線 #--------------------------------------------- # 罫線の太さ Weight #--------------------------------------------- XLHAIRLINE = 1 # 極細 XLTHIN = 2 # 細 XLMEDIUM = -4138 # 中 XLTHICK = 4 # 太 #--------------------------------------------- # 個別罫線の指定 Borders(値) #--------------------------------------------- XLDIAGONALDOWN = 5 # 右下がり斜線 XLDIAGONALUP = 6 # 右上がり斜線 XLEDGEBOTTOM = 9 # 下辺 XLEDGELEFT = 7 # 左辺 XLEDGERIGHT = 10 # 右辺 XLEDGETOP = 8 # 上辺 XLINSIDEHORIZONTAL = 12 # 内側の水平線 XLINSIDEVERTICAL = 11 # 内側の垂直線 #--------------------------------------------- # 横位置の指定 HorizontalAlignment(値) #--------------------------------------------- XLHALIGNCENTER = -4108 # 中央揃え XLHALIGNDISTRIBUTED = -4117 # 均等割り付け XLHALIGNJUSTIFY = -4130 # 両端揃え XLHALIGNLEFT = -4131 # 左詰め(インデント) XLHALIGNRIGHT = -4152 # 右詰め XLHALIGNCENTERACROSSSELECTION = 7 # 選択範囲内で中央 XLHALIGNFILL = 5 # 繰り返し XLHALIGNGENERAL = 1 # 標準 #--------------------------------------------- # 縦位置の指定 VerticalAlignment(値) #--------------------------------------------- XLVALIGNBOTTOM = -4107 # 下詰め XLVALIGNCENTER = -4108 # 中央揃え XLVALIGNDISTRIBUTED = -4117 # 均等割り付け XLVALIGNJUSTIFY = -4130 # 両端揃え XLVALIGNTOP = -4160 # 上詰め |
セルに計算式を登録するには
セルに計算式を登録するには、下記の様に記述します。
1 |
sheet.range('B7').formula = '=sum(B3:B6)' |
このプログラムを実行した結果は以下の様になります。
B7のセルには、2+4+6+8=20が正しく表示されています。
グラフにアクセスするには
グラフはシートの中に配列で保持されており、charts プロパティで取得できます。
下記は先頭のグラフに対して、タイトルを変更した後で画像ファイルとしてサンプルです。
api は配列になっていますが、0ではなく1を指定します。
また、Export を export と記述した場合、そこでフリーズしてしまいますので、打ち間違いにはご注意下さい。
1 2 3 |
chart = sheet.charts[0] chart.api[1].ChartTitle.Text = 'A title' #タイトルを設定 chart.api[1].Export('D:/mychart.jpg') #ファイルにjpg形式で保存 |
グラフに対しては、追加や削除などのメソッドが用意されていますので、詳しくは下記の公式サイトをご確認下さい。
Excel側のマクロを呼び出すには
Excel側のマクロを呼び出すには、macroメソッドを使います。
1 2 |
macro = wb.macro('MyMacro') macro() |
詳しくは下記の記事に記載しているので、併せてご一読下さい。
まとめ
今回は xlwings を使った Excelブックの読み書きについて解説しました。
Excelをインストールしておく必要はありますが、Excelとの互換性を考えるなら、xlwings が一番使いやすいと言えます。
書き込みについては、For ループで単一セルに値を書き込むような処理だと時間が掛かりますが、range を使った一括書き込みの場合はかなり高速に処理してくれます。
PythonでExcelを編集したい場合は、xlwings もご検討ください。
この記事が皆さんのお役に立てれば幸いです。
コメント