1

I'm trying to compress a Excel BytesIO stream into a ZIP BytesIO stream but ValueError: stat: embedded null character in path is called when I use write(). I used pyzipper and pyminizip but neither worked well.

def __compress_excel__(self, excel_buffer):
    zip_buffer = BytesIO()
    password = b'password'
    zip_buffer = pyzipper.AESZipFile(zip_stream,  mode='w')
    zip_buffer.setpassword(password)
    zip_buffer.write(excel_buffer.getvalue())
    return zip_buffer.getvalue()

I want to avoid using a temp file to do this. Regards.

UPDATE

Now thanks to martineau comments, Excel could be compressed now, but I have a new problem is that setpassword() from ZipFile doesn't work. A ZIP is created but when in uncompress it, no password is required.

def __compress_excel__(self, excel_buffer):
    zip_stream = BytesIO()
    password = b'password'
    with ZipFile(zip_stream ,  mode='w') as zipf:
        zipf.setpassword(password)
        zipf.writestr('excel.xlsx', excel_buffer.getvalue())
        
    return zip_stream.getvalue()

Regards

Minitorr
  • 17
  • 7
  • From the error message it sound like something you're using expected to be passed a file path, not an open file. You should be able compress the `excel_buffer` using the `zlib` module in the standard library. See [this answer](https://stackoverflow.com/a/10452244/355230) for an example. – martineau Mar 29 '22 at 10:33
  • Then you can't do what you want unless you can find something that lets you pass the data directly (like the `zlib` module does). – martineau Mar 29 '22 at 10:37
  • Does Zlib accept compression with password ? – Minitorr Mar 29 '22 at 10:39
  • I don't think so (check its fine [documentation](https://docs.python.org/3/library/zlib.html#module-zlib)). You may be able to encrypt the data yourself using some other library. – martineau Mar 29 '22 at 10:42
  • Oh that's a problem. The original idea is to compress a Excel buffer into a ZIP buffer protected with a password. If I encrypt the data, then it can't be dencrypt when the ZIP is uncompressed. For more details, I will get bytes from ZIP buffer and use as an attachment with smtplib. That's the reason why I need a ZIP buffer instead of a ZIP file in disk. – Minitorr Mar 29 '22 at 10:45
  • Python's [`zipfile`](https://docs.python.org/3/library/zipfile.html#module-zipfile) module will allow you to add members to a `zipfile.ZipFile` instance from data in a buffer using the [`ZipFile.writestr()`](https://docs.python.org/3/library/zipfile.html#zipfile.ZipFile.writestr) method. You can specify a password for encrypting the data when you open the member for writing via the [`ZipFile.open()`](https://docs.python.org/3/library/zipfile.html#zipfile.ZipFile.open) method. – martineau Mar 29 '22 at 11:10
  • Oh! That method works very well to compress the Excel but the problem is when I uncompress the ZIP file, no password is asked so **setpassword()** is not working. – Minitorr Mar 29 '22 at 11:14
  • The password will need to be supplied when opening the zipfile for reading later. – martineau Mar 29 '22 at 11:18
  • So how can I add a password to ZIP file? – Minitorr Mar 29 '22 at 11:25
  • My apologies, apparently Python's `zipfile` module cannot *create* password protected zip archives, only read them — see [How to create an encrypted ZIP file?](https://stackoverflow.com/questions/17250/how-to-create-an-encrypted-zip-file). So, as I said earlier you will need to find some (third-party) module that accepts in-memory data, not just a file path (or write your own code that supports that). – martineau Mar 29 '22 at 18:44

0 Answers0