4

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.

StevenMurray
  • 742
  • 2
  • 7
  • 18
  • You can use the python GZip library to zip in memory. But I am not sure if you can make the PDF in memory. you can also check out (http://stackoverflow.com/questions/6413441/python-pdf-library) and xhtml2pdf. – pranshus Jan 15 '13 at 09:57

2 Answers2

6

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

StevenMurray
  • 742
  • 2
  • 7
  • 18
2

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

Krzysztof Szularz
  • 5,151
  • 24
  • 35