OpenPyXLでエクセルのウィンドウ枠の固定をしたい

TAGS :

テスト用にエクセルを準備する

まずは、以下のコードでエクセルの表を出力します。"test.xlsx" というファイルが出力されます。

Python

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)

このようなエクセルの表が出力されます。
エクセル表

OpenPyXLでエクセルのウィンドウ枠の固定をする

OpenPyXL でウィンドウ枠の固定をしてみましょう。
残念ながら、freeze_panes の公式ドキュメントは見当たりませんでした。
freeze_panesのコードは こちら です。

実装コードです。
ウィンドウ枠の固定は、ws.freeze_panes='C3' で実現しています。

Python

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でウィンドウ枠の固定)

もっと柔軟なコードにする

今のままでは、"C3" という固定値を使っているため、あらゆるエクセル表に対応できません。
ちょっといじってみたいと思います。

今回の例でいうと、ヘッダ行は1行目で、"Name"属性がユニークな属性になっていそうです。
そのため、"Name" のセルの右下でウィンドウ枠の固定ができていると良さそうです。

改変したコードでは、ヘッダ行のセルで "Name" となっているセルを見つけ、次の列の列名を get_column_letter で取得しています。
その列名と2行目を指定して、"B2" でウィンドウ枠の固定をしています。

Python

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)

出力ファイルはこうなります。"B2" で固定できていることがわかります。
エクセル表(B2でウィンドウ枠の固定)