Sending multiple .CSV files to .ZIP without storing to disk in Python

前端 未结 3 1992
萌比男神i
萌比男神i 2020-12-31 17:50

I\'m working on a reporting application for my Django powered website. I want to run several reports and have each report generate a .csv file in memory that can be download

3条回答
  •  隐瞒了意图╮
    2020-12-31 18:39

    zipfile is a standard library module that does exactly what you're looking for. For your use-case, the meat and potatoes is a method called "writestr" that takes a name of a file and the data contained within it that you'd like to zip.

    In the code below, I've used a sequential naming scheme for the files when they're unzipped, but this can be switched to whatever you'd like.

    import zipfile
    import StringIO
    
    zipped_file = StringIO.StringIO()
    with zipfile.ZipFile(zipped_file, 'w') as zip:
        for i, file in enumerate(files):
            file.seek(0)
            zip.writestr("{}.csv".format(i), file.read())
    
    zipped_file.seek(0)
    

    If you want to future-proof your code (hint hint Python 3 hint hint), you might want to switch over to using io.BytesIO instead of StringIO, since Python 3 is all about the bytes. Another bonus is that explicit seeks are not necessary with io.BytesIO before reads (I haven't tested this behavior with Django's HttpResponse, so I've left that final seek in there just in case).

    import io
    import zipfile
    
    zipped_file = io.BytesIO()
    with zipfile.ZipFile(zipped_file, 'w') as f:
        for i, file in enumerate(files):
            f.writestr("{}.csv".format(i), file.getvalue())
    
    zipped_file.seek(0)
    

提交回复
热议问题