PDF Download button error

Hi

This code for a generated PDF download link works:

b64 = base64.b64encode(pdf.output(dest=“S”))
html = f’Download file
st.markdown(html, unsafe_allow_html=True)

But this link for a download button does not work:

b64 = base64.b64encode(pdf.output(dest=“S”)).decode()
st.download_button(“Download Report”, data=b64, file_name=f"{oflnme}", mime=“application/octet-stream”)

Any idea why this is happening?

Thanks in advance :slight_smile:

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"
)
1 Like

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.

Is that possible any other way?

Thanks

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.

Hi @Shawn_Pereira,

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.

Best, :balloon:
Snehan

hi @snehankekre , my sample code is here. It produces an unreadable PDF.

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)

Thanks in advance

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)

@Shawn_Pereira,

Here’s a working example with st.download_button(). :partying_face:

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') :point_up:. 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.

fpdf

Happy Streamlit-ing! :balloon:
Snehan

Wow. Thank you so much @snehankekre for your help and support. :slight_smile:

1 Like

Hi, how can we save the whole page of streamlit app and export it as a pdf file or picture?
Thank you.

1 Like