我想通了
请注意,目录阶段是存储我的临时下载文件的位置
首先这是我的目录树的样子:
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中我会动态生成一个dash-table + 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),传入了我想在dash-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对象是文件/stage/filename+filestamp的路径被发送到ID为download_link的对象作为href 属性,这是文件functions.py 中的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 中删除应用程序,问题很快得到解决。