首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用木星笔记本和Voila使一个临时压缩对象可被用户下载

如何使用木星笔记本和Voila使一个临时压缩对象可被用户下载
EN

Stack Overflow用户
提问于 2022-05-24 10:16:52
回答 1查看 82关注 0票数 0

我写了一个jupyter笔记本,我想用Voila来创建一个小型的web应用程序/工具。该工具所做的是从用户获取包含多个多边形的一个 Geojson文件,并返回一个包含多个 GeoJSON文件的ZIP文件(每个多边形一个文件)。例如,如果用户上传一个包含20个多边形的GeoJSON文件(它们都位于同一个文件中),那么输出应该是一个包含20个不同GeoJSON文件的ZIP文件--每个多边形都是文件。我可以在本地完成它,并根据需要保存ZIP文件。

但是,我想使用Voila来呈现它,这样它以后可以在任何地方工作,这意味着ZIP文件将在内存中/处于动态状态/作为缓冲区(不确定哪个术语是准确的)中创建,然后用户将能够通过自动下载或通过单击按钮或弹出窗口下载ZIP文件,这在这里并不重要。

下面是我的代码片段(如果还不够,请告诉我):

代码语言:javascript
复制
def on_button_clicked(event):
    with output:
        clear_output()
        df = gpd.GeoDataFrame().from_features(json.loads(upload.data[0])) # if the file is geojson
        display(HTML(f'<h4><left>There are {len(df)} polygons in the file</left></h4>'))
        
        # make results.zip in temp directory
        # https://gist.github.com/simonthompson99/362404d6142db3ed14908244f5750d08
        tmpdir = tempfile.mkdtemp()
        zip_fn = os.path.join(tmpdir, 'results.zip')
        zip_obj = zipfile.ZipFile(zip_fn, 'w')

        for i in range(df.shape[0]):

            if len(field_names_col.value)==0:
                field_name = f'field_{str(i+1)}'
            else:
                field_name = df[field_names_col.value][i]

            output_name = f'{field_name}.{output_format.value.lower()}'

            df.iloc[[i]].to_file(f'{tmpdir}\\{output_name}', driver=output_format.value)

        for f in glob.glob(f"{tmpdir}/*"):
            zip_obj.write(f, os.path.basename(f)) # add file to archive, second argument is the structure to be represented in zip archive, i.e. this just makes flat strucutre

        zip_obj.close()

button_send.on_click(on_button_clicked)

vbox_result = widgets.VBox([button_send, output])

重要的部分接近尾声:

代码语言:javascript
复制
for f in glob.glob(f"{tmpdir}/*"):
    zip_obj.write(f, os.path.basename(f)) # add file to archive, second argument is the structure to be represented in zip archive, i.e. this just makes flat strucutre

zip_obj.close()

我遍历临时的单独文件,并创建一个存储在zip_obj中的临时ZIP文件(zip_obj)。我如何“推送”这个ZIP对象给用户使用木星笔记本下载?

我尝试使用(就在zip_obj.close()之前或之后):

代码语言:javascript
复制
local_file = FileLink(os.path.basename(f), result_html_prefix="Click here to download: ")
display(local_file)

但是我在用Voila渲染它时出错了:

路径(results.zip)不存在。它可能仍在生成过程中,或者您可能有错误的路径。

例如,为了在本地保存它,我做到了:

代码语言:javascript
复制
with zipfile.ZipFile('c:/tool/results.zip', 'w') as zipf:
    for f in tmpdir.glob("*"):
      zipf.write(f, arcname=f.name)
EN

回答 1

Stack Overflow用户

发布于 2022-05-24 17:21:08

我遍历临时独立文件并创建存储在zip_obj中的临时ZIP文件(Zip_obj)。我如何“将”这个ZIP对象“推送”给用户使用朱庇特笔记本下载?

有一个制作下载链接的示例,该链接将显示在Voila呈现这里中。(从这里获悉,虽然关注的焦点是文件上传。该示例还包括下载结果。)在这个答案在这里的底部找到了一个更简单的处理方法,将其转换为您的情况:

代码语言:javascript
复制
%%html
<a href="./voila/static/the_archive.zip" download="demo.xlsx">Download the Resulting Files as an Archive</a>

这两个选项为答案这里的底部部分(当前行下的所有内容)中的不同类型的文件演示。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72361140

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档