如何通过Streamlit的file_uploader向用户选择的CSV文件写入数据?
解决Streamlit中无法将数据写入上传CSV文件的问题
问题根源
file_uploader返回只读对象:你拿到的file是Streamlit的UploadedFile类型,仅支持读取操作,不允许直接写入,所以file.write()或dataframe.to_csv(file)必然报错。- 数据格式不匹配:代码里的
dataframe是Python字典,不是pandas的DataFrame,就算对象支持写入,to_csv方法也无法直接作用在字典上。
正确解决思路
Web应用无法直接修改用户本地文件,正确流程是:
- 在内存中处理数据(合并原有数据与新数据/编辑后的数据)
- 生成新的CSV内容,通过下载按钮让用户保存到本地
完整代码示例
1. 基础版:合并原有数据与新数据并提供下载
import pandas as pd import streamlit as st FILE_TYPES = ["csv"] file = st.file_uploader("Upload .csv file", type=FILE_TYPES) if file is not None: # 读取上传的原有数据 original_data = pd.read_csv(file) st.dataframe(original_data.head(10)) # 将字典转为pandas DataFrame new_data_dict = { "DateTime": ["ss"], "Name": ["s"], "Email": ["ese"], "Target User": ["csc"], "Alternate Target": ["dsd"], "Questions": ["ese"] } new_data = pd.DataFrame(new_data_dict) # 合并原有数据与新数据(如需追加则用此步骤,不需要可跳过) combined_data = pd.concat([original_data, new_data], ignore_index=True) # 生成CSV二进制内容 csv_content = combined_data.to_csv(index=False).encode('utf-8') # 提供下载按钮 st.download_button( label="下载修改后的CSV", data=csv_content, file_name="modified_data.csv", mime="text/csv" )
2. 适配AgGrid的版本
如果要将AgGrid中编辑后的数据导出,只需替换数据来源为AgGrid返回的结果:
import pandas as pd import streamlit as st from st_aggrid import AgGrid, GridUpdateMode FILE_TYPES = ["csv"] file = st.file_uploader("Upload .csv file", type=FILE_TYPES) if file is not None: original_data = pd.read_csv(file) # 渲染可编辑的AgGrid grid_response = AgGrid( original_data, editable=True, update_mode=GridUpdateMode.MODEL_CHANGED, height=300, width='100%' ) # 获取AgGrid中编辑后的DataFrame edited_data = grid_response['data'] # 生成CSV并提供下载 csv_content = edited_data.to_csv(index=False).encode('utf-8') st.download_button( label="下载编辑后的CSV", data=csv_content, file_name="edited_data.csv", mime="text/csv" )
关键注意点
- 禁止直接对
file_uploader返回的对象执行写入操作,它的设计仅用于读取。 - 所有数据处理都在内存中完成,最终通过下载按钮让用户主动保存修改后的文件。
- 合并数据时确保新旧数据的列名、格式一致,避免出现拼接错误。
内容的提问来源于stack exchange,提问作者Hilal
相关产品推荐
相关产品推荐

