Using st.Markdown to show embedded PDF-file - Gets page not found

I am making a simple streamlit app to show different PDF files. To show the PDF file I would like to use markdown with an embedded file.

My code:

showstring = f"""                 
                <body>
                <div> <embed src="{file}" width="800px" height="2100px" /> </div>
                </body>
                """
st.markdown(showstring, unsafe_allow_html=True)

Where file is the name of the pdf file.

Instead of showing the PDF file, I get the following error message and my mainpage app in the embedded file window framesize.

Page not found

You have requested page /NDS-00130.pdf, but no corresponding file was found in the appโ€™s pages/ directory. Running the appโ€™s main page.

For me it looks like a conflict with the streamlit multipage functionality.

I am using:

  • Streamlit version: 1.13.0

Hi @EBEN! Good to see you back on our forum! :hugs:

One possible issue is that the file variable might not be properly resolving to the correct file path. Make sure that the file variable contains the correct file path to the PDF file that you want to display.

You might also want to check that the file exists at the specified location and that your Streamlit app has the necessary permissions to access it.

Let me know how it goes. If itโ€™s still not working, we can take a closer look :wink:

Thanks,
Charly

Thanks for the quick reply!

I have made a sample HTML page with the same html markdown snippet, located in the same path as the streamlit python file. This one show the file as expected.

Using this minimal streamlit code (MinimalSolution.py) to show a PDF-file:

Running the streamlit file:

file setup of rootfolder with streamlit file:

I also have a copy of the PDF-file in a folder /pages/ just to see if that was a workaround, with no luck.

Encoding to base64 worked for me.

import base64
from pathlib import Path

import streamlit as st

pdf_path = Path("NDS-00130.pdf")
base64_pdf = base64.b64encode(pdf_path.read_bytes()).decode("utf-8")
pdf_display = f"""
    <iframe src="data:application/pdf;base64,{base64_pdf}" width="800px" height="2100px" type="application/pdf"></iframe>
"""
st.markdown(pdf_display, unsafe_allow_html=True)

I found this solution in a blog post:

3 Likes

Thanks for the blog post link and code sample.

It works when I use a very simple PDF file (Just a blank page with a short text), but with a โ€œrealโ€ PDF file the iframe shows nothing.

Displaying the PDF file in a standard HTML document without base64 encoding gives me no issues as:

<!DOCTYPE html>
<html lang="en">

<body>

<div> <embed src="NDS-00130.pdf" width="800px" height="2100px" />
</div>

</body>
</html>

@Goyo
The iframe approach may not work well anymore, tested in MS edge and chrome, iframes are blocked. The section of your blog about pdf is also not displayed correctly

For now, I can use PyMuPDF to convert PDF to image, and then use st.image to display.

doc = fitz.open(stream=file_stream, filetype='pdf')
image_list = []
for page_number in range(doc.page_count):
    page = doc.load_page(page_number)
    pix = page.get_pixmap(dpi=300)  # scale up the image resolution
    img = Image.frombytes("RGB", [pix.width, pix.height], pix.samples)
    image_list.append(img)

It works for me using Firefox 110.0.1 but not Edge 112.0.1722.58 (Windows 10) when running in Streamlit Cloud. It works with both browsers when running in localhost.

iโ€™m running into the same issue with Iframe , was there any fixes around this ?