Dash Plotly点击按钮无法下载处理后Excel文件的问题求助
解决Dash应用无法下载处理后Excel文件的问题
你的代码目前缺少下载功能的核心逻辑:没有存储处理后的DataFrame,也没有针对下载按钮的回调来生成并返回Excel文件。以下是具体修改方案:
关键修改点
- 添加
dcc.Store组件持久化存储处理后的DataFrame(Dash是无状态框架,需要临时存储数据供后续回调调用) - 新增下载按钮的回调函数,将存储的DataFrame转换为Excel字节流返回给用户
- 修复重复初始化Dash应用的冗余代码
修改后的完整代码
import base64 import io import dash from dash.dependencies import Input, Output, State from dash import dcc, html import plotly.express as px import pandas as pd # 修复重复初始化问题 app = dash.Dash(prevent_initial_callbacks=True) app.layout = html.Div([ html.H1('Convertion of FMS logdata to parced data'), dcc.Upload( id='upload-data', children=html.Div([ 'Drag and Drop or ', html.B('Select Files') ]), style={ 'width': '100%', 'height': '60px', 'lineHeight': '60px', 'borderWidth': '1px', 'borderStyle': 'dashed', 'borderRadius': '5px', 'textAlign': 'center', 'margin': '10px' }, multiple=True ), # 添加Store组件存储处理后的DataFrame(以JSON格式保存) dcc.Store(id='processed-data', data={}), html.Div(id='output-data-upload'), html.Div([ html.Button("Download xlsx", id="btn"), dcc.Download(id="download") ]) ]) def parse_contents(contents, filename): content_type, content_string = contents.split(',') decoded = base64.b64decode(content_string) df2 = pd.read_excel(io.BytesIO(decoded), skiprows=8, usecols=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11]) # 返回图表组件和处理后的DataFrame的JSON格式 return html.Div([ html.P(f'File: {filename} - Analog Input2 with Respect to Timestamp'), dcc.Graph(figure=px.scatter(df2, x="Speed", y="Longitude")) ]), df2.to_json(date_format='iso', orient='split') @app.callback( [Output('output-data-upload', 'children'), Output('processed-data', 'data')], Input('upload-data', 'contents'), State('upload-data', 'filename'), State('upload-data', 'last_modified') ) def update_output(list_of_contents, list_of_names, list_of_dates): if list_of_contents is not None: children = [] processed_data = {} for c, n, d in zip(list_of_contents, list_of_names, list_of_dates): component, df_json = parse_contents(c, n) children.append(component) processed_data[n] = df_json return children, processed_data return [], {} @app.callback( Output("download", "data"), Input("btn", "n_clicks"), State("processed-data", "data"), prevent_initial_call=True ) def download_excel(n_clicks, processed_data): if not processed_data: return dash.no_update # 创建Excel文件,每个上传的文件对应一个sheet output = io.BytesIO() with pd.ExcelWriter(output, engine='xlsxwriter') as writer: for filename, df_json in processed_data.items(): df = pd.read_json(df_json, orient='split') # 去掉文件名的后缀作为sheet名 sheet_name = filename.rsplit('.', 1)[0] df.to_excel(writer, sheet_name=sheet_name, index=False) output.seek(0) # 返回下载的Excel文件 return dcc.send_bytes(output.getvalue(), "processed_data.xlsx") if __name__ == '__main__': app.run_server(debug=True)
代码说明
dcc.Store组件:将每个上传文件处理后的DataFrame以JSON格式存储,供下载回调读取- 下载回调函数:
- 从Store中读取所有处理后的DataFrame
- 使用
pd.ExcelWriter将多个DataFrame写入同一个Excel文件的不同sheet(如果上传多个文件) - 通过
dcc.send_bytes返回Excel字节流,触发浏览器下载
- 修复冗余代码:移除了重复的
app = dash.Dash()初始化语句
内容的提问来源于stack exchange,提问作者aparna podili
相关产品推荐
相关产品推荐

