openpyxl python3——格式化整行会导致奇怪的行为
我正在使用pivot表格的XLSX文件,并编写一个脚本,将它们解析为每个选项卡的一个新文件 由于openpyxl默认不支持透视表,我需要做一些工作来重新插入在复制过程中丢失的透视“样式” 为此,我遍历每一行和每一列,查找第0列中的值openpyxl python3——格式化整行会导致奇怪的行为,python,openpyxl,Python,Openpyxl,我正在使用pivot表格的XLSX文件,并编写一个脚本,将它们解析为每个选项卡的一个新文件 由于openpyxl默认不支持透视表,我需要做一些工作来重新插入在复制过程中丢失的透视“样式” 为此,我遍历每一行和每一列,查找第0列中的值Total。找到后,该行应更改为allbold=True 相反,我会收到不稳定的行为,有时会在第一个None之后加粗所有单元格。我的print('bolding totals')消息显示它正在正确计算每一行/单元格。我是不是有点头晕目眩,把我的环上的凹痕弄得乱七八糟
Total
。找到后,该行应更改为allbold=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处理样式中的一个bug。我运行了另一个非常简单的编辑,得到了奇怪的行为 如果我们有一个粗体/非粗体单元格的简单布局。 然后我们运行这个简单的命令来更改一个单元格:
>>> new_wb.worksheets[0].cell(row=10,column=0).style.font.bold = False
整个列(而不仅仅是单元格)的输出更改。在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')
您好,
openpyxl
中的bug对我来说并不太令人震惊。我以前对它有意见。对我来说,通过COM端口驱动Excel直接重写整个应用程序比修复openpyxl
更容易。这是我的帖子,有一个答案;希望它能有所帮助:我投票决定结束这个问题,尽管它写得很好,也很有趣,因为:(a)它没有答案,不管是否被接受;(b) 与实际输出和期望输出的链接失效;(c) OP已近两年没有访问过;(d) 任何相关的openpyxl错误现在都可能已经修复;(e)这仍然是一个悬而未决的问题,尽管它现在实际上无法回答。@AleksanderLidtke我不记得有关于这个问题的错误报告。您的评论似乎暗示openpyxl非常有缺陷,我认为这是不公平的。当然,如果可以的话,直接使用Excel是很好的。您可能还想看看xlwings如何做到这一点。