Вернуть объект рабочей книги openpyxl как HttpResponse в django. Является ли это возможным?

Мне нужно предоставить данные с форматированием Excel из базы данных django для посетителей.

Единственный способ, которым я могу думать, состоит в следующих шагах:

  • Извлечь данные из базы данных.
  • Оберните его с помощью объекта Workbook из openpyxl.
  • Сохраните его где-нибудь временно.
  • Прочитайте его снова как "rb".
  • образ возврата excel mime.
  • Удалить файл excel на диске. (Это бесполезно сейчас?)

Это должно сделать это. Но, я думаю, есть еще один лучший способ сделать это. Я имею в виду возможно, есть способ вернуть объект openpyxl как HttpResponse напрямую без промежуточной файловой среды.

Итак, мой вопрос здесь: можно ли вернуть openpyxl Worbook объект? (Я новичок в openpyxl)

Ответ 1

Вам на самом деле не нужно сохранять данные где-либо на диске; У openpyxl есть способ сделать это, хотя это не очень хорошо документировано. Давным-давно я создал что-то вроде этого с помощью xlwt, но недавно я также создал нечто подобное в среде Falcon, используя 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)

UPDATE: Теперь это намного проще, так как я полностью переписал мою старую библиотеку django-excel-response, используя openpyxl! Теперь его можно найти здесь: https://github.com/tarkatronic/django-excel-response

Вы можете установить его с pip install django-excel-response и начать использовать его как альтернативу Django HttpResponse! Включена минимальная документация, приветствуются улучшения/предложения. :)

Ответ 2

это сработало для меня

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