首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何从Falcon resp.stream获取.xlsx文件

如何从Falcon resp.stream获取.xlsx文件
EN

Stack Overflow用户
提问于 2019-04-30 03:10:08
回答 2查看 672关注 0票数 0

我正在尝试从API中获取生成的.xlsx文件。

我在后端有以下代码:

代码语言:javascript
复制
from io import BytesIO
from openpyxl import Workbook

@api_resource('/get_report')
class Report:
    @auth_required()
    def on_get(self, req, resp):
        wb = Workbook()
        ws = wb.active
        ws.title = "report"
        ws['C9'] = 'hello world'
        f = BytesIO()
        wb.save(f)
        f.seek(0)
        resp.stream = f
        resp.content_type = \
            'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'

前台代码如下:

代码语言:javascript
复制
ReportsAPI.getReport(filters).then(resp => {
 openXLS([resp.data], `report.xlsx`);
});

function openXLS(blob_data, filename) {
  let blob = new Blob(blob_data, {
    type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
  });
  let url = window.URL.createObjectURL(blob);
  let link = document.createElement("a");
  document.body.appendChild(link);
  link.style = "display: none";
  link.href = url;
  link.download = filename;
  link.click();
  document.body.removeChild(link);
  window.URL.revokeObjectURL(url);
}

我正在通过API请求下载文件,但文件已损坏。如果我将文件保存在后台的文件系统中(`wb.save('test.xlsx')`

代码语言:javascript
复制
), the file opens without problems.

I tried to save the file as indicated in the documentation for openpyxl, but it does not work. 

...
from tempfile import NamedTemporaryFile

wb = Workbook()
with NamedTemporaryFile() as tmp:
     wb.save(tmp.name)
     tmp.seek(0)
     resp.stream = BytesIO(tmp.read())

我做错了什么?

在终端file -bi filename.xlsx中,在正常文件上返回application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; charset=binary,但在损坏文件上返回application/zip; charset=binary

我尝试从终端向API发出请求。

代码语言:javascript
复制
http  GET 'http://127.0.0.1:8000/api/v1/get_report' > test.xlsx

并且文件没有被破坏。问题似乎出在前端。

在我看来,问题出在编码上,但我不能确定。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-05-28 04:56:59

问题出在我对api的请求中,我使用axios,默认情况下,它总是在JSON中处理数据。只需将响应类型设置为arraybuffer

代码语言:javascript
复制
class ReportsAPI {
  getReport(filters) {
    return instance.get(`/get_report`, {
      params: { ...filters },
      responseType: "arraybuffer"
    });
  }
}
票数 0
EN

Stack Overflow用户

发布于 2019-04-30 14:01:05

尝试将header设置为响应,如下所示:

代码语言:javascript
复制
def on_get(self, req, resp):
    wb = Workbook()
    ws = wb.active
    ws.title = "report"
    ws['C9'] = 'hello world'
    f = BytesIO()
    wb.save(f)
    f.seek(0)
    filename = 'sample.xlsx'
    resp.stream = f
    resp.content_type = \
        'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'

    resp.set_header("Content-Disposition", f"attachment; filename={filename}")
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55909451

复制
相关文章

相似问题

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