Pythonでエクセルをいじるようになると、見た目の仕上げとしてウィンドウ枠を固定したくなります。
OpenPyXLでウィンドウ枠の固定を自動で設定できるようにします。
テスト用にエクセルを準備する
サンプルデータとして、次のようなエクセルのデータを作成します。
実行すると、pythonのコードと同じディレクトリにtest.xlsxというファイルが出力されます。
import openpyxl import os data = { 'Ken' : { 'Country': 'US', 'Job': 'Artist', 'Age': 56 }, 'Alan' : { 'Country': 'Japan', 'Job': 'Carpenter', 'Age': 27 }, 'Steven' : { 'Country': 'China', 'Job': 'Artist', 'Age': 40 } } wb = openpyxl.Workbook() ws = wb.create_sheet(title='test') headers = ['Name'] + list(data[list(data.keys())[0]].keys()) for header in headers: col = headers.index(header) + 1 ws.cell(row=1, column=col).value = header row = 2 for name in data: ws.cell(row=row, column=1).value = name for header in data[name]: col = headers.index(header) + 1 ws.cell(row=row, column=col).value = data[name][header] row += 1 filename = 'test.xlsx' file_path = os.path.join(os.getcwd(), filename) wb.remove(wb['Sheet']) wb.save(file_path)
エクセルのウィンドウ枠の固定をする
作成済みのtest.xlsxを開いて、OpenPyXLのウィンドウ枠の固定の処理をします。
ウィンドウ枠の固定は、ws.freeze_panes=’C3′ で実現しています。
import os import openpyxl filename = 'test.xlsx' file_path = os.path.join(os.getcwd(), filename) wb = openpyxl.load_workbook(file_path) ws = wb['test'] ws.freeze_panes = 'C3' filename = 'test_freeze_panes.xlsx' file_path = os.path.join(os.getcwd(), filename) wb.save(file_path)
出力ファイルはこうなります。C3のセルで固定できていることがわかります。
いろいろなデータに対応できるように柔軟なコードにする
現在の実装は、C3という固定値を使っているため、汎用性がありません。
今回のデータを見てみると、1行目はヘッダで、2行目からは各個人の情報が書かれています。
そのため、Nameの列が左端で固定されていて、それより右の情報をスクロールできる状態になっていれば良さそうです。
汎用性のあるコードに修正してみます。
ヘッダがNameとなっている列を自動検出し、列の列名をget_column_letterで取得します。
その列名と2行目を指定して、B2でウィンドウ枠の固定をします。
このコードによって、複数のデータでNameの列がどこにあってもNameの右で固定することができます。
import os import openpyxl from openpyxl.utils import get_column_letter, column_index_from_string filename = 'test.xlsx' file_path = os.path.join(os.getcwd(), filename) wb = openpyxl.load_workbook(file_path) ws = wb['test'] for col in range(1, ws.max_column+1): if ws.cell(row=1, column=col).value == 'Name': freeze_col_str = get_column_letter(col+1) break ws.freeze_panes = freeze_col_str + str(2) print(freeze_col_str + str(2)) filename = 'test_freeze_panes_b.xlsx' file_path = os.path.join(os.getcwd(), filename) wb.save(file_path)
出力ファイルを見るとNameの右で固定できていることがわかります。