135

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

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

4

13 回答 13

104

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

警告

此库将不再读取 .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ý)。

于 2010-05-31T12:24:02.403 回答
56

使用熊猫:

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...
于 2017-05-23T04:04:41.027 回答
32

您可以选择其中任何一个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    
于 2017-04-06T14:15:44.890 回答
22

我认为熊猫是最好的选择。这里已经有一个关于 Pandas 使用ExcelFile函数的答案,但它对我来说不能正常工作。从这里我找到了read_excel可以正常工作的功能:

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

PS您需要xlrd安装才能使read_excel功能正常工作

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

dfs = pd.read_excel("your_file_name.xlsx", sheet_name="your_sheet_name", engine="openpyxl")
于 2018-06-12T10:35:51.410 回答
5

对于 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
于 2018-10-28T11:53:39.720 回答
3

如果您需要旧的 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))
于 2019-11-17T05:15:01.173 回答
2

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

或者你可以xlrd通过导入直接使用。像下面

import xlrd
wb = xlrd.open_workbook(file_name)

或者你也可以使用 pandaspd.read_excel()方法,但不要忘记指定引擎,虽然默认是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.
于 2020-08-12T06:06:33.137 回答
1

您可以使用此处列出的任何库(例如基于 JExcelApi 或xlwt 的 Pyxlreader ,以及使用 Excel 本身读取文件的 COM 自动化,但为此您将 Office 作为软件的依赖项引入,这可能并不总是一种选择。

于 2010-05-31T10:46:03.927 回答
1

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

它也可以在 Debian 和 Ubuntu 中使用:

 sudo apt-get install python-excelerator
于 2015-04-08T22:11:50.583 回答
0

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

于 2012-11-25T21:43:46.930 回答
0

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

于 2013-09-18T20:35:35.847 回答
0

如果文件真的是一个旧的 .xls,这对我在 python3 上只使用 base open() 和 pandas 有效:

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

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

我对 xlrd 的运气并不好,因为——我认为——UTF-8 问题。

于 2020-12-14T21:16:19.180 回答
0
    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。它也非常简单明了你可以看到下面的代码片段希望这会有所帮助

    import openpyxl
    book = openpyxl.load_workbook(filename)
    sheet = book.active 
    result =sheet['AP2']
    print(result.value)
于 2020-06-19T12:26:22.040 回答