如何使用openpyxl写入新空白单元格 解决固定起始位重复覆盖问题
问题核心原因分析
- 起始行号固定为7,每次运行都会先执行
counter +=1从第8行开始覆盖原有内容 - 存在无用的
for row in sheet.rows遍历逻辑冗余,没有实际作用还会降低运行效率 - 缺少输入异常处理,用户输入非数字内容时程序会直接报错退出
- 主动退出逻辑缺失,必须跑满1000次循环才会停止,无法中途主动终止录入
符合Python编码规范的最新版实现
import openpyxl def get_valid_input(prompt, input_type=str, allow_quit=True): """通用输入校验函数""" while True: user_input = input(prompt).strip() # 支持主动退出 if allow_quit and user_input.lower() == 'q': return None try: processed_input = input_type(user_input.capitalize() if input_type == str else user_input) return processed_input except ValueError: print(f"输入格式错误,请输入合法的{}类型内容,输入q可退出".format(input_type.__name__)) if __name__ == "__main__": file_path = 'Path/To/File/roster.xlsx' # 加载工作簿 roster = openpyxl.load_workbook(file_path) sheet = roster.active # 可根据实际表头占用的表头结束行号调整该常量 HEADER_END_ROW = 7 # 动态计算起始行:如果已有内容就从最后一行的下一行开始,没有内容就从表头下第一行开始 start_row = max(HEADER_END_ROW + 1, sheet.max_row + 1) while start_row < 1000: # 录入姓名类信息 fname = get_valid_input("请输入名字(输入q退出录入:") if fname is None: break lname = get_valid_input("请输入姓氏(输入q退出录入:") if lname is None: break # 录入数值类信息 grade = get_valid_input("请输入年级(输入q退出录入:", input_type=int) if grade is None: break attendance = get_valid_input("请输入出勤次数(输入q退出录入:", input_type=int) if attendance is None: break # 写入行数据写入 sheet[f'A{start_row}'] = start_row sheet[f'B{start_row}'] = fname sheet[f'C{start_row}'] = lname sheet[f'D{start_row}'] = grade sheet[f'E{start_row}'] = attendance start_row += 1 # 保存修改 roster.save(file_path) print(f"数据已保存,本次共新增{}条记录".format(start_row - max(HEADER_END_ROW + 1, sheet.max_row + 1)))
优化说明
- 动态计算起始行:通过openpyxl官方推荐的
sheet.max_row属性获取当前表格已使用的最大行号,自动从已有内容的下一行开始写入,完全避免覆盖原有数据 - 移除冗余逻辑:删除无意义的遍历行循环,大幅提升写入效率
- 鲁棒性提升:封装通用输入校验函数,支持异常捕获和主动退出逻辑,避免非法输入导致程序崩溃
- 符合PEP8编码规范:命名规范、注释清晰,通用逻辑单独封装,可维护性更高
- 没有使用已废弃的API,适配所有最新版openpyxl版本
内容的提问来源于stack exchange,提问作者SpamMeUpScottie
相关产品推荐
相关产品推荐

