我已经知道了以下方法(链接这里):
server = Flask(__name__)
app = dash.Dash(server=server)
@server.route("/download/<path:path>")
def download(path):
"""Serve a file from the upload directory."""
return send_from_directory(UPLOAD_DIRECTORY, path, as_attachment=True)但问题是,当我使用Plotly建议的多页面方法时(链接这里 (下面是“构建多页应用程序”- index.py)):
app.layout = html.Div([
dcc.Location(id='url', refresh=False),
html.Div(id='page-content')
])
@app.callback(Output('page-content', 'children'),
[Input('url', 'pathname')])
def display_page(pathname):
if pathname == '/apps/app1':
return app1.layout
elif pathname == '/apps/app2':
return app2.layout
else:
return '404'我不能使用server.route,因为它将被上面所示的callback捕获。
使文件仍然可下载的最佳方法是什么?
发布于 2020-04-09 16:49:42
发布于 2021-04-12 23:24:29
我想出来了
注意,目录阶段是存储临时下载文件的地方。
首先,这是我的目录树的样子:
root
|
|---apps
| └── main.py
|---assets
|---layouts
| |--layout.py
| └── error.py
|---stage
|---app.py
|---functions.py
└── index.py这就是我的index.py的样子
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State
from app import app
from apps import main
app.layout = html.Div(
[dcc.Location(id="url", refresh=False), html.Div(id="page-content")]
)
@app.callback(Output("page-content", "children"), [Input("url", "pathname")])
def display_page(pathname):
if pathname == "/main":
return main.layout
else:
return main.error_page
if __name__ == "__main__":
app.run_server(debug=True, host="llp-lnx-dt-10200", port=15021)在functions.py中,我将动态生成一个仪表符表+带有要下载的链接的html.A(...,该函数是
def display_final_results(table):
import dash_html_components as html
import dash_core_components as dcc
import dash_table
import pandas as pd
return html.Div(
[
html.H5("""File processed and stuff worked"""),
dash_table.DataTable(
id="result_table",
data=table.iloc[:20, :].to_dict("records"),
columns=[{"name": i, "id": i} for i in list(table)],
),
html.Hr(),
dcc.Store(id="result_vault", data=table.to_dict()),
html.A(id="download_link", children=html.Button(children="Download")),
]
)在main.py中,我调用传递给表的函数def_final_results(table),这是我想要显示在仪表符表中的表,也是下载的链接。
下面是main.py中的回调,后面跟着app.server.route()
@app.callback(
Output("download_link", "href"),
[Input("result_vault","data"),
Input("h5_filename", "children")]
)
def return_download_link(data, upload_filename):
shutil.rmtree("stage")
os.mkdir("stage")
target = pd.DataFrame(data)
download_filename = upload_filename.split(":")[1].strip() + f"""_{filestamp()}.xlsx"""
uri = f"""stage/{download_filename}"""
target.to_excel(
uri, engine="xlsxwriter", index=False, header=True, sheet_name="results"
)
return uri
@app.server.route("/stage/<path:path>")
def serve_static(path):
root_dir = os.getcwd()
return flask.send_from_directory(os.path.join(root_dir, "stage"), filename=path)在main.py中,表target保存到目录/stage中,uri对象(即文件的路径)被发送到以id download_link作为href属性的对象,这是文件/stage中的html.A(...我返回了href,因为download属性对我不起作用。
我犯的一个大错误是,我的index.py dcc.Location url曾经是:
if pathname == "apps/main":
return main.layout因此,每次路由都会转到https://llp-lnx-dt-10200:15021/apps/stage/filename而不是https://llp-lnx-dt-10200:15021/stage/filename。
通过将应用程序从url中删除,问题得到了迅速解决。
https://stackoverflow.com/questions/61124604
复制相似问题