使用下载组件
使用PlainDownloader
组件
Dash File Cache提供了一个定制化的组件,用来透过callback触发下载事件。
downloader = PlainDownloader(id: str)
以下代码对比了分别使用、和不使用PlainDownloader
的实现。这两种实现的效果是等价的。
- 使用Downloader
- 不使用Downloader
with_plain_downloader.py
import io
from typing import Optional
import dash
from dash import html
from dash import Output, Input
import dash_file_cache as dfc
app = dash.Dash("demo")
service = dfc.ServiceData(dfc.CachePlain(1))
service.serve(app)
app.layout = html.Div(
(
html.Div(html.Button(id="btn", children="Download")),
dfc.PlainDownloader(id="downloader")
)
)
@app.callback(Output("downloader", "url"), Input("btn", "n_clicks"))
def a_callback_creating_data(n_clicks: Optional[int]) -> str:
if not n_clicks:
return dash.no_update
address = service.register(
fobj=io.StringIO("test file data..."),
file_name="test.txt",
mime_type="text/plain",
one_time_service=True,
download=True,
)
return address
if __name__ == "__main__":
app.run()
without_downloader.py
import io
from typing import Optional
import dash
from dash import html
from dash import Output, Input
import dash_file_cache as dfc
app = dash.Dash("demo")
service = dfc.ServiceData(dfc.CachePlain(1))
service.serve(app)
app.layout = html.Div(
(
html.Div(html.Button(id="btn", children="Download")),
html.Div(id="downloader-js-finish-trigger", hidden=True),
html.Div(id="downloader-js-trigger", hidden=True),
html.Div(id="downloader-trigger", hidden=True),
)
)
@app.callback(Output("downloader-trigger", "children"), Input("btn", "n_clicks"))
def a_callback_creating_data(n_clicks: Optional[int]) -> str:
if not n_clicks:
return dash.no_update
address = service.register(
fobj=io.StringIO("test file data..."),
file_name="test.txt",
mime_type="text/plain",
one_time_service=True,
download=True,
)
return address
@app.callback(
Output("downloader-js-trigger", "children"),
Input("downloader-trigger", "children"),
prevent_initial_call=True,
)
def download_redirect(trigger: Optional[str]):
"""Trigger of download link redirection."""
if not trigger:
return dash.no_update
return trigger
app.clientside_callback(
"""
function (uri) {
var link = document.createElement("a");
link.setAttribute("download", "");
link.setAttribute("target", "_blank");
link.setAttribute("rel", "no-refresh");
link.href = uri;
document.body.appendChild(link);
link.click();
link.remove();
return "success";
}
""",
Output("downloader-js-finish-trigger", "children"),
Input("downloader-js-trigger", "children"),
prevent_initial_call=True,
)
if __name__ == "__main__":
app.run()
PlainDownloader(...)
是最简单的、用来提供下载功能的组件。透过触发属性url
的callback,可以立即触发一个下载事件。
PlainDownloader
背后实现的逻辑、和上例without_downloader.py
的做法是完全一致的。在触发url
的callback时,会临时创建一个不可见的<a>
标签、并自动点击它。下载事件开始后,就会移除该<a>
标签。标签所设的地址、由ServiceData(...)