单击按钮即可在Dash中下载内存中生成的文件:如何提供文件名? [英] Dash download in-memory generated file on button click: How to give filename?

查看:59
本文介绍了单击按钮即可在Dash中下载内存中生成的文件:如何提供文件名?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我通过 pd.ExcelWriter BytesIO 为我的Python3.8仪表板应用程序中的click事件生成了一个内存 Excel文件.

I generate an in-memory Excel file via pd.ExcelWriter and BytesIO for a click event in my Python3.8 dash app.

一切正常.下载文件时,出现此弹出消息,询问我是否要继续下载/打开生成的文件.但是,弹出消息显示了这个(我猜是 base64 编码的)字符串(或路径?),例如 ... ydaHdjhgk328AAAAnxsAA == ,下载后,下载文件将获得(随机分配?)一组字符作为文件名(例如 ZySzsdn1.xlsx ).

Everything works as it should be. When I download my file I get this popup message asking me if I would like to continue to download/open the generated file. However, the popup message shows this (I guess base64 encoded) string (or path?), e.g. ...ydaHdjhgk328AAAAnxsAA== and after downloading the download gets a (randomly assigned?) set of characters as the filename (e.g. ZySzsdn1.xlsx).

我该如何调整它以便显示并将文件名分配给类似 download.xlsx 的文件?我的猜测是与 base64 编码的 href 有关.

How can I adjust this so it would display and assign the filename to something like download.xlsx? My guess is that is has something to do with the base64 encoded href.

生成excel文件的功能:

The function to generate the excel file:

def write_product_file():
    output = BytesIO()
    writer = pd.ExcelWriter(output, engine="xlsxwriter")
    upload_df = pd.DataFrame()
    upload_df.to_excel(writer, index=False, sheet_name="sheet1")
    writer.save()
    return output

我的Dash应用程序中的按钮:

The button in my Dash application:

html.Div(
  id="select-upload-form",
  style={"width": "100%"},
  children=[
    dbc.Button(
      "Download the upload form",
      id="download-excel",
      color="secondary",
      external_link="true",
      target="",
      href="",
    ),
  ],
),

最后是我的回叫:

@app.callback(
    [
        Output("download-excel", "href"),
        Output("download-excel", "color"),
        Output("download-excel", "target"),
    ],
    [Input("download-excel", "n_clicks")],
)
def download_template_file(n_clicks):
    if n_clicks:
        excelfile = write_product_file()
        excelfile.seek(0)
        media_type = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
        data = base64.b64encode(excelfile.read()).decode("utf-8")
        href_data = f"data:{media_type};base64,{data}"
        return href_data, "success", href_data,
    else:
        return None, "secondary", None

推荐答案

您可以使用dash-extensions软件包中的 Download 组件,

You could use the Download component from the dash-extensions package,

pip install dash-extensions == 0.0.18

语法更简单,并且具有 filename 参数.这是一个小例子,

The syntax is simpler, and it has a filename argument. Here is a small example,

import dash
import dash_html_components as html
import numpy as np
import pandas as pd

from dash.dependencies import Output, Input
from dash_extensions import Download
from dash_extensions.snippets import send_bytes

# Generate some example data.
data = np.column_stack((np.arange(10), np.arange(10) * 2))
df = pd.DataFrame(columns=["a column", "another column"], data=data)
# Create app.
app = dash.Dash(prevent_initial_callbacks=True)
app.layout = html.Div([html.Button("Download xlsx", id="btn"), Download(id="download")])


@app.callback(Output("download", "data"), [Input("btn", "n_clicks")])
def generate_xlsx(n_nlicks):

    def to_xlsx(bytes_io):
        xslx_writer = pd.ExcelWriter(bytes_io, engine="xlsxwriter")
        df.to_excel(xslx_writer, index=False, sheet_name="sheet1")
        xslx_writer.save()

    return send_bytes(to_xlsx, "some_name.xlsx")


if __name__ == '__main__':
    app.run_server()

免责声明:我是dash-extensions软件包的作者.

Disclaimer: I am the author of the dash-extensions package.

这篇关于单击按钮即可在Dash中下载内存中生成的文件:如何提供文件名?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆