pythonでExcel出力 ~辞書型データの書き込み処理~
これまでスクレイピングをいろいろやってきましたが、取得データに合わせてエクセルへの書き込み処理を見直すのも手間に感じ始めたので、より汎用性を高くして使いまわしやすい処理を作ってみました。
はじめに
今回はopenpyxlを使用したエクセル生成とpandasを使用したエクセル生成の2パターンを実装します。
設計内容はいずれも以下のように同じ辞書型データをもとにエクセル出力を実施するものとします。
処理の流れ
① 初めに「Key = ヘッダ、Value = セルの入力値」となるような辞書型のデータを用意
② 初期化(ヘッダ情報入力)実施
③ 辞書型のValueに入力したい値を設定
④ ③の辞書型を渡すことで、行追加
⑤ ③→④を繰り返す
⑥ 保存処理を要求(エクセル名、シート名を指定)
openpyxlを使用したエクセル生成
参考とできるよう、罫線(borders)、文字の配置(alignment)、セルの色(styles)を設定させています。
実装
import datetime
import openpyxl
from openpyxl.styles.borders import Border, Side
from openpyxl.styles.alignment import Alignment
from openpyxl.styles import PatternFill
temp_dic = {"KEY1":1,"KEY2":2,"KEY3":3,"KEY4":4,"KEY5":5}
def main():
# 初期化
excel = make_excel(temp_dic)
# 行の追加(temp_dicの各Valueは更新しておくこと)
excel.add_inf(temp_dic)
excel.add_inf(temp_dic)
# エクセルの保存
now = datetime.datetime.now()
file_name = 'sample_excel_{}.xlsx'.format(now.strftime('%Y%m%d_%H%M%S'))
excel.save_file(file_name,"sample1")
# エクセル転記
class make_excel():
wb = openpyxl.Workbook()
ws = wb.active
write_line = 1
# 各種設定
side = Side(style='thin', color='000000')
border = Border(top=side,bottom=side,right=side,left=side)
fill = PatternFill(patternType='solid', fgColor='87CEFA', bgColor='87CEFA')
# エクセルヘッダ記入
def __init__( self , init_dic) :
key_list = init_dic.keys()
for i , key_name in enumerate(key_list):
self.ws.cell(column=i+1, row=self.write_line).value = key_name
self.ws.cell(column=i+1, row=self.write_line).alignment = Alignment(horizontal = 'center', vertical = 'center',wrapText=True)
self.ws.cell(column=i+1, row=self.write_line).fill = self.fill
self.ws.cell(column=i+1, row=self.write_line).border = self.border
self.write_line += 1
return
# 行追加
def add_inf( self , add_dict ) :
value_list = add_dict.values()
for i , add_value in enumerate(value_list):
self.ws.cell(column=i+1, row=self.write_line).value = add_value
self.ws.cell(column=i+1, row=self.write_line).border = self.border
self.write_line += 1
# ファイル保存
def save_file( self , file_name , title ):
self.ws.title = title
self.wb.save(file_name)
if __name__ == '__main__':
main()
実行結果
コードと同じ場所に指定したファイル名、シート名のエクセルが出力されます。
pandasを使用したエクセル生成
正直df.to_excelで簡単にデータフレームをそのままエクセル出力しちゃえばいいのですが、上記openpyxlと同じ構造で作ってみました。
実装
import pandas as pd
import datetime
temp_dic = {"KEY1":1,"KEY2":2,"KEY3":3,"KEY4":4,"KEY5":5}
def main():
# 初期化
excel = make_excel(temp_dic)
# 行の追加(temp_dicの各Valueは更新しておくこと)
excel.add_inf(temp_dic)
excel.add_inf(temp_dic)
# エクセルの保存
now = datetime.datetime.now()
file_name = 'sample_excel_{}.xlsx'.format(now.strftime('%Y%m%d_%H%M%S'))
excel.save_file(file_name,"sample1")
class make_excel:
# エクセルヘッダ記入
def __init__( self , init_dic) :
key_list = init_dic.keys()
self.df = pd.DataFrame(columns=key_list)
# 行追加
def add_inf ( self , add_dict ) :
self.df = self.df.append( add_dict , ignore_index=True)
return
# ファイル保存
def save_file( self , file_name , title ):
self.df.to_excel(file_name, sheet_name=title)
return
if __name__ == "__main__":
main()
実行結果
見栄えもそんなに悪くないですね。
最後に
簡単ですが辞書型データで逐次行追加を意識したエクセル出力の実装については以上になります。
openpyxlを使用すれば、罫線やセルの色等エクセルの細かいフォーマットの操作が可能です。ですが細かい設定をすればするほど処理速度の重さが顕著に現れます。
一方でpandasは細かい設定が出来ませんが、その分大容量のデータでもエクセル出力が比較的早く完了します。
出力内容に応じてセルの書式を変えたりしたい場合はopenpyxl、単純な表出力でよければpandasといったところでしょうか。
その他それぞれの違いについては以下がとても参考になります。