35

On a django site, I want to generate an excel file based on some data in the database.

I'm thinking of using xlwt, but it only has a method to save the data to a file. How can get the file to the HttpResponse object? Or maybe do you know a better library?

I've also found this snippet but it doesn't do what I need. All I want is a way to get the stream from the xlwt object to the response object (without writing to a temporary file)

jbochi
  • 28,816
  • 16
  • 73
  • 90
Adrian Mester
  • 2,523
  • 1
  • 19
  • 23

6 Answers6

56

neat package! i didn't know about this

According to the doc, the save(filename_or_stream) method takes either a filename to save on, or a file-like stream to write on.

And a Django response object happens to be a file-like stream! so just do xls.save(response). Look the Django docs about generating PDFs with ReportLab to see a similar situation.

edit: (adapted from ShawnMilo's comment):

def xls_to_response(xls, fname):
    response = HttpResponse(mimetype="application/ms-excel")
    response['Content-Disposition'] = 'attachment; filename=%s' % fname
    xls.save(response)
    return response

then, from your view function, just create the xls object and finish with

return xls_to_response(xls,'foo.xls')
Javier
  • 60,510
  • 8
  • 78
  • 126
  • thanks, I thought it should be something like this, I just didn't know where to look. I'll give it a try – Adrian Mester May 19 '09 at 23:47
  • 6
    This works great, but not until you figure out the syntax. The trick is to create an HttpResponse object and save the xlwt workbook to it. Sample: xls_response = HttpResponse(mimetype="application/ms-excel") xls_response['Content-Disposition'] = 'attachment; filename=foo.xls' xls.save(xls_response) return xls_response – ShawnMilo Jun 30 '09 at 15:20
  • Your answer looks really great! But I'm just confused what his xls object is? Since it has a save() method, I thought it was "xls = xlwt.Workbook()", but this threw me 500 back, any help please? @Javier – Fisher Coder Jun 30 '16 at 18:13
  • What do I need to do in JavaScript to receive this `.xls` file in frontend? – srgbnd Oct 30 '16 at 14:05
  • "application/vnd.ms-excel" would be a better mimetype choice. Specifying `content_type='application/vnd.ms-excel; charset=utf-8'` instead of mimetype would be even better. – rioted Oct 25 '18 at 18:08
6

***UPDATE: django-excel-templates no longer being maintained, instead try Marmir http://brianray.github.com/mm/

Still in development as I type this but http://code.google.com/p/django-excel-templates/ Django excel templates project aims to do what your asking.

Specifically look at the tests. Here is a simple case:

#
from django_excel_templates import *
from django_excel_templates.color_converter import *
from models import *
from django.http import HttpResponse

def xls_simple(request):

    ## Simple ##
    testobj = Book.objects.all()

    formatter = ExcelFormatter()
    simpleStyle = ExcelStyle(vert=2,wrap=1)
    formatter.addBodyStyle(simpleStyle)
    formatter.setWidth('name,category,publish_date,bought_on',3000)
    formatter.setWidth('price',600)
    formatter.setWidth('ebook',1200)
    formatter.setWidth('about',20000)

    simple_report = ExcelReport()
    simple_report.addSheet("TestSimple")
    filter = ExcelFilter(order='name,category,publish_date,about,bought_on,price,ebook')
    simple_report.addQuerySet(testobj,REPORT_HORZ,formatter, filter)

    response = HttpResponse(simple_report.writeReport(),mimetype='application/ms-excel')
    response['Content-Disposition'] = 'attachment; filename=simple_test.xls'
    return response
brianray
  • 1,139
  • 1
  • 12
  • 16
2

You might want to check huDjango which comes fith a function called serializers.queryset_to_xls() do convert a queryset into an downloadable Excel Sheet.

max
  • 29,122
  • 12
  • 52
  • 79
2

You can save your XLS file to a StringIO object, which is file-like.

You can return the StringIO object's getvalue() in the response. Be sure to add headers to mark it as a downloadable spreadsheet.

S.Lott
  • 384,516
  • 81
  • 508
  • 779
1

Use https://bitbucket.org/kmike/django-excel-response

satels
  • 789
  • 6
  • 13
0

If your data result doesn't need formulas or exact presentation styles, you can always use CSV. any spreadsheet program would directly read it. I've even seen some webapps that generate CSV but name it as .XSL just to be sure that Excel opens it

Javier
  • 60,510
  • 8
  • 78
  • 126
  • I've also read somewhere that you can return an html file that excel can read, but I want to use formulas and styling, so that's no good. – Adrian Mester May 19 '09 at 23:48