you can use this function to download a pdf file in streamlit:
with open("yourpdf.pdf", "rb") as file:
btn=st.download_button(
label="click me to download pdf",
data=file,
file_name="dowloaded.pdf",
mime="application/octet-stream"
)
Thank you @BeyondMyself for sharing your code, it is greatly appreciated. However, this method requires you to already have a PDF file on disk, open it and then transfer the file via the download button to the client.
I am using a PDF file already created in memory with FPDF. I dont want to save this PDF copy to disk temporarily (as this would have to do so on the server). I wish to let the client user directly download the PDF in memory to his/her downloads folder.
you can save it into a pdf on your disk first.
when people finish their download, than you remove the pdf file on disk.
use time.sleep(60), give people 1 minute to dowload the pdf from your disk.
finally, you solve this problem, peple download successfully and no space is occupied on your disk.
Could you share a minimal reproducible example of creating a PDF with FPDF? That’ll help me generate one on my end so that I can figure out how to make it work with st.download_button.
It doesn’t seem to work for me when I comment those lines out:
import streamlit as st
from fpdf import FPDF
import base64
pdf = FPDF() # pdf object
pdf = FPDF(orientation="P", unit="mm", format="A4")
pdf.add_page()
pdf.set_font("Times", "B", 18)
pdf.set_xy(10.0, 20)
pdf.cell(w=75.0, h=5.0, align="L", txt="This is my sample text")
oflnme = "Output.pdf"
# b64 = base64.b64encode(pdf.output("", dest="S")).decode()
# st.download_button(
# "Download Report",
# data=b64,
# file_name=oflnme,
# mime="application/octet-stream",
# help=f"Download file {oflnme}",
# )
# alternatively, if I replace the above last 2 lines with the following 3 lines of code for a download hyperlink, it works fine.
b64 = base64.b64encode(pdf.output(dest="S"))
html = f"Download file"
st.markdown(html, unsafe_allow_html=True)
import streamlit as st
from fpdf import FPDF
import base64
pdf = FPDF() # pdf object
pdf = FPDF(orientation="P", unit="mm", format="A4")
pdf.add_page()
pdf.set_font("Times", "B", 18)
pdf.set_xy(10.0, 20)
pdf.cell(w=75.0, h=5.0, align="L", txt="This is my sample text")
st.download_button(
"Download Report",
data=pdf.output(dest='S').encode('latin-1'),
file_name="Output.pdf",
)
Note how I used .encode('latin-1'). The fpfd source code says “manage binary data as latin1 until PEP461 or similar is implemented”. pdf.output(dest='S') outputs a binary string that must be encoded as latin1.