V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
aieike
V2EX  ›  Python

我想在 flask 里返回 pandas 生成的 Excel 表格, 但又不想保存这个文件 有没有办法,跳过生成文件这个步骤? 我想到用流处理,但不知道该怎么弄

  •  
  •   aieike ·
    AIEIKE · 2019-08-19 16:57:02 +08:00 · 3077 次点击
    这是一个创建于 1923 天前的主题,其中的信息可能已经有所发展或是发生改变。

    这是代码

    def download_excel():
        try:
            logger.info('download_excel, %s' % str(request.form))
            form_data = json.loads(request.form.get('data'))
            header_names = form_data['header_names']
            headers = form_data['headers']
            rows = form_data['list']
            data = OrderedDefault(list)
            for row in rows:
                for i, header_name in enumerate(header_names):
                    header = headers[i]
                    data[header_name].append(row[header])
            file_name = 'temp_data/temp.xlsx'
            pd.DataFrame(data).to_excel(file_name, index=False)
            response = make_response(send_file(file_name))
            return response
        except Exception as e:
            logger.exception(e)
            return make_response('Error', 301)
    
    第 1 条附言  ·  2019-08-20 10:15:58 +08:00

    修改完后代码

    def download_excel():
        try:
            logger.info('download_excel, %s' % str(request.form))
            form_data = json.loads(request.form.get('data'))
            header_names = form_data['header_names']
            headers = form_data['headers']
            rows = form_data['list']
            data = OrderedDefault(list)
            for row in rows:
                for i, header_name in enumerate(header_names):
                    header = headers[i]
                    data[header_name].append(row[header])
            bf = io.BytesIO()
            pd.DataFrame(data).to_excel(bf, index=False)
            logger.info('Excel file size: {}'.format(bf.tell()))
            bf.seek(0)
            return send_file(bf, mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
    
        except Exception as e:
            logger.exception(e)
            return make_response('Error', 301)
    
    16 条回复    2019-08-27 20:04:29 +08:00
    Nostalgiaaaa
        1
    Nostalgiaaaa  
       2019-08-19 17:05:24 +08:00
    试试 StringIO ?
    aieike
        2
    aieike  
    OP
       2019-08-19 17:06:54 +08:00
    @Nostalgiaaaa 我试了,但没成功,可能我的方法不对
    vZexc0m
        3
    vZexc0m  
       2019-08-19 17:26:19 +08:00
    sunhk25
        4
    sunhk25  
       2019-08-19 17:26:24 +08:00 via Android
    参考一下 https://zdyxry.github.io/2018/07/08/Flask-%E6%B5%81%E5%BC%8F%E5%93%8D%E5%BA%94/
    这个功能以后有时间也想实现一下
    julyclyde
        5
    julyclyde  
       2019-08-19 17:38:34 +08:00
    @aieike “没成功”三个字没什么信息量
    你需要写的是“但是遇到了叉叉错误”
    aieike
        6
    aieike  
    OP
       2019-08-19 17:48:20 +08:00
    @vZexc0m 谢谢, 用这句解决了
    response = send_file(buffer,
    attachment_filename=filename,
    as_attachment=True)
    wuwukai007
        7
    wuwukai007  
       2019-08-19 18:09:22 +08:00 via Android
    有个问题,这个 io 是放在内存当中,如何放入 redis 中呢,或者集成到类似 django 的 cache 中
    janxin
        8
    janxin  
       2019-08-19 18:13:56 +08:00
    @wuwukai007 这个 io 是 file-like,支持读写操作
    wuwukai007
        9
    wuwukai007  
       2019-08-19 18:17:38 +08:00 via Android
    @ janxin 我的意思是,如果用户量大的话,这个 io 是用的本地的内存,怎么用 redis 之类作为 io 的存储
    reself
        10
    reself  
       2019-08-19 21:47:11 +08:00 via Android
    用 BytesIO 试试看,pandas 有个 ExcelWriter 组件,可以往 filelike 的对象里写东西。对了,io 对象写好过后记得要 seek(0)。
    1462326016
        11
    1462326016  
       2019-08-20 08:18:07 +08:00
    一楼的意思应该是 BytesIO ?
    ebingtel
        12
    ebingtel  
       2019-08-20 08:59:32 +08:00
    @wuwukai007 既然是 file-like,可以 read 出来,存进 redis 的吧?但是存个 excel 的 io 好,还是存原始的数据,这个还需要权衡下
    aieike
        13
    aieike  
    OP
       2019-08-20 10:11:04 +08:00
    @reself 对的, 我当时没有 seek(0), 也没加 minetype, 所以报错了
    aieike
        14
    aieike  
    OP
       2019-08-20 10:17:33 +08:00
    还有一个问题,想问一下, 这个 Bytesio 需不需要像文件那样 close
    LUXiaobo
        15
    LUXiaobo  
       2019-08-21 15:01:31 +08:00
    试试 tempfile
    aieike
        16
    aieike  
    OP
       2019-08-27 20:04:29 +08:00
    @LUXiaobo 是个不错的方法[赞]
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2807 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 13:27 · PVG 21:27 · LAX 05:27 · JFK 08:27
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.