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

Streamlit下载按钮无法自动识别文本输入的自定义文件名变更

解决Streamlit下载按钮未实时获取文本输入框文件名的问题

问题核心:在Streamlit应用中,用户修改文件名输入框后直接点击下载按钮,输入的新文件名不会生效,必须按下回车或点击输入框外部确认后才能触发更新。

问题根源

Streamlit的st.text_input组件默认仅在用户按下回车或点击输入框外部时,才会将输入值同步到Session State或返回最新值。直接点击下载按钮时,输入框的最新内容尚未被提交,导致下载逻辑仍使用旧的文件名。

解决方案:使用表单包裹输入框与下载按钮

通过st.form组件将文件名输入框和下载按钮包裹起来,表单的提交按钮会强制同步所有表单内组件的当前值,无需等待用户手动确认输入框内容。

修改后的核心代码片段:

if data_dicts:
    st.success("PDFs were parsed successfully.")
    
    # 生成Excel文件
    excel_data = create_excel(data_dicts)

    # 初始化文件名Session State
    if "file_name" not in st.session_state:
        st.session_state.file_name = "extracted_info"

    # 用表单包裹输入框和下载按钮,确保点击下载时同步输入值
    with st.form("download_form", clear_on_submit=False):
        # 文件名输入框
        file_name_input = st.text_input(
            "Enter the desired file name (without extension):", 
            value=st.session_state.file_name
        )
        
        # 表单提交按钮(作为下载触发按钮)
        submit_download = st.form_submit_button(label="Download Excel file")

        if submit_download and excel_data:
            # 获取当前输入的文件名,为空则用默认值
            current_file_name = file_name_input.strip() or st.session_state.file_name
            # 更新Session State以便下次使用
            st.session_state.file_name = current_file_name
            
            # 触发下载
            st.download_button(
                label="Download Excel file",
                data=excel_data,
                file_name=f"{current_file_name}.xlsx",
                mime="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
                # 给按钮加动态key,确保文件名变化时按钮状态更新
                key=f"download_btn_{current_file_name}"
            )
            st.success(f"Excel file '{current_file_name}.xlsx' was created successfully.")

代码说明

  1. 表单同步机制:点击表单的submit_button时,会自动将表单内所有组件的当前值同步到Session State,包括输入框中未确认的内容,确保下载时使用最新文件名。
  2. 动态按钮key:给download_button添加包含文件名的动态key,避免Streamlit缓存旧的按钮状态,确保每次文件名变化时按钮能正确响应。
  3. 默认值处理:若用户输入空文件名,自动回退到Session State中保存的默认值。

替代方案:实时同步输入框值(无需表单)

如果不想使用表单,可以在每次脚本运行时直接将输入框的返回值同步到Session State,但这种方法仍需用户确认输入(回车/失焦)才能生效,仅适用于不需要实时响应的场景:

if data_dicts:
    st.success("PDFs were parsed successfully.")
    excel_data = create_excel(data_dicts)

    if "file_name" not in st.session_state:
        st.session_state.file_name = "extracted_info"

    # 实时同步输入框值到Session State
    file_name = st.text_input(
        "Enter the desired file name (without extension):", 
        value=st.session_state.file_name
    )
    st.session_state.file_name = file_name.strip() or "extracted_info"

    if excel_data:
        if st.download_button(
            label="Download Excel file",
            data=excel_data,
            file_name=f"{st.session_state.file_name}.xlsx",
            mime="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
            key=f"download_btn_{st.session_state.file_name}"
        ):
            st.success(f"Excel file '{st.session_state.file_name}.xlsx' was created successfully.")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 06:17:02