Export/Save Streamlit app (Screenshots or Pdf)

Summary

I have a Streamlit app that mimics daily reports. Where each input widget is initialized with a value from the database.

I am trying to export/save my Streamlit app as a pdf and or screenshot.

At the moment, I am trying to create multiple screenshots of the page and then combine them into single full screenshot. To do so I need to move my window position by x amount.

I have tried the following script using Selenium,however scroll action doesn’t happen/work. I have also tried options with PAGE_DOWN Key.

Please suggest what could be the issue and potential solution.

Steps to reproduce

Code snippet:

            driver = webdriver.Chrome()
            # Navigate to the desired web page
            url =' http://localhost:8501/'  
            driver.get(url)
            scroll_x = 0  # Horizontal scroll position
            scroll_y = 500  # Vertical scroll position
            driver.execute_script(f"window.scrollTo({scroll_x}, {scroll_y});")

You should be able to use the menu in the top right corner and choose “print”

If you want to do it automatically, and selenium isn’t working for you, you might try using Playwright, which supports full page screenshots. Screenshots | Playwright

Thank you for your fast response. I am able to use “print” option in the top right corner. However, It produce inconsistent results, as it based on the screen resolution. Moreover, it does produce some blank pages at the start.

I have tested Playwright. Using following script, but it didn’t managed to produce full page (i.e. screenshot_full.png==screenshot.png), however it worked for some arbitrary website.

        import asyncio
        from playwright.async_api import async_playwright

        async def test():
            async with async_playwright() as p:
                browser = await p.chromium.launch()
                page = await browser.new_page()
                await page.goto("http://localhost:8501/")
                time.sleep(2)
                await page.screenshot(path="screenshot_full.png", full_page=True)
                await page.screenshot(path="screenshot.png", full_page=False)
                await browser.close()

        if __name__ == '__main__':
            loop = asyncio.ProactorEventLoop()
            asyncio.set_event_loop(loop)
            loop.run_until_complete(test())

Hi Kawanovs,
Please visit the below youtube video. It uses headless option and lambda function.
Selenium Full Page ScreenShot Youtube Video : https://www.youtube.com/watch?v=iOpGGW__oz4

I hope you find this helpful.:pray:

Hi Vickyraghuwanshi,

Thank you for your suggestion. It does work work some arbitrary website, but not for the streamlit app.

With the given code I get following error:

        from selenium.webdriver.chrome.service import Service
        chrome_options = Options()
        chrome_options.add_argument("--headless")  # Set any desired options

        driver = webdriver.Chrome(options=chrome_options, service=Service(ChromeDriverManager().install()))
        driver.implicitly_wait(10)

        # Navigate to the desired web page
        url = ' http://localhost:8501/'  # Replace with your desired URL
        driver.get(url)
        # Small screenshot
        driver.get_screenshot_as_file('report.png')
        # Full screenshot
        S = lambda x: driver.execute_script('return document.body.parentNode.scroll' + x)
        driver.set_window_size(S('Width'), S('Height'))
        driver.find_element(By.XPATH, '/html/body').screenshot('report_full.png')

selenium.common.exceptions.WebDriverException: Message: unknown error: unhandled inspector error: {“code”:-32000,“message”:“Cannot take screenshot with 0 height.”}. I have also tried to use other elements, but I only have managed to get a small screenshot.

Any other suggestion are appreciated!

UPDATE:
Following solution was found. It does produce some bugs with sidebar animation and loading animation, but nothing critical.

    allow_scroll = """
                    <style>
                        .stApp{ position: relative !important;}
                        .appview-container{ position: relative !important;}
                    </style>
                    """
    st.markdown(allow_scroll, unsafe_allow_html=True)

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.