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)

OpenPyXLでオートフィルタ設定をする

OpenPyXLのオートフィルタ設定は、範囲を設定するだけです。

オートフィルタの範囲を固定にする

オートフィルタの範囲はws.auto_filter.refで設定しています。

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']

ws.auto_filter.ref = "A1:D4"

filename = 'test_autofilter.xlsx'
file_path = os.path.join(os.getcwd(), filename)
wb.save(file_path)

上のコードを実行すると、コードと同じディレクトリにtest_autofilter.xlsxというファイルが出力されます。

1行目にオートフィルタの設定ができました。

オートフィルタの範囲を自動にする

ヘッダのカラム数を数えたりせずに、表を作ったらヘッダのエリアを自動で検出できるようにします。

get_column_letter関数を使って、オートフィルタの設定範囲が自動的に変わるように実装しましょう。

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']

# フィルタをかけるエリアを自動算出する。
area = get_column_letter(1) + str(1) + ':' + get_column_letter(ws.max_column) + str(ws.max_row)
print(area) # A1:D4
ws.auto_filter.ref = area

filename = 'test_autofilter.xlsx'
file_path = os.path.join(os.getcwd(), filename)
wb.save(file_path)