You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Streamlit download_button下载Zip文件失败,报错RuntimeError求助

解决Streamlit download_button无法下载Zip文件的错误

问题描述

从.xlsx文件中的URL下载图片并打包为Zip文件,单独执行打包代码正常,但使用Streamlit的download_button时触发错误:

RuntimeError: Invalid binary data format: <class 'zipfile.ZipFile'>

相关代码如下:

import pandas as pd
import urllib.request
import zipfile

df = pd.read_excel("images.xlsx")
# Column containing the image names
title = df["Name"].tolist()
# Column containing the image urls
images = df["Image"].tolist()

with zipfile.ZipFile("images.zip", "w", zipfile.ZIP_DEFLATED) as z:
    for idx,image in enumerate(images):
        response = urllib.request.urlopen(image)
        img_data = response.read()
        z.writestr(title[idx], img_data)

    st.download_button(
        label="Download Images",
        data=z,
        file_name="images.zip",
        mime="application/zip",
    )

错误原因

Streamlit的download_button的data参数要求传入二进制数据(bytes类型),而不是zipfile.ZipFile对象。直接将ZipFile实例传给data会触发格式错误。

解决方案

有两种可行的修正方式:

方式1:读取本地Zip文件的二进制内容

先完成本地Zip文件的写入,再读取其二进制数据传给download_button:

import pandas as pd
import urllib.request
import zipfile
import streamlit as st

df = pd.read_excel("images.xlsx")
title = df["Name"].tolist()
images = df["Image"].tolist()

# 先创建本地Zip文件
with zipfile.ZipFile("images.zip", "w", zipfile.ZIP_DEFLATED) as z:
    for idx, image in enumerate(images):
        response = urllib.request.urlopen(image)
        img_data = response.read()
        z.writestr(title[idx], img_data)

# 读取Zip文件的二进制内容
with open("images.zip", "rb") as f:
    zip_data = f.read()

# 传递二进制数据给download_button
st.download_button(
    label="Download Images",
    data=zip_data,
    file_name="images.zip",
    mime="application/zip",
)

方式2:使用内存中的BytesIO创建Zip(推荐)

无需写入本地文件,直接在内存中生成Zip的二进制数据,更高效:

import pandas as pd
import urllib.request
import zipfile
import streamlit as st
from io import BytesIO

df = pd.read_excel("images.xlsx")
title = df["Name"].tolist()
images = df["Image"].tolist()

# 使用BytesIO在内存中创建Zip
zip_buffer = BytesIO()
with zipfile.ZipFile(zip_buffer, "w", zipfile.ZIP_DEFLATED) as z:
    for idx, image in enumerate(images):
        response = urllib.request.urlopen(image)
        img_data = response.read()
        z.writestr(title[idx], img_data)

# 将缓冲区指针移到开头,读取二进制数据
zip_buffer.seek(0)

st.download_button(
    label="Download Images",
    data=zip_buffer,
    file_name="images.zip",
    mime="application/zip",
)

内容的提问来源于stack exchange,提问作者d1p3n

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 03:20:16