【问题标题】:How to check the uploaded file is csv or xls in python?如何在python中检查上传的文件是csv还是xls?
【发布时间】:2014-06-24 07:29:02
【问题描述】:

How to check is upload file is CSV or XLS 。 如何在python中检查它。我正在将文件导入到 openerp 中的二进制字段,该字段可以作为二进制对象检索。我需要读取文件并将数据导入表。用户可以上传 csv 或 xls 文件。只知道我可以使用 csv 包或 xlrd 包。

【问题讨论】:

  • XLS/XLSX 不会以字节编码吗? CSV 只是一个标准文本文件。
  • 一般你只能猜测。唯一干净的解决方案是获取 HTTP 请求的“Content-Type”。如果您不指定二进制数据是什么,它可以是任何东西。这就是 Content-Type 字段的原因。
  • 在下面查看我的解决方案。我已经测试了它的有效性。

标签: python excel csv


【解决方案1】:

只是对 PolyWhirl 帖子的扩展,其中包含我遇到的一些边缘情况。

def isExcelDoc(file):

    excelSigs = [
        ('xlsx', b'\x50\x4B\x05\x06', 2, -22, 4),
        ('xls', b'\x09\x08\x10\x00\x00\x06\x05\x00', 0, 512, 8),  #Saved from Excel
        ('xls', b'\x09\x08\x10\x00\x00\x06\x05\x00', 0, 1536, 8), #Saved from LibreOffice Calc
        ('xls', b'\x09\x08\x10\x00\x00\x06\x05\x00', 0, 2048, 8)  #Saved from Excel then saved from Calc
]

    for sigType, sig, whence, offset, size in excelSigs:
        with open(file, 'rb') as f:
            f.seek(offset, whence)
            bytes = f.read(size)

            if bytes == sig:
                return True

    return False

【讨论】:

    【解决方案2】:

    hex signature for an .xls 文件如下:

    Excel 电子表格副标题 (MS Office)

    09 08 10 00 00 06 05 00 [512 byte offset]

    您可以在 Wikipedia 上阅读其他各种签名。

    我相信你可以做这样的事情。这是未经测试的,但你可以摆弄它直到它工作。如有任何建议或更改,请留下 cmets。谢谢!

    xls_sig = b'\x09\x08\x10\x00\x00\x06\x05\x00'
    offset = 512
    size = 8
    
    with open('spreadsheet.xls', 'rb') as f:
        f.seek(offset)       # Seek to the offset.
        bytes = f.read(size) # Capture the specified number of bytes.
    
        if bytes == xls_sig:
            print 'Uploaded file is an xls.'
        else:
            print 'File is not an xls.'
    

    更新 1

    对此进行了测试,我可以验证它是否适用于检测.xls 文件。

    更新 2

    我开发了一个程序来确定文件是 xls 还是 xlsx:

    import codecs
    
    xlsx_sig = b'\x50\x4B\x05\06'
    xls_sig = b'\x09\x08\x10\x00\x00\x06\x05\x00'
    
    filenames = [
        ('spreadsheet.xls', 0, 512, 8),
        ('spreadsheet.xlsx', 2, -22, 4)]
    
    for filename, whence, offset, size in filenames:
        with open(filename, 'rb') as f:
            f.seek(offset, whence) # Seek to the offset.
            bytes = f.read(size)   # Capture the specified number of bytes.
    
            print codecs.getencoder('hex')(bytes)
    
            if bytes == xls_sig:
                msg = '"{}" is an xls.'
            elif bytes == xlsx_sig:
                msg = '"{}" is an xlsx.'
            else:
                msg = '"{}" is not an Excel document.'
            print msg.format(filename)
    

    这是输出:

    ('0908100000060500', 8)
    "spreadsheet.xls" is an xls.
    ('504b0506', 4)
    "spreadsheet.xlsx" is an xlsx.
    

    【讨论】:

    • 此方法可验证文件,但当我尝试使用 XLRD 读取 xlsx 文件时,出现文件不受支持或损坏的错误。
    • 就像一个边缘案例。如果您有 LibreOffice Calc 保存的 .xls 文件,则偏移量为 1536。
    • 请注意:xlsx_sig = b'\x50\x4B\x05\06' 有点误导;应该将 open_xml_sig 读取为具有此签名的文件也可以是 .docx 或 .pptx 文件。
    【解决方案3】:

    您可以尝试,如果不起作用,请尝试其他方法。

    import xlrd
    import csv
    
    try:
        # reading the file by xlrd
        ...
        print "Thanks for your Excel file"
    except: # if you find specific Exception types, use them here
        try:
            # reading as CSV file
            ...
            print "thanks for your CSV file"
        except: # if you find specific Exception types, use them here
            print "sorry, now way, give me some usable file."
    

    【讨论】:

    猜你喜欢
    • 2013-10-25
    • 1970-01-01
    • 2012-02-23
    • 2019-10-15
    • 2017-07-21
    • 2021-11-14
    • 2011-05-09
    • 2012-08-22
    • 1970-01-01
    相关资源
    最近更新 更多