10

私はピボットテーブルの XLSX ファイルを扱っており、それらを解析してタブごとに新しいファイルにするスクリプトを書いています。

デフォルトでは、openpyxl はピボット テーブルをサポートしていないため、コピー中に失われたピボットの「スタイル」を再挿入するためにいくつかの作業を行う必要があります。

これを行うには、各行と列を反復処理してTotal、列 0 の値を探します。見つかったら、行は all に変更されますbold=True

代わりに、最初のNone. 私のprint('bolding totals')メッセージは、各行/セルを正しく評価していることを示しています。おそらく、私は頭が悪く、ループのくぼみを台無しにしていますか?

from openpyxl import Workbook
from openpyxl import load_workbook
from copy import deepcopy

wb = load_workbook(filename=r'input.xlsx')

# Print 1
sheetlist = wb.get_sheet_names()
print(sheetlist)

for i in range(len(sheetlist)-1):
    dest_filename = r''+sheetlist[i]+'.xlsx'
    new_wb = Workbook()
    ws = wb.get_sheet_by_name(sheetlist[i])
    new_wb.add_sheet(ws, 0)

    for k in range(0, new_wb.worksheets[0].get_highest_row()):
        print(new_wb.worksheets[0].cell(row=k, column=0).value)
        # ignore empty cells
        if new_wb.worksheets[0].cell(row=k, column=0).value is not None:
            if 'Total' in new_wb.worksheets[0].cell(row=k, column=0).value:
                for j in range(0, new_wb.worksheets[0].get_highest_column()):
                    print('bolding totals, '+str(k), str(j))
                    new_wb.worksheets[0].cell(
                        row=k, column=j).style.font.bold = True
            elif 'Total' not in new_wb.worksheets[0].cell(row=k, column=0).value:
                for j in range(0, new_wb.worksheets[0].get_highest_column()):
                    print('not bolding anything')
                    new_wb.worksheets[0].cell(
                        row=k, column=j).style.font.bold = False

    # remove the blank sheet created in new_wb by openpyxl
    new_wb.remove_sheet(new_wb.get_sheet_by_name('Sheet'))
    print(new_wb.get_sheet_names())
    new_wb.save(dest_filename)
    break  # set to break after one sheet for testing

print('finished')

この時点で、これはスタイルの openpyxl 処理のバグであると思われます。別の非常に単純な編集を実行したところ、奇妙な動作が発生しました。

太字/非太字のセルを含む単純なレイアウトがある場合。次に、この単純なコマンドを実行して、1 つのセルを変更します。

>>> new_wb.worksheets[0].cell(row=10,column=0).style.font.bold = False

セルだけではなく、列全体の出力が変化します。

4

1 に答える 1

7

openpyxl 2.0 より前は、セル スタイルがセル間で共有されていました。これは、ソース XML でポインターを使用する実装からの持ち越しでした。2 つ (またはそれ以上) のセルは両方ともスタイル "1" を使用していました。1 つのセルでこのスタイルを変更すると、すべてのセルでスタイルが変更されることになり、ここで観察されている動作のように聞こえます。

それ以来、実装にはさまざまな変更がありましたが、1 つのセルのスタイルを変更する際の副作用はなくなりました。重要な変更点は、書式設定オブジェクトFontが直接利用可能で、スタイルでラップする必要がないことです。

他にもいくつかの変更がありました。ワークシートは、親ワークブックに保存されているデータに依存しているため、ワークブック間でコピーできません。

元のファイルがないと確信が持てませんが、次のコードは openpyxl >= 2.2 で動作するはずです。

from openpyxl import Workbook
from openpyxl import load_workbook

wb = load_workbook(filename='input.xlsx', read_only=True)

for sheet in wb.sheetnames:

    dest_filename = '{0}.xlsx'.format(sheet)
    new_wb = Workbook()
    del new_wb["Sheet"]

    ws1 = wb[sheet]
    ws2 = new_wb.create_sheet(sheet)

    for row in ws1:
        ws2.append([c.value for c in row])
        first = row[0]
        if first.data_type == "s" and "Total" in first.value:
            for idx in range(len(row)):
                cell = ws2.cell(row=ws2.max_row, column=idx+1)
                bolded = cell.font.copy(bold=True)
                cell.font = bolded

    new_wb.save(dest_filename)
    print("saving {0}".format(dest_filename))

print('finished')
于 2015-11-28T17:56:42.643 に答える