【问题标题】:Reading/parsing Excel (xls) files with Python [closed]使用 Python 读取/解析 Excel (xls) 文件 [关闭]
【发布时间】:2011-02-25 22:32:22
【问题描述】:

使用 Python 读取 Excel (XLS) 文件(不是CSV 文件)的最佳方法是什么。

是否有 Python 默认支持的内置包来执行此任务?

【问题讨论】:

    标签: python xls


    【解决方案1】:

    我强烈推荐xlrd 来阅读.xls 文件。但是有一些限制(参考xlrd github page):

    警告

    此库将不再读取 .xls 文件以外的任何内容。为了 读取较新文件格式的替代方案,请参阅 http://www.python-excel.org/.

    以下内容也不受支持,但会安全可靠地支持 忽略:

    - Charts, Macros, Pictures, any other embedded object, including embedded worksheets.
    - VBA modules
    - Formulas, but results of formula calculations are extracted.
    - Comments
    - Hyperlinks
    - Autofilters, advanced filters, pivot tables, conditional formatting, data validation
    

    受密码保护的文件不受支持且无法由此读取 图书馆。

    voyager 提到了 COM 自动化的使用。几年前我自己做过这个,请注意,这样做是一个真正的 PITA。警告的数量巨大,文档缺乏且令人讨厌。我遇到了许多奇怪的错误和陷阱,其中一些需要花费数小时才能弄清楚。

    更新:对于较新的 .xlsx 文件,推荐的读写库似乎是 openpyxl(感谢 Ikar Pohorský)。

    【讨论】:

    • 对于 Excel 2007+ 文件 (.xlsx),您可能会使用 OpenPyXL
    • 聚会有点晚了,但是您对库覆盖 .xls 文件并保留宏/图片有什么建议吗?我使用 xlrd/xlwt/xlutils 创建了一个解决方案,直到最后才意识到宏/图片被删除了。我过去使用过 Openpyxl/XlsxWriter(用于 xlsx),但显然这些库都不适合我的用例。 Pandas 使用 xlrd 引擎是否也这样做?
    【解决方案2】:

    如果文件真的是一个旧的 .xls,这适用于我在 python3 上仅使用 base open() 和 pandas:

    df = pandas.read_csv(open(f, encoding = 'UTF-8'), sep='\t')
    

    请注意,我使用的文件是制表符分隔的。 less 或文本编辑器应该能够读取 .xls,以便您可以嗅出分隔符。

    我对 xlrd 不太满意,因为——我认为——UTF-8 问题。

    【讨论】:

    • 如果上述方法适合您,则您没有 Excel 文件,而是一个制表符分隔的文本文件,有时称为 TSV 文件。因此,xlrd 不会打开它。
    【解决方案3】:

    使用熊猫:

    import pandas as pd
    
    xls = pd.ExcelFile(r"yourfilename.xls") #use r before absolute file path 
    
    sheetX = xls.parse(2) #2 is the sheet number+1 thus if the file has only 1 sheet write 0 in paranthesis
    
    var1 = sheetX['ColumnName']
    
    print(var1[1]) #1 is the row number...
    

    【讨论】:

    • pandas 正在使用 xlrd 进行阅读;您还需要安装 xlrd 作为依赖项
    • 如果需要 xlrd 作为依赖,为什么不直接使用呢?
    【解决方案4】:

    对于较旧的.xls 文件,您可以使用xlrd

    您也可以通过导入直接使用xlrd。如下所示

    import xlrd
    wb = xlrd.open_workbook(file_name)
    

    或者你也可以使用pandas的@​​987654325@方法,但是不要忘记指定引擎,虽然默认是xlrd,但必须指定。

    pd.read_excel(file_name, engine = xlrd)
    

    它们都适用于较旧的.xls 文件格式。 事实上,当我使用OpenPyXL 时,我遇到了这个问题,我得到了以下错误

    InvalidFileException: openpyxl does not support the old .xls file format, please use xlrd to read this file, or convert it to the more recent .xlsx file format.
    

    【讨论】:

      【解决方案5】:
          with open(csv_filename) as file:
              data = file.read()
      
          with open(xl_file_name, 'w') as file:
              file.write(data)
      

      您可以使用内置软件包将 CSV 转换为上述的 excel。 CSV 可以使用内置的 dictreader 和 dictwriter 包来处理,其工作方式与 python 字典的工作方式相同。这很容易 我目前不知道任何用于 excel 的内置软件包,但我遇到了 openpyxl。它也非常简单明了您可以查看下面的代码 sn-p 希望对您有所帮助

          import openpyxl
          book = openpyxl.load_workbook(filename)
          sheet = book.active 
          result =sheet['AP2']
          print(result.value)
      

      【讨论】:

        【解决方案6】:

        我认为 Pandas 是最好的选择。已经有一个答案 here 与 Pandas 使用 ExcelFile 函数,但它对我来说不能正常工作。从here 我发现read_excel 功能很好:

        import pandas as pd
        dfs = pd.read_excel("your_file_name.xlsx", sheet_name="your_sheet_name")
        print(dfs.head(10))
        

        P.S.您需要安装xlrdread_excel 功能才能工作

        2020 年 3 月 21 日更新: 如您所见 herexlrd 引擎存在问题,将被弃用。 openpyxl 是最好的替代品。因此,如here 所述,规范语法应该是:

        dfs = pd.read_excel("your_file_name.xlsx", sheet_name="your_sheet_name", engine="openpyxl")
        

        【讨论】:

        • AttributeError: 'dict' 对象没有属性 'head'
        【解决方案7】:

        对于 xlsx,我喜欢之前发布为 https://web.archive.org/web/20180216070531/https://stackoverflow.com/questions/4371163/reading-xlsx-files-using-python 的解决方案。我只使用标准库中的模块。

        def xlsx(fname):
            import zipfile
            from xml.etree.ElementTree import iterparse
            z = zipfile.ZipFile(fname)
            strings = [el.text for e, el in iterparse(z.open('xl/sharedStrings.xml')) if el.tag.endswith('}t')]
            rows = []
            row = {}
            value = ''
            for e, el in iterparse(z.open('xl/worksheets/sheet1.xml')):
                if el.tag.endswith('}v'):  # Example: <v>84</v>                            
                    value = el.text
                if el.tag.endswith('}c'):  # Example: <c r="A3" t="s"><v>84</v></c>                                 
                    if el.attrib.get('t') == 's':
                        value = strings[int(value)]
                    letter = el.attrib['r']  # Example: AZ22                         
                    while letter[-1].isdigit():
                        letter = letter[:-1]
                    row[letter] = value
                    value = ''
                if el.tag.endswith('}row'):
                    rows.append(row)
                    row = {}
            return rows
        

        添加的改进是按工作表名称获取内容,使用 re 获取列并检查是否使用了共享字符串。

        def xlsx(fname,sheet):
            import zipfile
            from xml.etree.ElementTree import iterparse
            import re
            z = zipfile.ZipFile(fname)
            if 'xl/sharedStrings.xml' in z.namelist():
                # Get shared strings
                strings = [element.text for event, element
                           in iterparse(z.open('xl/sharedStrings.xml')) 
                           if element.tag.endswith('}t')]
            sheetdict = { element.attrib['name']:element.attrib['sheetId'] for event,element in iterparse(z.open('xl/workbook.xml'))
                                              if element.tag.endswith('}sheet') }
            rows = []
            row = {}
            value = ''
        
            if sheet in sheets:
            sheetfile = 'xl/worksheets/sheet'+sheets[sheet]+'.xml'
            #print(sheet,sheetfile)
            for event, element in iterparse(z.open(sheetfile)):
                # get value or index to shared strings
                if element.tag.endswith('}v') or element.tag.endswith('}t'):
                    value = element.text
                # If value is a shared string, use value as an index
                if element.tag.endswith('}c'):
                    if element.attrib.get('t') == 's':
                        value = strings[int(value)]
                    # split the row/col information so that the row leter(s) can be separate
                    letter = re.sub('\d','',element.attrib['r'])
                    row[letter] = value
                    value = ''
                if element.tag.endswith('}row'):
                    rows.append(row)
                    row = {}
        
            return rows
        

        【讨论】:

        • 感谢您回复我的答案!
        • 第二个函数有一个错误:它创建了“sheetdict”字典,但后来尝试读取“sheets”字典。另外,在“if sheet in sheet:”之后添加一个标签:
        【解决方案8】:

        如果您需要旧的 XLS 格式。下面是 ansii 'cp1251' 的代码。

        import xlrd
        
        file=u'C:/Landau/task/6200.xlsx'
        
        try:
            book = xlrd.open_workbook(file,encoding_override="cp1251")  
        except:
            book = xlrd.open_workbook(file)
        print("The number of worksheets is {0}".format(book.nsheets))
        print("Worksheet name(s): {0}".format(book.sheet_names()))
        sh = book.sheet_by_index(0)
        print("{0} {1} {2}".format(sh.name, sh.nrows, sh.ncols))
        print("Cell D30 is {0}".format(sh.cell_value(rowx=29, colx=3)))
        for rx in range(sh.nrows):
           print(sh.row(rx))
        

        【讨论】:

          【解决方案9】:

          您可以选择其中任何一个http://www.python-excel.org/
          我会推荐 python xlrd 库。

          使用安装它

          pip install xlrd
          

          使用导入

          import xlrd
          

          打开工作簿

          workbook = xlrd.open_workbook('your_file_name.xlsx')
          

          按名称打开工作表

          worksheet = workbook.sheet_by_name('Name of the Sheet')
          

          按索引打开工作表

          worksheet = workbook.sheet_by_index(0)
          

          读取单元格值

          worksheet.cell(0, 0).value    
          

          【讨论】:

          • “读取单元格值”不起作用...它引发 TypeError:'Sheet' 对象不可调用。其余的一切都很好。
          【解决方案10】:

          Python Excelerator 也处理此任务。 http://ghantoos.org/2007/10/25/python-pyexcelerator-small-howto/

          它在 Debian 和 Ubuntu 中也可用:

           sudo apt-get install python-excelerator
          

          【讨论】:

            【解决方案11】:

            对于较旧的 Excel 文件,OleFileIO_PL module 可以读取使用的 OLE 结构化存储格式。

            【讨论】:

              【解决方案12】:

              您也可以考虑运行(非 python)程序 xls2csv。给它一个 xls 文件,你应该得到一个 csv。

              【讨论】:

              • 但是发帖人说他需要读 Python... 你是建议运行 xls2csv,然后从 Python 中解析 csv
              • Python-excelerator 包含一个围绕 python 转换器的可执行 py_xls2csv 包装器。
              【解决方案13】:

              您可以使用任何库 listed here(如基于 JExcelApi 的 Pyxlreaderxlwt)以及 COM automation to use Excel itself 来读取文件,但为此您将 Office 作为您的软件的依赖性,这可能并不总是一种选择。

              【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2016-02-01
              • 1970-01-01
              • 1970-01-01
              • 2021-08-12
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多