Python - 如何防止for循环覆盖相同的excel表
Posted
技术标签:
【中文标题】Python - 如何防止for循环覆盖相同的excel表【英文标题】:Python - How to prevent for loop overwriting same excel sheet 【发布时间】:2018-11-21 16:55:22 【问题描述】:最近我一直在做我的小项目,该项目会为我自动生成工作时间电子表格。它只对我来说效果很好,但是当我想生成多个工作表(后来被称为工作表)和/或生成多个电子表格时,它会覆盖旧的。
为了打开、编辑和生成电子表格,我使用的是 openpyxl lib。
我尝试移动保存部分并在循环之外生成部分等,但这些都没有帮助我。
问题是如何防止 for 循环覆盖文件而不是生成新文件?
下面是该软件的主要部分。
cols = [2, 3, 4, 12]
row = 9
hrs = 0
nhrs = 0
for worker in workers:
sheet.title = (' '.format(worker.name, worker.surename))
for day, hday in itertools.zip_longest(days, holidays):
if day.weekday() <= 4 and day not in holydays:
sheet.cell(row=row, column=cols[0]).value = '08:00'
sheet.cell(row=row, column=cols[1]).value = '16:00'
sheet.cell(row=row, column=cols[2]).value = '8 h'
hrs += 8
row += 1
elif day.weekday() > 4 and day not in holidays:
sheet.cell(column=cols[0], row=row).value = ''
row += 1
elif day in holidays:
sheet.cell(column=cols[3], row=row).value = '8 h'
nhrs += 8
row += 1
sheet.cell(column=cols[2], row=40).value = str(hrs) + ' h'
sheet.cell(column=cols[3], row=40).value = str(nhrs) + ' h'
workbook.save('SPREADSHEET_.xlsx'.format(native_month))
print('Done')
提前致谢!
从评论编辑:
# native_month for the workbook name is provided by this function applied to a 1-12
def month_name_native(month):
months = ["Unknown", "Januar", "Februar", "Mart", "April", "Maj", "Jun",
"Jul", "August", "Septembar", "Oktobar", "Decembar" ]
return months[month].upper()
【问题讨论】:
native_month
是在哪里定义的?有变化吗?
关于Minimal, Complete, and Verifiable example,您的代码不完整 - 不包含,不创建工作簿,不向工作簿添加工作表,.....
本机月份是从函数(方法)month_name_native 返回的字符串,它将月份作为整数并以我的母语(塞尔维亚语)返回月份名称。请在评论中进一步找到代码 sn-p:def month_name_native(month):months = ["Unknown", "Januar", "Februar", "Mart", "April", "Maj", "Jun", "Jul ", "August", "Septembar", "Oktobar", "Decembar" ] 返回月份[月].upper()
【参考方案1】:
如果我的理解正确,您希望为每个工作人员提供一个新的电子表格,对吗?
您当前正在做的是一遍又一遍地使用同一个工作表对象,因此它被覆盖了。您必须在 for 循环中为每个工作人员创建一个新工作表。应该这样做:
cols = [2, 3, 4, 12]
row = 9
hrs = 0
nhrs = 0
workbook = Workbook() # assuming you imported openpyxl with *, else adjust
for worker in workers:
sheet = workbook.create_sheet(' '.format(worker.name, worker.surename))
for day, hday in itertools.zip_longest(days, holidays):
if day.weekday() <= 4 and day not in holydays:
sheet.cell(row=row, column=cols[0]).value = '08:00'
sheet.cell(row=row, column=cols[1]).value = '16:00'
sheet.cell(row=row, column=cols[2]).value = '8 h'
hrs += 8
row += 1
elif day.weekday() > 4 and day not in holidays:
sheet.cell(column=cols[0], row=row).value = ''
row += 1
elif day in holidays:
sheet.cell(column=cols[3], row=row).value = '8 h'
nhrs += 8
row += 1
sheet.cell(column=cols[2], row=40).value = str(hrs) + ' h'
sheet.cell(column=cols[3], row=40).value = str(nhrs) + ' h'
workbook.save('SPREADSHEET_.xlsx'.format(native_month))
print('Done')
【讨论】:
不错的猜测 - 应该帮助 OP 修复他的问题。不幸的是,此代码本身不会运行,因为 OP 未指定workers
、days
和 holidays
。伤心。
是的,这是正确的伴侣。唯一的事情是我正在加载预制的电子表格(因为样式)。所以基本上我想要实现的是一遍又一遍地加载相同的模板工作表并将其保存为单独的文件和/或工作表。
我明白了。你试过target = workbook.copy_worksheet(source)
我现在在 for 循环中使用了 target = workbook.copy_worksheet(source)
,它按预期生成了新的工作表。剩下的唯一问题是如何为每个工人重置行,因为现在在第二个工人的工作表中它从第 39 行左右开始......
这很简单。而不是row
,而是使用另一个变量来跟踪每个worker的行(例如addRow+=1
),并且在worker for循环开始时初始化为0。然后在 .cell 方法中使用row=row+addRow
而不是row=row
。 PS:赞赏我的答案/cmets ;-)以上是关于Python - 如何防止for循环覆盖相同的excel表的主要内容,如果未能解决你的问题,请参考以下文章
如何防止在 Python 中使用 FTPLIB 覆盖现有文件?