Excel Binary Workbook を Python で処理する方法
今回は,先日初めて経験したファイル形式の Excel Binary Workbook (xlsb) に関して,python で csv にパースする話になる.
.xlsx
はよくある Excel ファイル形式だが,それのバイナリー形式である .xlsb
はあまり見かけないように思う.
Excel の闇や Excel との格闘は色々あるが,今回はそこをグッと堪えて進めたいと思う笑
.xlsb とは
Weblio 辞書によると以下のように記載されている.
.xlsbとは,Excel 2007で作成したブックを「XML形式でないバイナリブック」として保存する際に用いられる拡張子である..xlsbでブックを保存した場合はファイル全体がバイナリ形式で保存され,XMLベースである.xlsxなどのファイル形式で保存した場合と比べて,ファイルサイズを数分の1程度に抑えることができる.
受け取ったファイルは .xlsb
形式でも100MBぐらいで,.xlsx
形式だとかなり容量が大きく,ファイルを開くと処理が重たくなることが想像できるので,圧縮したのだと考えられる.
Excelを扱えるpythonライブラリ
openpyxl
定番の openpyxl を使っていく.
上記ページにも記載されているが,Excel ファイルの拡張子である .xlsx
を扱うことができる.
openpyxl is a Python library to read/write Excel 2010 xlsx/xlsm/xltx/xltm files.
いつものようにこのライブラリで処理しようとしたところ,下記のようなエラーが発生した.
openpyxl.utils.exceptions.InvalidFileException: openpyxl does not support binary format .xlsb, please convert this file to .xlsx format if you want to open it with openpyxl
もう一度 openpyxl の説明を見ると,確かに扱える拡張子は xlsx/xlsm/xltx/xltm
となっているので,.xlsb
は扱えないのが分かる.
そこで,.xlsb
の拡張子が扱えるライブラリを調べたところ,pyxlsb というのがあるみたいで,それを使うことにした.
pyxlsb
pyxlsb は公式の説明にあるように,xlsb 形式を扱える python ライブラリになる.
pyxlsb is an Excel 2007-2010 Binary Workbook (xlsb) parser for Python.
pip でインストールすることができる.
pip install pyxlsb
公式のサンプルコードを記載しておく.
import csv
from pyxlsb import open_workbook
with open_workbook('Book1.xlsb') as wb:
for name in wb.sheets:
with wb.get_sheet(name) as sheet, open(name + '.csv', 'w') as f:
writer = csv.writer(f)
for row in sheet.rows():
writer.writerow([c.v for c in row])
もし pandas のデータフレームに変換したい場合は,参考ページのコードで可能となる.
ただし,時刻変換に関して少し注意が必要で,公式にもある通り,日付は float に変換されてしまうため,convert_date 関数を使う必要がある.
Note that dates will appear as floats. You must use the convert_date(date) method from the corresponding Workbook instance to turn them into datetime.
なので,元のファイルに時刻が入っている場合には,上記変換をコードの中に入れて処理する必要があるのでご注意を!
print(wb.convert_date(41235.45578))
>>> datetime.datetime(2012, 11, 22, 10, 56, 19)
今回は個人的に嵌ってしまった .xlsb
形式のファイルを扱う方法を紹介したが,出来ればデータ分析をするようなデータを Excel ファイルで扱いたくないのが本音😅
もちろん簡単なデータの可視化とか表計算で Excel が活躍する場面は多々あるが,自動化してデータを分析することを考えると,複雑だったり独自のデータフォーマットで保存することは危険である.
参考
追記
- 2020/01/05: 更新
pandas の「version=1.0.0」で .xlsb
ファイルをロードできるようになったみたい.方法は pd.read_excel
の引数で engine="pyxlsb"
と指定するだけ.
# Returns a DataFrame
pd.read_excel("path_to_file.xlsb", engine="pyxlsb")
- 参考: https://pandas.pydata.org/docs/user_guide/io.html#io-xlsb