generated at
openpyxl
PythonExcelファイルを作ったり編集したりできるライブラリ。


バージョンごとの大きな変更
2.3.5Apr 12, 2016
2.4.0Sep 15, 2016
2.5.0Jan 24, 2018セルのコピーができるようになった
2.6.0Feb 7, 2019readでチャートを読み込むようになった(編集はできない)/ sharedStrings.xmlの生成を行わなくなった
2.6.4Sep 25, 2019bug fixes
3.0.0Sep 26, 2019Py2終了、Py3のみ対応
3.0.3Jan 11, 2020bug fixes

はまったこと
2.3.5 => 2.4.1にしたらStyle周りのAPIが変わっていてスタイルが壊れた
2.3.5ではセルのコピーができない。2.5.0 以降にあげればできる
2.6.x 以降で sharedStrings.xml が生成されなくなって困ったので、2.5.14にバージョンダウンした

Excelの行挿入でスタイルが壊れる
openpyxlで行を挿入すると、セル結合の状態、行の高さ、計算式は、元々の行番号に適用されるため、ずれる
Excelでは通常、追加してずれた行にスタイルも追従して適用される
python
def hogehoge(worksheet, start_idx: int, add_row_count: int): # 行追加の開始行から、追加する行数分だけ追加する worksheet.insert_rows(idx=start_idx, amount=add_row_count) # 追加した行にスタイルを適用する _copy_styles(worksheet=worksheet, add_row_count=add_row_count) # このあと、セル結合、行の高さなどを修正する必要がある # 43行目の高さを14ピクセルにし、 (43 + 追加行 - 2)行目の高さを4ピクセルにする # レイアウトの関係から、43行目だけ高さが短いので、移動先の高さを変更する worksheet.row_dimensions[43].height = 14.25 worksheet.row_dimensions[43 + add_row_count].height = 4.5 def _copy_styles(worksheet, add_row_count: int): """ セルのスタイルをコピーする :param worksheet: Worksheetオブジェクト :param add_row_count: 追加した行数 """ org_cells = worksheet['A35:R35'] # 行追加の直前の行のスタイルを適用する start_row_no = 36 # 行追加の開始行 for org_cell in org_cells[0]: # 更新対象の列を取得 column = org_cell.column # 列単位でスタイルを適用 for i in range(add_row_count): row_no = start_row_no + i # スタイルを適用する new_cell = worksheet.cell(row=row_no, column=column) new_cell.font = org_cell.font.copy() new_cell.border = org_cell.border.copy() new_cell.fill = org_cell.fill.copy() new_cell.number_format = org_cell.number_format new_cell.protection = org_cell.protection.copy() new_cell.alignment = org_cell.alignment.copy()

Excelのセルのスタイルを複製する
python
def get_style(cell: openpyxl.cell.Cell) -> openpyxl.styles.Style: """セルのスタイルをまとめて返す cell.styleはUserWarningになる。 :param cell: 対象のセルオブジェクト :return: スタイルオブジェクト """ ret = { "font": cell.font.copy(), "fill": cell.fill.copy(), "border": cell.border.copy(), "alignment": cell.alignment.copy(), "number_format": cell.number_format, "protection": cell.protection.copy(), } return ret def copy_cell(dst_cell: openpyxl.cell.Cell, src_cell: openpyxl.cell.Cell): """セルの値とスタイルをコピーする :param dst_cell: コピー先のセルオブジェクト :param src_cell: コピー元のセルオブジェクト """ dst_cell.value = src_cell.value st = get_style(src_cell) dst_cell.font = st.get("font", None) dst_cell.fill = st.get("fill", None) dst_cell.border = st.get("border", None) dst_cell.alignment = st.get("alignment", None) dst_cell.number_format = st.get("number_format", None) dst_cell.protection = st.get("protection", None) return dst_cell

Excelのセル結合でExcelファイルが壊れる
openpyxl (2.6.4)
セル結合で、結合対象セルの一部が既に別のセルと結合されている場合に発生
エラーにならずファイルも作成されますが、MS Excel で開くと破損ファイルになる

Excelの印刷領域設定
python
# 印刷領域を設定 worksheet.print_area = "A1:S{}".format(default_max_row + add_row_count) # 1ページにする worksheet.sheet_properties.pageSetUpPr = PageSetupProperties(fitToPage=True, autoPageBreaks=False)

Excel上でマクロ記録を行って修正するプロパティを見つけ、openpyxlの公式で探した

Excelの画像が消える1
Pillowが環境にインストールされていないと、画像が消える
python
import openpyxl o = openpyxl.open('sample.xlsx') o.save('foo.xlsx')
このコードをPillowあり、なし、環境で実行しすると以下の結果になる
Pillowなし環境: 画像が消えた、警告等は表示されない
Pillowあり環境: 画像が維持された

Excelの画像が消える2
wmf(ウインドウズメタファイル)形式の画像は、消える
Excel上で画像を右クリックして、メニューに「図の編集」が表示されるものが wmf形式
対処方法としては、wmf形式 の画像を通常の画像に置き換える

Excelの画像が消える3
元のExcelにshapes, drawingsが含まれていると、全てのshapeや画像が消える
画像が巻き添えで消えてしまうのが悲しい
shapes, drawingsが一つでもあると、以下のメッセージが表示される
UserWarning: DrawingML support is incomplete and limited to charts and images only. Shapes and drawings will be lost.
対処方法としては、shapes, drawingsを使わない