Streamlit中本地PDF文件可点击下载链接问题求助
解决Streamlit中DataFrame本地PDF下载链接无响应问题
问题根源
浏览器出于安全限制,禁止网页直接通过本地文件路径(file://协议)访问用户本地文件系统,所以直接将本地路径作为HTML链接的href属性,点击后不会触发任何操作。
可行解决方案
方案1:将文件转为Base64嵌入HTML链接(适合小文件)
把本地PDF文件编码为Base64格式,嵌入到HTML链接中,让浏览器直接识别文件内容并触发下载:
import os import pandas as pd import streamlit as st import base64 # 构造数据源 df = pd.DataFrame({ 'name': ['John', 'Mathew', 'Sato'], 'link': ['C://Users//Satokuzuma//Documents//sample1.pdf', 'C://Users//Satokuzuma//Documents//sample2.pdf', 'C://Users//Satokuzuma//Documents//sample3.pdf'] }) def generate_download_link(file_path): # 读取文件并转为Base64编码 with open(file_path, 'rb') as f: file_bytes = f.read() b64_encoded = base64.b64encode(file_bytes).decode() file_name = os.path.basename(file_path) # 生成可下载的HTML链接 return f'<a href="data:application/pdf;base64,{b64_encoded}" download="{file_name}">下载{file_name}</a>' # 为DataFrame添加下载链接列 df['下载链接'] = df['link'].apply(generate_download_link) # 渲染HTML表格 st.markdown(df.to_html(escape=False), unsafe_allow_html=True)
方案2:使用Streamlit官方下载按钮(适合大文件)
直接利用Streamlit的st.download_button组件生成下载按钮,避免Base64编码带来的体积膨胀问题:
import os import pandas as pd import streamlit as st # 构造数据源 df = pd.DataFrame({ 'name': ['John', 'Mathew', 'Sato'], 'link': ['C://Users//Satokuzuma//Documents//sample1.pdf', 'C://Users//Satokuzuma//Documents//sample2.pdf', 'C://Users//Satokuzuma//Documents//sample3.pdf'] }) # 遍历每行生成独立下载按钮 for idx, row in df.iterrows(): file_name = os.path.basename(row['link']) with open(row['link'], 'rb') as f: st.download_button( label=f"下载 {row['name']} 的PDF文件", data=f, file_name=file_name, mime='application/pdf', key=f"download_{idx}" )
关键说明
原代码的核心问题是直接使用本地文件路径作为链接地址,违反了浏览器的安全策略。上述两种方案均通过将文件内容传递给浏览器,而非直接暴露本地路径,从而实现正常下载功能。
内容的提问来源于stack exchange,提问作者eaglebird
相关产品推荐
相关产品推荐

