web-dev-qa-db-ja.com

Excelスプレッドシートのいくつかの条件を満たす行を削除するにはどうすればよいですか?

Excel(xlsx)スプレッドシートの「縮小」バージョンを作成したいのですが(つまり、何らかの基準に従っていくつかの行を削除することによって)、これがopenpyxlで実行できるかどうかを知りたいのです。

(pythonish)擬似コードでは、私がやりたいことは次のようになります。

wb = openpyxl.reader.Excel.load_workbook('/path/to/workbook.xlsx')
sh = wb.get_sheet_by_name('someworksheet')

# weed out the rows of sh according to somecriterion
sh.rows[:] = [r for r in sh.rows if somecriterion(r)]

# save the workbook, with the weeded-out sheet
wb.save('/path/to/workbook_reduced.xlsx')

このようなことはopenpyxlで実行できますか?もしそうなら、どのように実行しますか?

12
kjo

2018年の更新:今日、行を削除する方法を探していたところ、openpyxl2.5.0-b2に機能が追加されていることがわかりました。試してみたところ、完璧に機能しました。答えを見つけたリンクは次のとおりです: https://bitbucket.org/openpyxl/openpyxl/issues/964/delete_rows-does-not-work-on-deleting

そして、1つの行を削除する構文は次のとおりです。

ws.delete_rows(index, 1)

ここで、「ws」はワークシート、「index」は行番号、「1」は削除する行数です。

列を削除する機能もありますが、私はそれを試していません。

9
jhughs

内部的には、openpyxlには「行」の概念がないようです。セルで機能し、次元を追跡します。 _Worksheet.rows_ を使用すると、次の2D配列が計算されます。その中の細胞。配列を変更することはできますが、ワークシートは変更されません。

ワークシート内でこれを行う場合は、古い位置から新しい位置に値をコピーし、不要になったセルの値を_''_またはNoneに設定する必要があります。 Worksheet.garbage_collect() を呼び出します。

データセットが小さく、性質が均一である場合(たとえば、すべての文字列)、関連するセル(コンテンツ)を新しいワークシートにコピーし、古いワークシートを削除して、新しいセルのタイトルをちょうどのタイトルに設定する方がよい場合があります。 1つ削除しました。

最も洗練された方法であるIMHOは、Worksheetまたはサブクラスを_delete_rows_メソッドで拡張することです。 Cellsの座標を変更することで、このようなメソッドを実装します。しかし、openpyxlの内部が変更された場合、これは壊れることがあります。

3
Anthon