StevenMurray
StevenMurray

Reputation: 752

Python/Django - Can I create multiple pdf file-like objects, zip them and send as attachment?

I'm using Django to create a web app where some parameters are input and plots are created. I want to have a link which will be to download ALL the plots in a zip file. To do this, I am writing a view which will create all the plots (I've already written views that create each of the single plots and display them), then zip them up, saving the zip file as the response object.

One way I could do this is to create each plot, save it as a pdf file to disk, and then at the end, zip them all up as the response. However, I'd like to sidestep the saving to disk if that's possible?

Cheers.

Upvotes: 4

Views: 2341

Answers (2)

StevenMurray
StevenMurray

Reputation: 752

This is what worked for me, going by Krzysiek's suggestion of using StringIO. Here canvas is a canvas object created by matplotlib.

#Create the file-like objects from canvases
file_like_1 = StringIO.StringIO()
file_like_2 = StringIO.StringIO()
#... etc...
canvas_1.print_pdf(file_like_1)
canvas_2.print_pdf(file_like_2)
#...etc....

#NOW create the zipfile
response = HttpResponse(mimetype='application/zip')
response['Content-Disposition'] = 'filename=all_plots.zip'

buff = StringIO.StringIO()
archive = zipfile.ZipFile(buff,'w',zipfile.ZIP_DEFLATED)
archive.writestr('plot_1.pdf',file_like_1.getvalue())
archive.writestr('plot_2.pdf',file_like_2.getvalue())
#..etc...
archive.close()
buff.flush()
ret_zip = buff.getvalue()
buff.close()
response.write(ret_zip)
return response

The zipping part of all of this was taken from https://code.djangoproject.com/wiki/CookBookDynamicZip

Upvotes: 6

Krzysztof Szularz
Krzysztof Szularz

Reputation: 5249

Look at the StringIO python module. It implements file behavior on in-memory strings.

Upvotes: 2

Related Questions