【问题标题】:Odoo 12. How to convert Binary File to Zip?Odoo 12. 如何将二进制文件转换为 Zip?
【发布时间】:2020-11-03 14:33:21
【问题描述】:

我需要导入一个仅包含 xml 文件的 zip 文件。

我的向导如下所示:

class ZipImportsWizard(models.Model):
    _name = 'import.zip.dte'

    type = fields.Selection([('purchase', 'Purchases'),('sale', 'Sales'),], string="Type", default="purchase")
    file = fields.Binary(string='ZIP File', store=True)

我需要打开这个 zip 文件并检查内容。 如果内容正常,我必须将其发送到另一个方法。

问题是,当我上传文件时,它会转换为二进制文件,所以我不能使用 zipfile 库来处理它。

如何将此二进制文件再次转换为 Zip 文件以使用它?

【问题讨论】:

    标签: python odoo binaryfiles zipfile odoo-12


    【解决方案1】:

    我没有使用 odoo 的经验;但是:

    如果您有一个字节变量(二进制数据),您可以使用io.BytesIOzipfile 使用标准python 库将其作为Zipfile 读取:

    from io import BytesIO
    import zipfile
    
     # I assume ths contains the zipfile uploaded by the user.
     uploaded_zipfile = fields.Binary(string='ZIP File', store=True)
    
    with BytesIO(uploaded_zipfile) as fp:
       userzip = zipfile.ZipFile(fp, 'r')
    
       # You can extract the zip like this:
       userzip.extractall()
    
       # Or you can check the contents without extracting all the file
       whats_inside_the_zip = userzip.infolist()
    
    
    

    【讨论】:

    • 我试过你的代码。不幸的是,它没有用,问题出在“userzip = zipfile.ZipFile(fp, 'r')”行......它返回:“zipfile.BadZipFile: File is not a zip file”
    • fields.Binary() 返回的类是什么?我以为那是“字节”。
    • 是的。我想我必须将其转换为 zip
    【解决方案2】:

    我能够自己找到解决方案,还要感谢@astronautlevel 在此Similar question 中的回答

    from odoo import fields, models, _
    from odoo.exceptions import UserError, ValidationError
    import zipfile
    import tempfile
    
    class ZipImportsWizard(models.Model):
        _name = 'import.zip.dte'
    
        type = fields.Selection([('purchase', 'Purchases'),('sale', 'Sales'),], string="Type", default="purchase")
        file = fields.Binary(string='ZIP File', store=True)
        file_name = fields.Char('File name')
    
        def read_files_from_zip(self):
            file = base64.decodestring(self.zip_file)
            fobj = tempfile.NamedTemporaryFile(delete=False)
            fname = fobj.name
            fobj.write(file)
            fobj.close()
    
            zipzip = self.zip_file
            f = open(fname, 'r+b')  
            data = f.read()
            f.write(base64.b64decode(zipzip))
            pos = data.find(b'\x50\x4b\x05\x06')
            f.seek(pos + 22)
            with zipfile.ZipFile(f, 'r') as zip_file: 
                # do some stuff
                
                f.close()
    
            return
    

    【讨论】:

      猜你喜欢
      • 2014-05-11
      • 2017-07-11
      • 1970-01-01
      • 2015-11-07
      • 2017-06-28
      • 1970-01-01
      • 2021-01-07
      • 2020-03-16
      • 1970-01-01
      相关资源
      最近更新 更多