当前位置: 代码迷 >> python >> 在 Django 中将 openpyxl 工作簿对象作为 HttpResponse 返回。 是否可以?
  详细解决方案

在 Django 中将 openpyxl 工作簿对象作为 HttpResponse 返回。 是否可以?

热度:69   发布时间:2023-06-13 13:35:31.0

我需要从 django 的数据库向访问者提供 excel 格式的数据。

我能想到的唯一方法是通过以下步骤:

  1. 从数据库中提取数据。
  2. 用来自openpyxl Workbook对象包装它。
  3. 暂时将其保存在某个地方。
  4. 再读一遍“rb”。
  5. 使用返回视图。
  6. 删除磁盘上的excel文件。 (现在没用了吧?)

那应该这样做。 但是,我认为还有另一种更好的方法来做到这一点。 我的意思是也许有一种方法可以直接将openpyxl对象作为HttpResponse返回,而无需中间文件介质。

所以,我的问题是:是否可以返回openpyxlWorbook对象? (我是openpyxl

您实际上不需要将数据保存在磁盘上的任何位置; openpyxl 有一种方法可以做到这一点,尽管它没有很好的记录。 很久以前,我使用 xlwt 创建,但我最近也在框架中使用 openpyxl 构建了类似的东西。

将这两者放在一起,您的代码将类似于以下内容:

from django.http import HttpResponse
from openpyxl import Workbook
from openpyxl.writer.excel import save_virtual_workbook


workbook = Workbook()
worksheet = workbook.active

# ... worksheet.append(...) all of your data ...

response = HttpResponse(content=save_virtual_workbook(workbook), mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
response['Content-Disposition'] = 'attachment; filename=myexport.xlsx'
return response

如果您要生成更大的文件,我建议您考虑使用 StreamingHttpResponse,但我相信这至少会让您有所收获。

这只是基于我参与的两个项目的合并的即兴片段,因此它可能不完全正确。 不过应该非常接近。 Falcon 中的输出如下所示:

response.content_type = 'application/octet-stream;'
response.set_header('Content-Disposition', 'attachment; filename=myexport.xlsx')
response.body = save_virtual_workbook(workbook)

更新:这现在更容易了,因为我使用 openpyxl 完全重写了我的旧django-excel-response库! 现在可以在这里找到: :

您可以使用pip install django-excel-response安装它,并开始使用它作为 Django 的HttpResponse的替代品! 包含的文档最少,欢迎提出改进/建议。 :)

由于 save_virtual_workbook 将过时,我使用了插入。

from openpyxl import Workbook
from tempfile import NamedTemporaryFile

def exportToExcel(request):
   workbook = Workbook()
   ...

   with NamedTemporaryFile() as tmp:
      workbook.save(tmp.name)
      tmp.seek(0)
      stream = tmp.read()

   response = HttpResponse(content=stream, content_type='application/ms-excel', )
   response['Content-Disposition'] = f'attachment; filename=ExportedExcel-{datetime.now().strftime("%Y%m%d%H%M")}.xlsx'
   return response

这对我有用

from openpyxl import Workbook, load_workbook
from openpyxl.writer.excel import save_virtual_workbook

wb = Workbook()
...

response = HttpResponse(content=save_virtual_workbook(wb), content_type='application/ms-excel')
response['Content-Disposition'] = 'attachment; filename=Inform.xlsx'
return response