Openpyxlを使って、エクセルのマージ作業を自動化したときに躓いたポイント


※2018年の6月くらいにメモっていたのですが、今更ながら投稿し忘れていたので遅れて投稿。
 2.5.1~2.5.4あたりのVLのものを使っていたと思いますが、もはや環境も残っていないため不明です。
 少し古いopenpyxlのため情報も古い可能性がありますが、許してくださいませ。

背景・はじめに

 私のプロジェクトでは、さまざまな大人達の都合もあって、
 テストの項目書などをいちいちエクセルで毎回毎回作成していました。
 
 この報告書は、一種の職人芸によって作られていたのですが、
 この崇高な作業も、openpyxl様のおかげで、ほぼ自動化されていました。
 そこで今回は、自動化で躓いたポイントを書きたいと思います。

1. 関数で参照される値を取得する

やり方

値を参照する場合、はdata_only=Trueを設定しましょう。
以下は、indirect関数で値を読み込んでいるセルから、"数値"を参照する場合の例です。

inwb = load_workbook(line.replace('\n',''),data_only=True)
inws = inwb['sheetname']
print(inws.cell(1,1).value)

出力

100

逆に数式をそのまま参照したい場合は、workbookを読み込む際、デフォルトのままにするとよいです。

inwb = load_workbook(line.replace('\n',''))

inws = inwb['sheetname']
print(inws.cell(1,1).value)

出力

 =INDIRECT($B4&"!H2")

2. セルのマージと、書式の設定

やり方

マージをするときは、merge_cells を使います。
また、罫線やテキストの配置などは、cell単位でいろいろとできるようです。

ここで注意が1点。
マージした後のセルに罫線を引いたりする場合は、すべてのセルに線を引く必要があります。
文字の位置なども指定があれば、↓のようにまとめて設定すると楽だと思います。

#セルのスタイル変更用の関数
from openpyxl.styles import Border, PatternFill, Font, Alignment

def set_styles(set_cell):
    set_cell.alignment = (
        wrap_text = True,          #行の折り返し
        horizontal = 'general',    #中央ぞろえ
        vertical = 'top'           #上ぞろえ
    )
    set_cell.border = Border(top=thin, left=thin, right=thin, bottom=thin)  #罫線
    set_cell.fill = PatternFill(fill_type='solid', fgColor='FFFDDFD0')  #塗りつぶし

#セルのマージ処理
outputws.merge_cells(ROW_START, COL_START, ROW_END, COL_END)

#マージした範囲に、スタイルを適用する。
for i in range(ROW_START, ROW_END):
    for j in range(COL_START, COL_END):
        set_styles(outputws.cel(i, j))

その他 気が付いた注意事項

行の追加の機能 (insert_rows()やinsert_cols()) という便利機能もあるのですが、これはうまく使えずあきらめました。
行の追加自体はできるのですが、"スタイル"などは行の追加とともにずれてはくれません。なので結局使わずじまいでした。

ということで、行の追加を使いたい場合は、実装の際、テキストの入力処理と整形する処理を分離して、
スタイル設定などは最後にまとめてやるような工夫が必要かもしれません。

その他 参考・役に立ったもの

 Python openpyxlでExcelを操作:
 https://qiita.com/tftf/items/07e4332293c2c59799d1
 
 公式? 
 http://openpyxl.readthedocs.io/en/stable/index.html
 ※webの記事は古いものが混じっているみたいです。
  旧版だと大変だったものが最新版だと楽に実装できるようになっているものもあります。
  非互換もありますので、細かなスタイルの設定などなど、公式の情報を読んだほうがよいと思います。

 https://openpyxl.readthedocs.io/en/stable/_modules/index.html
 こっちのページに、モジュールの一覧があります。とりあえず困ったときに見るのにおすすめ

※投稿時点ですと、xlwings ってものあるみたいですね。今から始める方はxlwingsを使うのもよいかもしれません。
 https://qiita.com/yniji/items/b38bc312e860027108ac