Adrian Z. February 2016

Django Pandas to http response (download file)

Python: 2.7.11

Django: 1.9

Pandas: 0.17.1

How should I go about creating a potentially large xlsx file download? I'm creating a xlsx file with pandas from a list of dictionaries and now need to give the user possibility to download it. The list is in a variable and is not allowed to be saved locally (on server).

Example:

df = pandas.DataFrame(self.csvdict)
writer = pandas.ExcelWriter('pandas_simple.xlsx', engine='xlsxwriter')
df.to_excel(writer, sheet_name='Sheet1')
writer.save()

This example would just create the file and save it where the executing script is located. What I need is to create it to a http response so that the user would get a download prompt.

I have found a few posts about doing this for a xlsxwriter but non for pandas. I also think that I should be using 'StreamingHttpResponse' for this and not a 'HttpResponse'.

Answers


America February 2016

You're mixing two requirements that should be separate:

  1. Creating a .xlsx file using python or pandas--it looks like you're good on this part.

  2. Serving a downloadable file (django); see this post or maybe this one


jmcnamara February 2016

With Pandas 0.17+ you can use a StringIO/BytesIO object as a filehandle to pd.ExcelWriter. For example:

import pandas as pd
import StringIO

output = StringIO.StringIO()

# Use the StringIO object as the filehandle.
writer = pd.ExcelWriter(output, engine='xlsxwriter')

# Write the data frame to the StringIO object.
pd.DataFrame().to_excel(writer, sheet_name='Sheet1')
writer.save()
xlsx_data = output.getvalue()

print len(xlsx_data)

After that follow the XlsxWriter Python 2/3 HTTP examples.

For older versions of Pandas you can use this workaround.


MartinH February 2016

Jmcnamara is pointing you in the rigth direction. Translated to your question you are looking for the following code:

sio = StringIO()
PandasDataFrame = pandas.DataFrame(self.csvdict)
PandasWriter = pandas.ExcelWriter(sio, engine='xlsxwriter')
PandasDataFrame.to_excel(PandasWriter, sheet_name=sheetname)
PandasWriter.save()

sio.seek(0)
workbook = sio.getvalue()

response = StreamingHttpResponse(workbook, content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
response['Content-Disposition'] = 'attachment; filename=%s' % filename

Notice the fact that you are saving the data to the StringIO variable and not to a file location. This way you prevent the file being saved before you generate the response.

Post Status

Asked in February 2016
Viewed 2,294 times
Voted 13
Answered 3 times

Search




Leave an answer