awacke1 commited on
Commit
25d433d
·
verified ·
1 Parent(s): a3ea8b1

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +110 -0
app.py ADDED
@@ -0,0 +1,110 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from selenium import webdriver
3
+ from selenium.webdriver.chrome.service import Service
4
+ from selenium.webdriver.chrome.options import Options
5
+ from selenium.webdriver.support.ui import WebDriverWait
6
+ from selenium.webdriver.support import expected_conditions as EC
7
+ import pdfkit
8
+ import time
9
+ import os
10
+ from pathlib import Path
11
+
12
+ class StreamlitPDFCapture:
13
+ def __init__(self):
14
+ self.options = {
15
+ 'page-size': 'A4',
16
+ 'margin-top': '0mm',
17
+ 'margin-right': '0mm',
18
+ 'margin-bottom': '0mm',
19
+ 'margin-left': '0mm',
20
+ 'encoding': 'UTF-8',
21
+ 'custom-header': [('Accept-Encoding', 'gzip')],
22
+ 'no-outline': None,
23
+ 'enable-local-file-access': None
24
+ }
25
+
26
+ def setup_chrome_driver(self):
27
+ """Setup Chrome driver with appropriate options."""
28
+ chrome_options = Options()
29
+ chrome_options.add_argument("--headless") # Run in headless mode
30
+ chrome_options.add_argument("--window-size=1920,1080")
31
+ chrome_options.add_argument("--disable-gpu")
32
+ chrome_options.add_argument("--no-sandbox")
33
+ return webdriver.Chrome(options=chrome_options)
34
+
35
+ def capture_page(self, url, output_path, wait_time=5):
36
+ """Capture a single Streamlit page as PDF."""
37
+ driver = self.setup_chrome_driver()
38
+ try:
39
+ # Navigate to page
40
+ driver.get(url)
41
+ time.sleep(wait_time) # Wait for page to fully load
42
+
43
+ # Get page height and set window size
44
+ height = driver.execute_script("return document.body.scrollHeight")
45
+ driver.set_window_size(1920, height + 100)
46
+
47
+ # Save as PDF using pdfkit
48
+ html_content = driver.page_source
49
+ pdfkit.from_string(html_content, output_path, options=self.options)
50
+
51
+ finally:
52
+ driver.quit()
53
+
54
+ def capture_multiple_pages(self, urls, output_dir, prefix="page"):
55
+ """Capture multiple Streamlit pages as separate PDFs."""
56
+ Path(output_dir).mkdir(parents=True, exist_ok=True)
57
+ pdfs = []
58
+
59
+ for i, url in enumerate(urls):
60
+ output_path = os.path.join(output_dir, f"{prefix}_{i+1}.pdf")
61
+ self.capture_page(url, output_path)
62
+ pdfs.append(output_path)
63
+
64
+ return pdfs
65
+
66
+ def add_pdf_download_button():
67
+ """Add a PDF download button to your Streamlit app."""
68
+ if st.button("📑 Download as PDF"):
69
+ with st.spinner("Generating PDF..."):
70
+ # Get current page URL
71
+ ctx = st.runtime.get_instance()
72
+ url = ctx.serverAddress if hasattr(ctx, 'serverAddress') else "http://localhost:8501"
73
+
74
+ # Initialize capture utility
75
+ pdf_capture = StreamlitPDFCapture()
76
+
77
+ # Generate PDF
78
+ output_path = "streamlit_page.pdf"
79
+ pdf_capture.capture_page(url, output_path)
80
+
81
+ # Provide download link
82
+ with open(output_path, "rb") as pdf_file:
83
+ pdfd = pdf_file.read()
84
+ st.download_button(
85
+ label="⬇️ Download PDF",
86
+ data=pdfd,
87
+ file_name="streamlit_page.pdf",
88
+ mime="application/pdf"
89
+ )
90
+
91
+ # Example usage in your Streamlit app:
92
+ if __name__ == "__main__":
93
+ st.title("Streamlit PDF Capture Demo")
94
+
95
+ # Add the PDF download button
96
+ add_pdf_download_button()
97
+
98
+ # Your regular Streamlit content here
99
+ st.write("This is a demo of PDF capture functionality")
100
+
101
+ # For multiple pages
102
+ if st.checkbox("Capture multiple pages"):
103
+ urls = [
104
+ "http://localhost:8501/page1",
105
+ "http://localhost:8501/page2"
106
+ ]
107
+ if st.button("Generate PDFs for all pages"):
108
+ pdf_capture = StreamlitPDFCapture()
109
+ pdfs = pdf_capture.capture_multiple_pages(urls, "output_pdfs")
110
+ st.success(f"Generated {len(pdfs)} PDFs in output_pdfs directory")