Skip to content

mwmi/streamlit-pdf

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 

Repository files navigation

streamlit-pdf

Preview PDF files using browser-native components in streamlit.

No third-party libraries required other than streamlit itself.

Demo

streamlit run streamlit_pdf.py

demo

Usage

Copy the following code into your streamlit application and invoke the st_show_pdf function.

import base64
import urllib.request
import streamlit as st
from streamlit.components.v1 import html


def st_show_pdf(
    input: str | bytes,
    width: str = "100%",
    height: str = "100%",
    id: str = "",
    view: str = "FitH",
    timeout: int = 10,
) -> bool:
    """
    Display a PDF file in Streamlit

    :param input: PDF file path or content
    :param width: Display width
    :param height: Display height
    :param id: Element ID, must be unique
    :param view: Display mode `FitH`, `FitV`, `FitB`, `FitBH`, `FitBV`
    :param timeout: Request timeout
    :return: Whether display succeeded
    """

    def content_to_base64(address: str, timeout: int):
        try:
            if address.startswith(("http://", "https://")):
                req = urllib.request.Request(address)
                with urllib.request.urlopen(req, timeout=timeout) as response:
                    if response.status != 200:
                        raise ValueError(
                            f"HTTP error: {response.status} {response.reason}"
                        )
                    header = response.read(5)
                    if header != b"%PDF-":
                        raise ValueError("Not a valid PDF file")
                    content = header + response.read()
            else:
                with open(address, "rb") as f:
                    header = f.read(5)
                    if header != b"%PDF-":
                        raise ValueError("Not a valid PDF file")
                    content = header + f.read()
            return base64.b64encode(content).decode("utf-8")
        except Exception:
            raise ValueError("Failed to read content")

    try:
        if isinstance(input, str):
            base64_pdf = content_to_base64(input, timeout)
        elif isinstance(input, bytes):
            if input.startswith(b"%PDF-"):
                base64_pdf = base64.b64encode(input).decode("utf-8")
            else:
                raise ValueError("Invalid PDF format")
        else:
            raise ValueError("Invalid input type")
        if id == "":
            id = "stPDF_" + str(hash(input))
        st.markdown(
            f'<embed id="{id}" width="0" height="0" type="application/pdf">',
            unsafe_allow_html=True,
        )
        html(
            f"""
<script>
let raw = atob("{base64_pdf}");
let rawLength = raw.length;
let uint8Array = new Uint8Array(rawLength);
while (rawLength--){{
    uint8Array[rawLength] = raw.charCodeAt(rawLength);
}}
let fileBlob = new Blob([uint8Array],{{type: "application/pdf"}});
let href = URL.createObjectURL(fileBlob);
let pdf = window.parent.document.getElementById("{id}");
if (pdf) {{
    pdf.src = href + "#view={view}";
    pdf.width = "{width}";
    pdf.height = "{height}";
}}
</script>
    """,
            height=0,
        )
        return True
    except Exception:
        return False

About

Preview PDF files in streamlit

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages