openpyxl python3 - 格式化整行ellicits奇怪的行为

时间:2013-07-30 19:02:36

标签: python openpyxl

我正在使用pivot-tabled XLSX文件并编写脚本来将它们解析为每个选项卡的新文件。

由于openpyxl默认情况下不支持数据透视表,我需要做一些工作来重新插入在复制过程中丢失的数据透视“样式”。

要执行此操作,我将遍历每一行和col,在第0列中查找值Total。一旦找到,该行应更改为全部bold=True

相反,我会收到不稳定的行为,有时会在第一个None之后加粗所有单元格。我的print('bolding totals')消息显示它正在正确评估每一行/单元格。我可能会bone bone and and and and and and screw???????????

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处理中的一个错误。我运行了另一个非常简单的编辑并且出现了奇怪的行为。

如果我们使用粗体/非粗体单元格进行简单布局。 然后我们运行这个简单的命令来改变一个单元格:

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

整个列的输出更改,而不是单独的单元格。

1 个答案:

答案 0 :(得分:7)

在openpyxl 2.0之前,单元格之间共享单元格样式:这是使用源XML中的指针实现的保留:两个(或更多)单元格都使用样式" 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')