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.")
代码说明
- 表单同步机制:点击表单的
submit_button时,会自动将表单内所有组件的当前值同步到Session State,包括输入框中未确认的内容,确保下载时使用最新文件名。 - 动态按钮key:给
download_button添加包含文件名的动态key,避免Streamlit缓存旧的按钮状态,确保每次文件名变化时按钮能正确响应。 - 默认值处理:若用户输入空文件名,自动回退到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
相关产品推荐
相关产品推荐

