公式サイトには列のグルーピングについては記載されていましたが、行のグルーピングについては記載されていませんでした。
ソースを参照しながら工夫したらどうにかできたので公開します。
今後公式から行のグルーピングについてアナウンスされるかもしれませんので、ご留意ください。
以下、ソースです。
# -*- coding:utf-8 -*- from openpyxl import Workbook from openpyxl.worksheet.dimensions import RowDimension data = [('スポーツ', '売上高'), [[('ゴルフ', 500000), ('ゴルフ', 200000), ('ゴルフ', 150000)], ('ゴルフ合計', '=SUBTOTAL(9,B2:B4)')], [[('サファリ', 900000), ('サファリ', 400000)], ('サファリ合計', '=SUBTOTAL(9,B6:B7)')], [[('テニス', 180000), ('テニス', 20000)], ('テニス合計', '=SUBTOTAL(9,B9:B10)')], ('総計', '=SUBTOTAL(9,B2:B10)')] def write_data(sheet, data, row=1, level=0): print(sheet, data, row, level) _row = row for item in data: if isinstance(item, tuple): for col in range(len(item)): sheet.cell(_row, col+1, value=item[col]) sheet.row_dimensions[_row] = RowDimension(sheet, index=_row, outline_level=level, hidden=(level != 0)) _row += 1 continue _row += write_data(sheet, item, row=_row, level=level+1) wrote_count = _row - row return wrote_count book = Workbook() sheet = book.active write_data(sheet, data) book.save('grouping.xlsx')
dataはワークシートのデータ リストに小計を挿入するをもとにしました。
tupleがExcelの行に対応し、listはグループに対応します。集計行を手で書いているのがいけてないです。
write_data関数が再起呼び出しになっています。
ポイントは、Worksheetオブジェクトのrow_dimensionsプロパティへRowDimensionオブジェクトをセットするところです。
row_dimensionsプロパティは辞書のようなオブジェクトです。キーがかぶらなければいいだろうということで、行番号をキーとして使用しています。
プログラムを実行すると、次のようなExcelファイルが出力されます。
出力直後はすべて折り畳まれた状態(1行目と12行目のみ表示された状態)です。
イマイチ歪な方法ではありますが、Excelの小計機能相当のプログラムが書けました。
さらに発展させて、集計結果に対して関数を適用するなども可能かと思います。
参考
openpyxl
0 件のコメント:
コメントを投稿