BuildShip Logo
BuildShip.Tools
HTML to PDF

HTML to PDF

Converts HTML content into a downloadable PDF file. Accepts raw HTML as input, generates a unique filename, uses a Puppeteer-based service to render the HTML as a PDF, stores it in Google Cloud Storage, and provides a public download URL as output.

9

Report this tool

Select the reason for reporting

Describe the issue in detail

Share tool

Link to tool

https://buildship.tools/tool/6eIy_AHzPV2N

Inputs

HTML

<div class="border border-light rounded-lg bg-secondaryBG absolute inset-4 sm:inset-6 overflow-hidden"><header class="hidden sm:flex w-full items-center justify-between border-light border-b"><div class="h-full px-4 flex items-center py-2.5 border-light border-r w-[calc(18rem_+_4rem)]"><a class="text-primaryText" href="https://g1mishra.dev">jeevan-kumar</a></div><div class="flex flex-1 justify-start w-full items-center whitespace-nowrap"><a class="px-6 h-full py-2.5 border-light border-r border-y-2 border-y-transparent text-center min-w-[120px] " href="https://g1mishra.dev">_hello</a><a class="px-6 h-full py-2.5 border-light border-r border-y-2 border-y-transparent text-center min-w-[120px] " href="https://g1mishra.dev/about-me">_about-me</a><a class="px-6 h-full py-2.5 border-light border-r border-y-2 border-y-transparent text-center min-w-[120px] " href="https://g1mishra.dev/projects">_projects</a><a class="px-6 h-full py-2.5 border-light border-r border-y-2 border-y-transparent text-center min-w-[120px] text-white border-b-[#FEA55F]" href="https://blog.g1mishra.dev">_blog</a></div><a class="px-4 h-full py-2.5 border flex items-center border-y-2 border-transparent border-l-light min-w-max " href="https://g1mishra.dev/contact-me">_contact-me</a></header><main class="flex flex-col sm:flex-row bg-secondaryBG text-primaryText"><div class="flex-grow p-3 sm:p-6"><article class="max-w-2xl mx-auto"><a class="text-[#FEA55F] hover:underline mb-2 inline-block text-sm" href="https://blog.g1mishra.dev">← Back to all posts</a><header class="mb-4"><h1 class="text-2xl sm:text-3xl font-bold text-[#E5E9F0] mb-2">A Complete Guide to Building Streamlit Data Web Apps with Code Examples</h1><div class="flex flex-wrap justify-between items-center text-[#607B96] text-sm"><p class="mr-4"><span class="text-[#FEA55F]">Published:</span> 2024-09-20</p><p><span class="text-[#FEA55F]">Category:</span> Data Science</p></div></header><div class="prose prose-sm prose-invert max-w-none mb-6"><h1>A Complete Guide to Building Streamlit Data Web Apps with Code Examples</h1> <p>Learn how to build interactive data dashboards using Streamlit. This guide provides a complete step-by-step approach, from creating a basic UI to deploying the app.</p> <h2>Introduction to Streamlit</h2> <p>Streamlit is an open-source framework for building quick data apps with Python.</p> <h3>Why Streamlit?</h3> <ul> <li>Easy for building data-driven apps.</li> <li>Simple integration with Python libraries like Pandas and Matplotlib.</li> </ul> <h3>Installation</h3> <p>To install Streamlit, run the following command:</p> <pre><code class="hljs language-bash">pip install streamlit </code></pre> <h3>Your First Streamlit App</h3> <p>Here's how to create a simple "Hello, World!" app:</p> <pre><code class="hljs language-python"><span class="hljs-keyword">import</span> streamlit <span class="hljs-keyword">as</span> st st.title(<span class="hljs-string">"Hello, Streamlit!"</span>) st.write(<span class="hljs-string">"This is your first Streamlit app."</span>) </code></pre> <p>Run the app with:</p> <pre><code class="hljs language-bash">streamlit run hello_world.py </code></pre> <h2>Building the Basic UI</h2> <p>Create a basic layout using Streamlit's built-in functions like <code>st.title()</code>, <code>st.header()</code>, and <code>st.file_uploader()</code>.</p> <pre><code class="hljs language-python"><span class="hljs-keyword">import</span> streamlit <span class="hljs-keyword">as</span> st st.title(<span class="hljs-string">"Interactive Data Dashboard"</span>) st.header(<span class="hljs-string">"1. Load your Dataset"</span>) uploaded_file = st.file_uploader(<span class="hljs-string">"Choose a CSV file"</span>, <span class="hljs-built_in">type</span>=<span class="hljs-string">"csv"</span>) <span class="hljs-keyword">if</span> uploaded_file: st.write(<span class="hljs-string">"File successfully uploaded."</span>) </code></pre> <h2>Loading and Displaying Data</h2> <p>Once a file is uploaded, use <code>pandas</code> to load and display the data.</p> <pre><code class="hljs language-python"><span class="hljs-keyword">import</span> pandas <span class="hljs-keyword">as</span> pd <span class="hljs-keyword">if</span> uploaded_file: df = pd.read_csv(uploaded_file) st.subheader(<span class="hljs-string">"2. Data Preview"</span>) st.dataframe(df.head()) </code></pre> <h3>Adding Filters</h3> <p>Allow users to filter data by a specific column.</p> <pre><code class="hljs language-python"><span class="hljs-keyword">if</span> uploaded_file: column_to_filter = st.selectbox(<span class="hljs-string">"Select column to filter"</span>, df.columns) selected_value = st.selectbox(<span class="hljs-string">f"Select <span class="hljs-subst">{column_to_filter}</span> value"</span>, df[column_to_filter].unique()) filtered_data = df[df[column_to_filter] == selected_value] st.write(<span class="hljs-string">f"Filtered data for <span class="hljs-subst">{column_to_filter}</span> = <span class="hljs-subst">{selected_value}</span>"</span>) st.dataframe(filtered_data) </code></pre> <h2>Data Visualization</h2> <h3>Matplotlib</h3> <p>Use Matplotlib to display static charts.</p> <pre><code class="hljs language-python"><span class="hljs-keyword">import</span> matplotlib.pyplot <span class="hljs-keyword">as</span> plt <span class="hljs-keyword">if</span> uploaded_file: fig, ax = plt.subplots() filtered_data[column_to_filter].value_counts().plot(kind=<span class="hljs-string">'bar'</span>, ax=ax) st.pyplot(fig) </code></pre> <h3>Plotly</h3> <p>For interactive visualizations, use Plotly.</p> <pre><code class="hljs language-python"><span class="hljs-keyword">import</span> plotly.express <span class="hljs-keyword">as</span> px <span class="hljs-keyword">if</span> uploaded_file: fig = px.line(filtered_data, x=<span class="hljs-string">"date_column"</span>, y=<span class="hljs-string">"value_column"</span>, title=<span class="hljs-string">"Trend over Time"</span>) st.plotly_chart(fig) </code></pre> <h2>Advanced Interactivity &amp; State Management</h2> <p>Enhance user experience with checkboxes and buttons.</p> <pre><code class="hljs language-python"><span class="hljs-keyword">if</span> st.checkbox(<span class="hljs-string">"Show raw data"</span>): st.subheader(<span class="hljs-string">"Raw Data"</span>) st.dataframe(df) </code></pre> <p>Use session state to store data across interactions.</p> <pre><code class="hljs language-python"><span class="hljs-keyword">if</span> <span class="hljs-string">'filtered_data'</span> <span class="hljs-keyword">not</span> <span class="hljs-keyword">in</span> st.session_state: st.session_state[<span class="hljs-string">'filtered_data'</span>] = df <span class="hljs-keyword">if</span> st.button(<span class="hljs-string">'Update Data'</span>): st.session_state[<span class="hljs-string">'filtered_data'</span>] = filtered_data </code></pre> <h2>Deploying the Data Dashboard</h2> <p>Once the app is ready, deploy it on Streamlit Cloud.</p> <ol> <li>Push the code to GitHub.</li> <li>Go to <a href="https://share.streamlit.io/">Streamlit Cloud</a>.</li> <li>Deploy with a single click.</li> </ol> <h2>Mini Project: Interactive Data Dashboard</h2> <p>Here's the full code to build an interactive data dashboard:</p> <pre><code class="hljs language-python"><span class="hljs-keyword">import</span> streamlit <span class="hljs-keyword">as</span> st <span class="hljs-keyword">import</span> pandas <span class="hljs-keyword">as</span> pd <span class="hljs-keyword">import</span> matplotlib.pyplot <span class="hljs-keyword">as</span> plt <span class="hljs-keyword">import</span> plotly.express <span class="hljs-keyword">as</span> px st.title(<span class="hljs-string">"Interactive Data Dashboard"</span>) uploaded_file = st.file_uploader(<span class="hljs-string">"Upload a CSV"</span>, <span class="hljs-built_in">type</span>=<span class="hljs-string">"csv"</span>) <span class="hljs-keyword">if</span> uploaded_file: df = pd.read_csv(uploaded_file) st.subheader(<span class="hljs-string">"Data Preview"</span>) st.dataframe(df.head()) column_to_filter = st.selectbox(<span class="hljs-string">"Filter by column"</span>, df.columns) selected_value = st.selectbox(<span class="hljs-string">f"Select <span class="hljs-subst">{column_to_filter}</span> value"</span>, df[column_to_filter].unique()) filtered_data = df[df[column_to_filter] == selected_value] st.subheader(<span class="hljs-string">f"Filtered Data for <span class="hljs-subst">{column_to_filter}</span> = <span class="hljs-subst">{selected_value}</span>"</span>) st.dataframe(filtered_data) fig, ax = plt.subplots() filtered_data[column_to_filter].value_counts().plot(kind=<span class="hljs-string">'bar'</span>, ax=ax) st.pyplot(fig) fig = px.line(filtered_data, x=<span class="hljs-string">"date_column"</span>, y=<span class="hljs-string">"value_column"</span>, title=<span class="hljs-string">"Trend over Time"</span>) st.plotly_chart(fig) <span class="hljs-keyword">if</span> st.checkbox(<span class="hljs-string">"Show raw data"</span>): st.subheader(<span class="hljs-string">"Raw Data"</span>) st.dataframe(df) </code></pre> <h2>Conclusion</h2> <p>In this guide, you've learned how to build a complete data dashboard using Streamlit. You can enhance it further with database integration, authentication, and more advanced filtering options.</p></div><div class="mt-4 flex flex-wrap gap-1"><span class="text-xs bg-[#1C2B3A] text-[#5565E8] px-2 py-0.5 rounded">Streamlit</span><span class="text-xs bg-[#1C2B3A] text-[#5565E8] px-2 py-0.5 rounded">Data Apps</span><span class="text-xs bg-[#1C2B3A] text-[#5565E8] px-2 py-0.5 rounded">Python</span></div><div class="mt-8 pt-6 border-t border-[#1E2D3D]"><h2 class="text-xl font-bold text-[#E5E9F0] mb-3">Related Posts</h2><div class="grid grid-cols-1 sm:grid-cols-2 gap-4"><a class="block" href="https://blog.g1mishra.dev/admob-ads-in-expo-react-native-app"><div class="bg-[#011221] border border-light rounded p-3 hover:bg-[#011627] transition-colors h-full flex flex-col"><h3 class="text-lg font-semibold text-[#E5E9F0] mb-1">How to Add AdMob Ads to Your Expo React Native App</h3><p class="text-[#607B96] text-sm mb-2 flex-grow">Step-by-step guide to implementing Google AdMob ads in Expo React Native apps with rewarded ads, banners, and interstitials.</p><span class="text-xs text-[#FEA55F]">Read more →</span></div></a><a class="block" href="https://blog.g1mishra.dev/hello-world"><div class="bg-[#011221] border border-light rounded p-3 hover:bg-[#011627] transition-colors h-full flex flex-col"><h3 class="text-lg font-semibold text-[#E5E9F0] mb-1">Hello, World!</h3><p class="text-[#607B96] text-sm mb-2 flex-grow">Welcome to my first blog post using Next.js and Markdown!</p><span class="text-xs text-[#FEA55F]">Read more →</span></div></a></div></div><div class="mt-10"><a class="text-[#FEA55F] hover:underline mb-4 inline-block" href="https://blog.g1mishra.dev">← Back to all posts</a></div></article></div></main><footer class="absolute z-50 bottom-0 inset-x-0 flex justify-between items-center overflow-hidden bg-secondaryBG border-t border-light"><div class="flex w-full sm:max-w-max sm:items-center gap-4"><p class="py-2 pl-4 whitespace-nowrap">find me on: </p><div class="flex items-center flex-1"><a href="https://linkedin.com/in/g1mishra" rel="noreferrer" target="_blank" class="flex-1 sm:flex-none opacity-60 hover:opacity-100 p-2 border-light border-x flex items-center justify-center"><svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M6.94 5.00002C6.93974 5.53046 6.72877 6.03906 6.35351 6.41394C5.97825 6.78883 5.46944 6.99929 4.939 6.99902C4.40857 6.99876 3.89997 6.78779 3.52508 6.41253C3.1502 6.03727 2.93974 5.52846 2.94 4.99802C2.94027 4.46759 3.15124 3.95899 3.5265 3.5841C3.90176 3.20922 4.41057 2.99876 4.941 2.99902C5.47144 2.99929 5.98004 3.21026 6.35492 3.58552C6.72981 3.96078 6.94027 4.46959 6.94 5.00002V5.00002ZM7 8.48002H3V21H7V8.48002ZM13.32 8.48002H9.34V21H13.28V14.43C13.28 10.77 18.05 10.43 18.05 14.43V21H22V13.07C22 6.90002 14.94 7.13002 13.28 10.16L13.32 8.48002V8.48002Z" fill="#607B96"></path></svg></a><a href="https://twitter.com/g1mishra" rel="noreferrer" target="_blank" class="flex-1 sm:flex-none opacity-60 hover:opacity-100 p-2 border-light border-l flex items-center justify-center"><svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M22.3832 5.65605C21.6197 5.99374 20.8101 6.21552 19.9812 6.31405C20.8549 5.79148 21.5089 4.96906 21.8212 4.00005C21.0012 4.48805 20.1022 4.83005 19.1652 5.01505C18.5358 4.34163 17.7015 3.89501 16.7921 3.74463C15.8827 3.59425 14.9491 3.74854 14.1364 4.1835C13.3238 4.61846 12.6776 5.30973 12.2983 6.14984C11.919 6.98995 11.8279 7.93183 12.0392 8.82905C10.3763 8.7457 8.74952 8.31357 7.26447 7.56071C5.77943 6.80785 4.46931 5.7511 3.41918 4.45905C3.04747 5.0975 2.85214 5.82328 2.85318 6.56205C2.85318 8.01205 3.59118 9.29305 4.71318 10.043C4.04919 10.0221 3.39982 9.84283 2.81918 9.52005V9.57205C2.81938 10.5377 3.15355 11.4737 3.76503 12.2211C4.37651 12.9686 5.22766 13.4815 6.17418 13.673C5.5578 13.8401 4.91149 13.8647 4.28418 13.745C4.55105 14.5763 5.07119 15.3032 5.77178 15.8242C6.47236 16.3451 7.31831 16.6338 8.19118 16.65C7.32366 17.3314 6.33036 17.835 5.26806 18.1322C4.20577 18.4294 3.09531 18.5143 2.00018 18.382C3.91188 19.6115 6.13728 20.2642 8.41018 20.262C16.1032 20.262 20.3102 13.889 20.3102 8.36205C20.3102 8.18205 20.3052 8.00005 20.2972 7.82205C21.116 7.23022 21.8228 6.49707 22.3842 5.65705L22.3832 5.65605Z" fill="#607B96"></path></svg></a><a href="https://instagram.com/g1mishra.dev" rel="noreferrer" target="_blank" class="flex-1 sm:flex-none opacity-60 hover:opacity-100 p-2 border-light border-x flex items-center justify-center"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 102 102" fill="none"><path d="M25.865,101.639A34.341,34.341,0,0,1,14.312,99.5a19.329,19.329,0,0,1-7.154-4.653A19.181,19.181,0,0,1,2.5,87.694,34.341,34.341,0,0,1,.364,76.142C.061,69.584,0,67.617,0,51s.067-18.577.361-25.14A34.534,34.534,0,0,1,2.5,14.312,19.4,19.4,0,0,1,7.154,7.154,19.206,19.206,0,0,1,14.309,2.5,34.341,34.341,0,0,1,25.862.361C32.422.061,34.392,0,51,0s18.577.067,25.14.361A34.534,34.534,0,0,1,87.691,2.5a19.254,19.254,0,0,1,7.154,4.653A19.267,19.267,0,0,1,99.5,14.309a34.341,34.341,0,0,1,2.14,11.553c.3,6.563.361,8.528.361,25.14s-.061,18.577-.361,25.14A34.5,34.5,0,0,1,99.5,87.694,20.6,20.6,0,0,1,87.691,99.5a34.342,34.342,0,0,1-11.553,2.14c-6.557.3-8.528.361-25.14.361s-18.577-.058-25.134-.361" data-name="Path 16"></path><path d="M25.865,101.639A34.341,34.341,0,0,1,14.312,99.5a19.329,19.329,0,0,1-7.154-4.653A19.181,19.181,0,0,1,2.5,87.694,34.341,34.341,0,0,1,.364,76.142C.061,69.584,0,67.617,0,51s.067-18.577.361-25.14A34.534,34.534,0,0,1,2.5,14.312,19.4,19.4,0,0,1,7.154,7.154,19.206,19.206,0,0,1,14.309,2.5,34.341,34.341,0,0,1,25.862.361C32.422.061,34.392,0,51,0s18.577.067,25.14.361A34.534,34.534,0,0,1,87.691,2.5a19.254,19.254,0,0,1,7.154,4.653A19.267,19.267,0,0,1,99.5,14.309a34.341,34.341,0,0,1,2.14,11.553c.3,6.563.361,8.528.361,25.14s-.061,18.577-.361,25.14A34.5,34.5,0,0,1,99.5,87.694,20.6,20.6,0,0,1,87.691,99.5a34.342,34.342,0,0,1-11.553,2.14c-6.557.3-8.528.361-25.14.361s-18.577-.058-25.134-.361" data-name="Path 17"></path><path fill="gray" d="M461.114,477.413a12.631,12.631,0,1,1,12.629,12.632,12.631,12.631,0,0,1-12.629-12.632m-6.829,0a19.458,19.458,0,1,0,19.458-19.458,19.457,19.457,0,0,0-19.458,19.458m35.139-20.229a4.547,4.547,0,1,0,4.549-4.545h0a4.549,4.549,0,0,0-4.547,4.545m-30.99,51.074a20.943,20.943,0,0,1-7.037-1.3,12.547,12.547,0,0,1-7.193-7.19,20.923,20.923,0,0,1-1.3-7.037c-.184-3.994-.22-5.194-.22-15.313s.04-11.316.22-15.314a21.082,21.082,0,0,1,1.3-7.037,12.54,12.54,0,0,1,7.193-7.193,20.924,20.924,0,0,1,7.037-1.3c3.994-.184,5.194-.22,15.309-.22s11.316.039,15.314.221a21.082,21.082,0,0,1,7.037,1.3,12.541,12.541,0,0,1,7.193,7.193,20.926,20.926,0,0,1,1.3,7.037c.184,4,.22,5.194.22,15.314s-.037,11.316-.22,15.314a21.023,21.023,0,0,1-1.3,7.037,12.547,12.547,0,0,1-7.193,7.19,20.925,20.925,0,0,1-7.037,1.3c-3.994.184-5.194.22-15.314.22s-11.316-.037-15.309-.22m-.314-68.509a27.786,27.786,0,0,0-9.2,1.76,19.373,19.373,0,0,0-11.083,11.083,27.794,27.794,0,0,0-1.76,9.2c-.187,4.04-.229,5.332-.229,15.623s.043,11.582.229,15.623a27.793,27.793,0,0,0,1.76,9.2,19.374,19.374,0,0,0,11.083,11.083,27.813,27.813,0,0,0,9.2,1.76c4.042.184,5.332.229,15.623.229s11.582-.043,15.623-.229a27.8,27.8,0,0,0,9.2-1.76,19.374,19.374,0,0,0,11.083-11.083,27.716,27.716,0,0,0,1.76-9.2c.184-4.043.226-5.332.226-15.623s-.043-11.582-.226-15.623a27.786,27.786,0,0,0-1.76-9.2,19.379,19.379,0,0,0-11.08-11.083,27.748,27.748,0,0,0-9.2-1.76c-4.041-.185-5.332-.229-15.621-.229s-11.583.043-15.626.229" data-name="Path 18" transform="translate(-422.637 -426.196)"></path></svg></a><a href="https://www.youtube.com/@codingwithjeevan" rel="noreferrer" target="_blank" class="flex-1 sm:flex-none opacity-60 hover:opacity-100 p-2 border-light border-x flex items-center justify-center"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="5.368 13.434 53.9 37.855"><path d="M41.272 31.81c-4.942-2.641-9.674-5.069-14.511-7.604v15.165c5.09-2.767 10.455-5.301 14.532-7.561h-.021z"></path><path d="M41.272 31.81c-4.942-2.641-14.511-7.604-14.511-7.604l12.758 8.575c.001 0-2.324 1.289 1.753-.971z"></path><path fill="gray" d="M27.691 51.242c-10.265-.189-13.771-.359-15.926-.803-1.458-.295-2.725-.95-3.654-1.9-.718-.719-1.289-1.816-1.732-3.338-.38-1.268-.528-2.323-.739-4.9-.323-5.816-.4-10.571 0-15.884.33-2.934.49-6.417 2.682-8.449 1.035-.951 2.239-1.563 3.591-1.816 2.112-.401 11.11-.718 20.425-.718 9.294 0 18.312.317 20.426.718 1.689.317 3.273 1.267 4.203 2.492 2 3.146 2.035 7.058 2.238 10.118.084 1.458.084 9.737 0 11.195-.316 4.836-.57 6.547-1.288 8.321-.444 1.12-.823 1.711-1.479 2.366a7.085 7.085 0 0 1-3.76 1.922c-8.883.668-16.426.813-24.987.676zM41.294 31.81c-4.942-2.641-9.674-5.09-14.511-7.625v15.166c5.09-2.767 10.456-5.302 14.532-7.562l-.021.021z"></path></svg></a></div></div><div class="hidden sm:flex items-center border-light border-l pr-4"><a target="_blank" href="https://github.com/g1mishra" class="opacity-60 hover:opacity-100 flex items-center justify-center" rel="noreferrer"><p class="px-4 py-2">@g1mishra </p><svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M12 2C6.475 2 2 6.475 2 12C1.99887 14.0993 2.65882 16.1456 3.88622 17.8487C5.11362 19.5517 6.84615 20.8251 8.838 21.488C9.338 21.575 9.525 21.275 9.525 21.012C9.525 20.775 9.512 19.988 9.512 19.15C7 19.613 6.35 18.538 6.15 17.975C6.037 17.687 5.55 16.8 5.125 16.562C4.775 16.375 4.275 15.912 5.112 15.9C5.9 15.887 6.462 16.625 6.65 16.925C7.55 18.437 8.988 18.012 9.562 17.75C9.65 17.1 9.912 16.663 10.2 16.413C7.975 16.163 5.65 15.3 5.65 11.475C5.65 10.387 6.037 9.488 6.675 8.787C6.575 8.537 6.225 7.512 6.775 6.137C6.775 6.137 7.612 5.875 9.525 7.163C10.3391 6.93706 11.1802 6.82334 12.025 6.825C12.875 6.825 13.725 6.937 14.525 7.162C16.437 5.862 17.275 6.138 17.275 6.138C17.825 7.513 17.475 8.538 17.375 8.788C18.012 9.488 18.4 10.375 18.4 11.475C18.4 15.313 16.063 16.163 13.838 16.413C14.2 16.725 14.513 17.325 14.513 18.263C14.513 19.6 14.5 20.675 14.5 21.013C14.5 21.275 14.688 21.587 15.188 21.487C17.173 20.8168 18.8979 19.541 20.1199 17.8392C21.3419 16.1373 21.9994 14.0951 22 12C22 6.475 17.525 2 12 2Z" fill="#607B96"></path></svg></a></div></footer></div>
This is a static example using sample inputs. Remix the tool to run it with your own values.

Output