Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django generate csv file on view and download

Tags:

python

csv

django

I have this code:

    with open('stockitems_misuper.csv', 'wb') as myfile:
        wr = csv.writer(myfile, quoting=csv.QUOTE_ALL)
        wr.writerows(file_rows)

    response = HttpResponse(myfile, content_type='text/csv')
    response['Content-Disposition'] = 'attachment; filename=stockitems_misuper.csv'
    return response

I get the error:

I/O operation on closed file

How can I send the created csv file to the front end?

like image 422
Alejandro Veintimilla Avatar asked Jan 17 '17 20:01

Alejandro Veintimilla


People also ask

How do I create a CSV file and download in django?

Create it in memory and serve it from django. Create it on the disk, and return a HttpResponseRedirect to it, so that your webserver deals with the download itself (if the file is very large, you should use this option).

How can I download Excel file in django?

Download data as Excel file in Django: It is always recommended to user virtual environment. Once virtual environment is activated, Run this command to add xlwt package. Inside your view, import xlwt package. Use below code in your view in views.py file to create and download excel file.

How import and read CSV file in django?

Uploading CSV file: First create HTML form to upload the csv file. Use below code for the same. Important: Do not forget to include enctype="multipart/form-data" in form. Add a URL in URLpatterns.


1 Answers

you're passing the handle of the file being written (and not sure of your indentation, you could just be outside the with block.

Just reopen it in read mode.

with open('stockitems_misuper.csv', 'w', newline="") as myfile:  # python 2: open('stockitems_misuper.csv', 'wb')
    wr = csv.writer(myfile, quoting=csv.QUOTE_ALL)
    wr.writerows(file_rows)

with open('stockitems_misuper.csv') as myfile:
    response = HttpResponse(myfile, content_type='text/csv')
    response['Content-Disposition'] = 'attachment; filename=stockitems_misuper.csv'
    return response

or better: write to a io.StringIO() instance, and pass that, avoiding to create the file.

import io,csv

buffer = io.StringIO()  # python 2 needs io.BytesIO() instead
wr = csv.writer(buffer, quoting=csv.QUOTE_ALL)
wr.writerows(file_rows)

buffer.seek(0)
response = HttpResponse(buffer, content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename=stockitems_misuper.csv'

return response
like image 197
Jean-François Fabre Avatar answered Sep 28 '22 03:09

Jean-François Fabre