PyQt5实现表单按行导出追加Excel时数据错位为列且覆盖原内容
Excel写入功能异常修正方案
现存问题根因
- 数据结构构建错误:直接将一维列表传入
pd.DataFrame()时,pandas会默认将其识别为单列多行的数据集,最终写入Excel后表现为竖排的列结构,而非目标的单行记录。 - 工作表名不匹配:创建空Excel时使用的工作表为带空格的
Sheet 1,但写入逻辑中部分代码引用了不带空格的Sheet1,无法定位到原有带表头的工作表,甚至会新建空白工作表。 - 文件覆盖逻辑错误:原代码未配置ExcelWriter的追加模式,默认会对整个目标文件进行覆盖写入,导致历史保存的所有内容被清空。
- 代码逻辑无效:原try分支中未初始化
writer对象就直接调用其属性,属于无法运行的无效代码,最终会触发异常进入except分支,执行覆盖写入操作。 - 字段读取笔误:Ok Mkt字段的读取逻辑错误绑定到了Fecha输入框,会导致该字段实际写入的是日期输入框的内容,数据错位。
修正后的核心实现代码
替换原有的Excel_information函数即可实现预期功能:
def Excel_information(self): # 读取表单输入,修正Ok Mkt字段的读取笔误 Fecha1 = str(self.Fecha.text()) Diasabiertos1 = str(self.Diasabiertos.text()) Nombredelcaso1 = str(self.Nombredelcaso.text()) Responsable1 = str(self.Responsable.text()) OkMkt1 = str(self.OkMkt.text()) Solicitudlotus1 = str(self.Solicitudlotus.text()) Os1 = str(self.Os.text()) Monto1 = str(self.Monto.text()) Fechacierre1 = str(self.Fechacierre.text()) Comentario1 = str(self.Comentario.text()) fill_form = [ Fecha1, Diasabiertos1, Nombredelcaso1, Responsable1, OkMkt1, Solicitudlotus1, Os1, Monto1, Fechacierre1, Comentario1 ] # 构建单行结构的DataFrame,列顺序与headers完全匹配 df = pd.DataFrame([fill_form], columns=headers) path = os.path.expanduser('~/Desktop') + r'\New.xlsx' try: # 配置ExcelWriter为追加模式,避免覆盖原有内容 with pd.ExcelWriter( path, engine='openpyxl', mode='a', if_sheet_exists='overlay' ) as writer: # 计算追加写入的起始行位置:原有数据行数+1 existing_rows = pd.read_excel(path, sheet_name='Sheet 1').shape[0] df.to_excel( writer, sheet_name='Sheet 1', index=False, header=False, startrow=existing_rows + 1 ) except FileNotFoundError: QMessageBox.warning(self, "提示", "请先生成基础空Excel文件后再写入数据")
运行注意事项
- 保持创建空Excel时的工作表名
Sheet 1与写入逻辑中引用的名称完全一致,避免出现工作表找不到的报错。 - 单行数据的字段顺序要与全局
headers列表顺序严格对应,防止数据列错位。 - 若使用的pandas版本低于1.4.0,不支持
if_sheet_exists参数,可替换为openpyxl直接操作单元格的写入逻辑:加载工作簿后定位到工作表最大行的下一行,逐列写入对应字段值即可。
内容的提问来源于stack exchange,提问作者Chub
相关产品推荐
相关产品推荐

