Last active
November 20, 2020 08:40
-
-
Save zulzeen/05a6e6f6913a359a983fbbfaefbb925b to your computer and use it in GitHub Desktop.
Create in-memory zip file with multiple in-memory CSVs to serve with Django
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from django.http import HttpResponse | |
import io | |
import csv | |
from zipfile import ZipFile | |
def get_zip(request): | |
# We generate rows for our different files | |
first_csv_rows = generate_rows_for_first_csv() | |
second_csv_rows = generate_rows_for_second_csv() | |
# We create file-like objects to be used as in-memory containers | |
# CSV files requires to be StringIO while Zip files are binary files | |
with io.BytesIO() as zip_buffer, io.StringIO() as first_csv, io.StringIO() as second_csv: | |
# We create a writer for each of our CSV files | |
first_writer = csv.writer(first_csv) | |
second_writer = csv.writer(second_csv) | |
# We write our rows in our CSV files | |
first_writer.writerows(first_rows) | |
second_writer.writerows(second_rows) | |
# We create our Zip file from our file-like object | |
with ZipFile(zip_buffer, 'w') as zip_file: | |
# Then write our CSV file-like | |
zip_file.writestr('first.csv', first_csv.getvalue()) | |
zip_file.writestr('second.csv', second_csv.getvalue()) | |
# Exiting the "with" statement closes the Zip file, effectivly "writing" data in our | |
# file-like BytesIO object | |
# We then pass the binary content of our binary file-like to our response | |
response = HttpResponse(zip_buffer.getbuffer().tobytes(), content_type="application/zip") | |
# Every file-like object is now closed | |
# We precise our response has an attachement | |
response['Content-disposition'] = 'attachement; filename=export.zip' | |
# We return our response | |
return response |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Of course, if we've had more than two files, a "for" iteration would've been welcome, but for readability I kept it simple.