下载作为字节流生成的 PDF 文件的 Dash 扩展问题
Dash extensions problem downloading PDF file generated as a byte stream
我有一个 Dash 应用程序,用户可以在其中与该应用程序交互,并且将使用 FPDF 生成 PDF。我正在尝试使用 Dash-extensions 包和下载选项转发要下载的 PDF,但出现错误。
我有生成 PDF 的功能:
def makeReport(info):
return create_pdf(info)
def create_pdf(info):
pdf = CustomPDF(format='letter')
for i, beam in enumerate(info):
pdf.addPage(info[i],i)
data = pdf.output(dest='S').encode('latin-1')
return data
那么这是下载按钮相关代码:
@app.callback(Output("download", "data"), [Input("download_btn", "n_clicks")], prevent_initial_call=True)
def sendPDF(n_clicks):
firstName, lastName, mrn = nameParser(patient)
fileName = lastName + ', ' + firstName + ' Cutout Factor Calc.pdf'
return send_bytes(makeReport(info), fileName)
def downloadButton():
return html.Div([html.Hr(),html.Button("Download Report", id="download_btn"), Download(id="download")])
点击按钮时出现的错误是:
send_bytes
实用函数期望将字节写入 BytesIO
对象的函数作为第一个参数,但是您向它传递的是字节字符串,因此您需要编写一个小的包装函数。这是一个演示如何完成的小例子,
import dash
import dash_html_components as html
from dash.dependencies import Output, Input
from dash_extensions import Download
from dash_extensions.snippets import send_bytes
from fpdf import FPDF
# Create example app.
app = dash.Dash(prevent_initial_callbacks=True)
app.layout = html.Div([html.Button("Download PDF", id="btn"), Download(id="download")])
def create_pdf(n_nlicks):
pdf = FPDF()
pdf.add_page()
pdf.set_font('Arial', 'B', 16)
pdf.cell(40, 10, f'Hello World! (n_clicks is {n_nlicks})')
return pdf
@app.callback(Output("download", "data"), [Input("btn", "n_clicks")])
def generate_xlsx(n_nlicks):
def write_pdf(bytes_io):
pdf = create_pdf(n_nlicks) # pass argument to PDF creation here
bytes_io.write(pdf.output(dest='S').encode('latin-1'))
return send_bytes(write_pdf, "some_name.pdf")
if __name__ == '__main__':
app.run_server()
我有一个 Dash 应用程序,用户可以在其中与该应用程序交互,并且将使用 FPDF 生成 PDF。我正在尝试使用 Dash-extensions 包和下载选项转发要下载的 PDF,但出现错误。
我有生成 PDF 的功能:
def makeReport(info):
return create_pdf(info)
def create_pdf(info):
pdf = CustomPDF(format='letter')
for i, beam in enumerate(info):
pdf.addPage(info[i],i)
data = pdf.output(dest='S').encode('latin-1')
return data
那么这是下载按钮相关代码:
@app.callback(Output("download", "data"), [Input("download_btn", "n_clicks")], prevent_initial_call=True)
def sendPDF(n_clicks):
firstName, lastName, mrn = nameParser(patient)
fileName = lastName + ', ' + firstName + ' Cutout Factor Calc.pdf'
return send_bytes(makeReport(info), fileName)
def downloadButton():
return html.Div([html.Hr(),html.Button("Download Report", id="download_btn"), Download(id="download")])
点击按钮时出现的错误是:
send_bytes
实用函数期望将字节写入 BytesIO
对象的函数作为第一个参数,但是您向它传递的是字节字符串,因此您需要编写一个小的包装函数。这是一个演示如何完成的小例子,
import dash
import dash_html_components as html
from dash.dependencies import Output, Input
from dash_extensions import Download
from dash_extensions.snippets import send_bytes
from fpdf import FPDF
# Create example app.
app = dash.Dash(prevent_initial_callbacks=True)
app.layout = html.Div([html.Button("Download PDF", id="btn"), Download(id="download")])
def create_pdf(n_nlicks):
pdf = FPDF()
pdf.add_page()
pdf.set_font('Arial', 'B', 16)
pdf.cell(40, 10, f'Hello World! (n_clicks is {n_nlicks})')
return pdf
@app.callback(Output("download", "data"), [Input("btn", "n_clicks")])
def generate_xlsx(n_nlicks):
def write_pdf(bytes_io):
pdf = create_pdf(n_nlicks) # pass argument to PDF creation here
bytes_io.write(pdf.output(dest='S').encode('latin-1'))
return send_bytes(write_pdf, "some_name.pdf")
if __name__ == '__main__':
app.run_server()