Odoo 12. 如何将二进制文件转换为 Zip?

Posted

技术标签:

【中文标题】Odoo 12. 如何将二进制文件转换为 Zip?【英文标题】:Odoo 12. How to convert Binary File to 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 文件以使用它?

【问题讨论】:

【参考方案1】:

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

如果您有一个字节变量(二进制数据),您可以使用io.BytesIO 和zipfile 使用标准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

【讨论】:

以上是关于Odoo 12. 如何将二进制文件转换为 Zip?的主要内容,如果未能解决你的问题,请参考以下文章

如何在CentOS 7.0 上安装Odoo 8.0

如何将字符串转换为 12 位二进制而不改变它在 asp.net c# 中的值

如何将python程序完全转换为exe文件? [复制]

提取 zip 文件并将其存储到图像或文件字段

如何将二进制资源转换为短数组?

C++如何将一个存有数据的文本文件转换为二进制文件?