Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Serving Excel(xlsx) file to the user for download in Django(Python)

I'm trying create and serve excel files using Django. I have a jar file which gets parameters and produces an excel file according to parameters and it works with no problem. But when i'm trying to get the produced file and serve it to the user for download the file comes out broken. It has 0kb size. This is the code piece I'm using for excel generation and serving.

def generateExcel(request,id):
    if os.path.exists('./%s_Report.xlsx' % id):
        excel = open("%s_Report.xlsx" % id, "r")
        output = StringIO.StringIO(excel.read())
        out_content = output.getvalue()
        output.close()
        response = HttpResponse(out_content,content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
        response['Content-Disposition'] = 'attachment; filename=%s_Report.xlsx' % id
        return response
    else:
        args = ['ServerExcel.jar', id]
        result = jarWrapper(*args) # this creates the excel file with no problem
        if result:
            excel = open("%s_Report.xlsx" % id, "r")
            output = StringIO.StringIO(excel.read())
            out_content = output.getvalue()
            output.close()
            response = HttpResponse(out_content,content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
            response['Content-Disposition'] = 'attachment; filename=%s_Report.xlsx' % id
            return response
        else:
            return HttpResponse(json.dumps({"no":"excel","no one": "cries"}))

I have searched for possible solutions and tried to use File Wrapper also but the result did not changed. I assume i have problem with reading the xlsx file into StringIO object. But dont have any idea about how to fix it

like image 771
Srht Avatar asked Nov 21 '14 13:11

Srht


2 Answers

Why on earth are you passing your file's content to a StringIO just to assign StringIO.get_value() to a local variable ? What's wrong with assigning file.read() to your variable directly ?

def generateExcel(request,id):
    path = './%s_Report.xlsx' % id # this should live elsewhere, definitely
    if os.path.exists(path):
        with open(path, "r") as excel:
            data = excel.read()

        response = HttpResponse(data,content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
        response['Content-Disposition'] = 'attachment; filename=%s_Report.xlsx' % id
        return response
    else:
        # quite some duplication to fix down there

Now you may want to check weither you actually had any content in your file - the fact that the file exists doesn't mean it has anything in it. Remember that you're in a concurrent context, you can have one thread or process trying to read the file while another (=>another request) is trying to write it.

like image 183
bruno desthuilliers Avatar answered Oct 21 '22 22:10

bruno desthuilliers


In addition to what Bruno says, you probably need to open the file in binary mode:

excel = open("%s_Report.xlsx" % id, "rb")
like image 44
Daniel Roseman Avatar answered Oct 21 '22 22:10

Daniel Roseman