公式サイトには列のグルーピングについては記載されていましたが、行のグルーピングについては記載されていませんでした。
ソースを参照しながら工夫したらどうにかできたので公開します。
今後公式から行のグルーピングについてアナウンスされるかもしれませんので、ご留意ください。
以下、ソースです。
# -*- 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 件のコメント:
コメントを投稿