37đź‘Ť
Give it a try:
from openpyxl.writer.excel import save_virtual_workbook
...
response = HttpResponse(save_virtual_workbook(wb), content_type='application/vnd.ms-excel')
save_virtual_workbook
was specially designed for your use case. Here’s a docstring:
“””Return an in-memory workbook, suitable for a Django response.”””
5đź‘Ť
On at least some versions of django/python/openpyxl, the given solution does not work. See https://bitbucket.org/openpyxl/openpyxl/issues/657/save_virtual_workbook-generates-junk-data
Simple working solution:
wb = Workbook(write_only=True, encoding='utf-8')
ws = wb.create_sheet()
for row in data:
ws.append([str(cell) for cell in row])
response = HttpResponse(content_type='application/vnd.ms-excel')
wb.save(response)
What’s happening here is that Django’s HttpResponse is a file-like object. Workbook.save()
can take a file-like object. (Internally, it uses zipfile, which takes either a filename or a file-like object.)
If you’re manipulating the file in memory, this is the simplest and probably most efficient solution. A streaming response doesn’t really make sense since the data is not being created with a generator. Even if save_virtual_workbook works, the data it writes is generated as a block before it’s readable.
The other option would be to create a NamedTemporaryFile (from tempfile or Django’s wrapper), pass that into Workbook.save()
, then use FileResponse to stream that from the filesystem instead of from memory.
- [Django]-How do I use a dictionary to update fields in Django models?
- [Django]-Warning: cannot find svn location for distribute==0.6.16dev-r0
- [Django]-Django ManyToMany filter()
4đź‘Ť
I usually use
ws = wb.add_sheet("Pi")
instead of
ws = wb.create_sheet()
ws.title = "Pi"
Moreover, you can try to do: (see documentation)
wb.save(stream)
and then use stream in HttpResponse.
- [Django]-How to Unit test with different settings in Django?
- [Django]-Why load staticfiles for every template even if it is extended?
- [Django]-Generating a Random Hex Color in Python
0đź‘Ť
You can try also the following code lines.
You can also set your file name as you want.
wb = Workbook()
..............
..............
response = HttpResponse(save_virtual_workbook(wb),content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
response['Content-Disposition'] = 'attachment; filename='+str(yourFileName)+'_report'+'.xlsx'
return response
- [Django]-Python Django Rest Framework UnorderedObjectListWarning
- [Django]-How to verify if object exist in manytomany
- [Django]-Redirect to Next after login in Django