You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AgGrid删除/更新行无法保存至本地DataFrame问题排查及咨询

问题1:删除行后数据未持久化的修复

你的代码存在几个关键问题导致删除后刷新数据恢复:

  • 前端JS删除仅修改了表格的前端展示,未触发后端数据同步;
  • 保存逻辑错误:if JsCode(string_to_delete)是无效判断,且df.append(df)会将数据重复写入,完全不符合需求;
  • 全局最后一行df.to_excel("Wi_Fi_DB.xlsx", index=False)会把原始读取的DataFrame重新写入文件,覆盖所有修改。

修正后的核心代码

import pandas as pd
import streamlit as st
from st_aggrid import AgGrid, GridOptionsBuilder, JsCode, GridUpdateMode

file_dir = r'C:\Users\....'  # 移除路径末尾反斜杠,避免转义错误
file_name = 'Wi_Fi_DB.xlsx'
filepath = f"{file_dir}/{file_name}"

def display_table(df: pd.DataFrame):
    sel_mode = st.selectbox('选择单行/多行', options=['single', 'multiple'])
    gb = GridOptionsBuilder.from_dataframe(df)
    # 统一配置选择模式,删除重复调用
    gb.configure_selection(selection_mode=sel_mode, use_checkbox=True)

    # 修正删除按钮JS逻辑:点击时选中当前行并执行删除
    string_to_delete = JsCode('''
        function(e) {
            let api = e.api;
            let rowNode = e.node;
            api.setNodesSelected([rowNode], true);
            let sel = api.getSelectedRows();
            api.applyTransaction({remove: sel});
        }
    ''')

    cell_button_delete = JsCode('''
        class BtnCellRenderer {
            init(params) {
                this.eGui = document.createElement('div');
                this.eGui.innerHTML = `
                 <span>
                    <style>
                    .btn {
                      background-color: #F94721;
                      border: none;
                      color: white;
                      font-size: 10px;
                      font-weight: bold;
                      height: 2.5em;
                      width: 8em;
                      cursor: pointer;
                    }
                    .btn:hover {
                      background-color: #FB6747;
                    }
                    </style>
                    <button class="btn">🗑️ Delete</button>
                 </span>
              `;
            }
            getGui() {
                return this.eGui;
            }
        };
    ''')

    gb.configure_column('Delete', headerTooltip='点击按钮删除行',
                        editable=False, filter=False, onCellClicked=string_to_delete,
                        cellRenderer=cell_button_delete,
                        autoHeight=True, suppressMovable=True)
    gb.configure_default_column(editable=True)
    grid_options = gb.build()

    # 设置更新模式,确保前端修改同步到后端
    grid_return = AgGrid(df, 
                         gridOptions=grid_options, 
                         allow_unsafe_jscode=True, 
                         theme="streamlit",
                         update_mode=GridUpdateMode.MODEL_CHANGED)
    
    # 点击按钮触发保存操作
    if st.button('保存修改'):
        updated_df = grid_return["data"]
        updated_df.to_excel(filepath, index=False)
        st.success('数据已成功保存!')
    return grid_return

# 读取文件并渲染表格
df = pd.read_excel(filepath)
st.info("选择行后点击删除按钮移除,最后点击保存修改")
response = display_table(df)

关键修改点说明

  • 移除未使用的js导入;
  • 修复路径字符串转义问题;
  • 统一选择模式配置,删除重复代码;
  • 调整删除按钮JS逻辑,确保点击时选中当前行,保证后端能捕获删除操作;
  • 设置update_mode=GridUpdateMode.MODEL_CHANGED,让前端修改同步到后端数据;
  • 替换错误的保存逻辑,用明确的按钮触发文件写入;
  • 删除全局末尾的df.to_excel,避免覆盖修改后的数据。
问题2:实现行更新并持久化到本地

行更新的实现逻辑和删除一致,核心是同步前端编辑到后端并写入文件:

  1. 确保gb.configure_default_column(editable=True)开启单元格编辑(你的代码已配置);
  2. 在AgGrid组件中设置update_mode=GridUpdateMode.MODEL_CHANGED,让前端编辑操作实时同步到后端;
  3. 通过grid_return["data"]获取编辑后的完整DataFrame;
  4. 点击「保存修改」按钮,将更新后的DataFrame写入本地Excel文件。

上述修正后的代码已包含行更新的完整逻辑,编辑单元格后点击保存按钮即可完成持久化。

内容的提问来源于stack exchange,提问作者Adnan Adnan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 23:30:48