Cucco’s Compute Hack

コンピュータ関係の記事を書いていきます。

openpyxlで、エクセルファイルのフィルタの設定をする

openpyxlで、エクセルファイルのフィルタの設定をする実証コード

エクセルで開いても、フィルタの設定は入っているが、フィルタ表示はされていない状態で表示される。
エクセルで開いて、フィルタのプルダウンを開いて、再適用すれば、フィルタリングされた状態で表示される。

コード
from openpyxl import Workbook, load_workbook, utils

# 1行目がヘッダで、A2からデータが入っている想定
read_filename = r"C:\dev\SampleCodes\hello_openpyxl\NATO_phonetic_alphabet.xlsx"
save_filename = read_filename.replace(".xlsx", "_filterd.xlsx")
wb = load_workbook(read_filename)

# 対象シートは 'Sheet1'
ws = wb['Sheet1']

# フィルタを設定したい列名を指定
filter_col = 'A'
# column_index_from_string(A)は1を返すが、使うときはオフセットで0始まりなので1を引いておく。
filter_col_offset = utils.column_index_from_string(filter_col) - 1
print("filter_col = {0}, filter_col_offset = {1}".format(
    filter_col, filter_col_offset))

# 表示したい行にある、A列の内容
# 実際にはない値を指定しても、add_filter_columnでは無視される。
filter_words = ["0", "A", "Z"]

# データがある最大行を取得
max_row = ws.max_row
max_col = ws.max_column
print("max_row = {0}, max_col = {1}".format(max_row, max_col))

# 表示したい値が、実際にあるか確かめておく
for word in filter_words:
    flag_find = False

    for row_index in range(0, max_row):
        cell_value = ws.cell(
            row=row_index+1, column=utils.column_index_from_string(filter_col)).value
        if word == str(cell_value):
            flag_find = True
            print("{0} in filter_words found".format(word))
            break

    if flag_find == False:
        print("Error!! {0} in filter_words not found".format(word))
        exit(-1)

# 列番号をxlsの列名アルファベットに変換
max_col_letter = utils.cell.get_column_letter(max_col)

# filterの範囲を指定
# A列からデータがあることが前提。
ws.auto_filter.ref = "A1:" + max_col_letter + str(max_row)
print("ws.auto_filter.ref = {0}".format(ws.auto_filter.ref))

# filter指定
# filter_col_index は 0だと、ws.auto_filter.refの範囲で、いちばん左の列
ws.auto_filter.add_filter_column(filter_col_offset, filter_words)
# サンプルコードにあったソートはしなくてよい。
# https://openpyxl.readthedocs.io/en/latest/filters.html#using-filters-and-sorts
# ws.auto_filter.add_sort_condition("B2:B15")

# 保存はする。
# エクセルで開いても、フィルタの設定は入っているが、フィルタ表示はされていない状態で表示される。
# エクセルで開いて、フィルタのプルダウンを開いて、再適用すれば、フィルタ表示される。
wb.save(save_filename)

wb.close()
実行結果
(base) C:\dev\SampleCodes\hello_openpyxl>python hello_filter.py
filter_col = A, filter_col_offset = 0
max_row = 37, max_col = 2
0 in filter_words found
A in filter_words found
Z in filter_words found
ws.auto_filter.ref = A1:B37

(base) C:\dev\SampleCodes\hello_openpyxl>
読んでいる元データ

NATO_phonetic_alphabet.xlsx

f:id:Cucco:20191018222930p:plain
読んでいる元データ