如何借助Streamlit Session State实现多页面共享上传Excel文件
解决Streamlit多页面共享已上传Excel文件的问题
核心思路
用Streamlit内置的st.session_state跨页面共享上传后的DataFrame,主页面上传文件后将原始数据存入session_state,其他页面直接读取该共享数据,无需重复上传。
修改步骤
- 主页面上传文件后,把原始DataFrame存入
st.session_state(避免后续页面修改数据影响其他页面) - 其他页面先检查session_state中是否存在共享数据,存在则直接使用,不存在则提示用户前往主页面上传
- 移除其他页面的文件上传组件,或保留组件但提示无需重复操作
修改后的代码示例
主页面代码
import streamlit as st import pandas as pd import numpy as np # 重置功能:清空session_state并刷新页面 if st.sidebar.button("Reset Page"): for key in st.session_state.keys(): del st.session_state[key] st.experimental_rerun() st.image('https://wallpapercave.com/wp/9WBdkYu.jpg') st.title('Excel Drag and Drop') uploaded_file = st.file_uploader('Please upload your Excel File') if uploaded_file: # 读取原始数据并存入session_state raw_df = pd.read_excel(uploaded_file) st.session_state['uploaded_df'] = raw_df.copy() # 主页面System Three处理逻辑 df = raw_df.copy() st.subheader('System Three Selections') df.drop(df[df["Country"] == "South Africa"].index, inplace=True) df = df.drop('Date', axis=1) df.replace('-', 0, inplace=True) df["Win Result"] = df["Win Result"].replace(["L"], -1) df["True Odds"] = np.where(df["BSP"].ne(0), df["BSP"].sub(1), 0) df["ProfitLoss"] = np.where(df["Win Result"].eq(-1), df["Win Result"], df["True Odds"]) df.replace('-', 0, inplace=True) df.loc[df['Win Result'] == 0, 'True Odds'] = 0 df.replace('-', 0, inplace=True) df.loc[df['BSP'] == 0, 'ProfitLoss'] = 0 df.loc[df['Win Result'] == 0, 'ProfitLoss'] = 0 df = df[(df['Country'] == 'United Kingdom') & (df['WFF Rank'] == 1) & (df['OR'] >= 100) & (df['BSP'].between(1.5, 30)) ] df.loc["Total", "ProfitLoss"] = df.ProfitLoss.sum() st.write(df)
Page1代码
import streamlit as st import pandas as pd import numpy as np st.set_page_config(layout="wide") # 重置功能:清空session_state并刷新页面 if st.sidebar.button("Reset Page"): for key in st.session_state.keys(): del st.session_state[key] st.experimental_rerun() st.image('https://wallpapercave.com/wp/9WBdkYu.jpg') st.title('Excel Drag and Drop') # 检查是否有共享数据 if 'uploaded_df' in st.session_state: # 读取共享的原始数据 raw_df = st.session_state['uploaded_df'] st.success("已使用主页面上传的Excel文件") # Page1的System Two处理逻辑 df = raw_df.copy() st.subheader('System Two Selections') df['Last Form'] = pd.to_numeric(df['Last Form'].replace({'U': '', 'C': '', 'B':'', 'D': '', 'F': '', '-': 0, 'P': '', 'R': '', 'S': '', 'V': ''}), errors='coerce') df.drop(df[df["Country"] == "South Africa"].index, inplace=True) df = df[~df['Venue'].isin(['Kempton', 'Kilbeggan', 'Kilarney', 'Leicester', 'Leopardstown', 'Limerick', 'Aintree'])] df = df[~df['Race Distance'].isin(['1m 6f 17', '1m 6y'])] df.replace('-', 0, inplace=True) df["Win Result"] = df["Win Result"].replace(["L"], -1) df["True Odds"] = np.where(df["BSP"].ne(0), df["BSP"].sub(1), 0) df["ProfitLoss"] = np.where(df["Win Result"].eq(-1), df["Win Result"], df["True Odds"]) df.loc[df['Win Result'] == 0, 'True Odds'] = 0 df.replace('-', 0, inplace=True) df.loc[df['BSP'] == 0, 'ProfitLoss'] = 0 df.loc[df['Win Result'] == 0, 'ProfitLoss'] = 0 df = df[(df['Country'] == 'United Kingdom') & (df['WFF Rank'] == 1) & (df['Last Form'].between(0, 3, inclusive=False)) & (df['Class Change'] >= 0) & (df['Improving Horse'] == 'Y') & (df['RDB Rating'] >= 140) & (df['Age'] <= 7) & (df['Runner Count'] <= 20) & (df['RDB Rank'] == 1) ] df.loc["Total", "ProfitLoss"] = df.ProfitLoss.sum() st.write(df) st.download_button(label='Download System 2', data=df.to_csv(), mime='text/csv') else: st.warning("请先到主页面上传Excel文件")
关键说明
- 存储原始DataFrame到session_state,每个页面基于副本做独立处理,避免页面间数据互相干扰
- 重置按钮改用Streamlit原生的
st.experimental_rerun(),比pyautogui刷新更符合框架交互逻辑 - Page2至Page5可完全参照Page1的逻辑修改,实现统一的共享数据读取逻辑
内容的提问来源于stack exchange,提问作者liambh
相关产品推荐
相关产品推荐

