Python读取Excel详细步骤

文章导读
多数人搜「Python读取Excel」,真正卡住的往往不是不会写 pd.read_excel(),而是不知道自己停在哪一步:是引擎没装、工作表选错、表头行不对,还是文件本身大到读一次要等很久。要能判断,得先能核对:拿到 sheet_names、shape、columns、dtypes 这四个可见输出,再决定继续往下做还是回头修参数。
📋 目录
  1. Ⅰ Python读取Excel表格数据
  2. Ⅱ Python读取Excel文件太慢
  3. Ⅲ 读取Excel:先把能核对的事实摆清楚
  4. Ⅳ 读取Excel最容易搞错的一点
  5. Ⅴ 读取Excel:一个照着就能做完的做法
A A

多数人搜「Python读取Excel」,真正卡住的往往不是不会写 pd.read_excel(),而是不知道自己停在哪一步:是引擎没装、工作表选错、表头行不对,还是文件本身大到读一次要等很久。要能判断,得先能核对:拿到 sheet_names、shape、columns、dtypes 这四个可见输出,再决定继续往下做还是回头修参数。

读取Excel的最小可核对路径是:先确认 pandas 与对应引擎装好,用 pd.ExcelFile 列出工作表名,再按 sheet_name、header、usecols 明确读入,最后用 shape、columns、dtypes 三项输出比对 Excel 里看到的内容。适用场景是常规 .xlsx/.xls 表格;合并单元格、多级表头、超宽表需要单独处理;文件格式与引擎不匹配时会直接报错,不是数据问题。

Python读取Excel表格数据

「Python读取Excel表格数据」对应读取链路里的第二步:定位到具体工作表,并把表头行和数据区域切分正确,最终得到一个列名可读的 DataFrame。它前面是环境准备(pandas + 引擎),后面是清洗和分析。判断是不是卡在这一步,看三个位置:pd.ExcelFile(...).sheet_names 是否列出了你预期的表名;df.columns.tolist() 里是否出现 Unnamed: 0 这类占位列名;df.shape 的行数是否与 Excel 状态栏里选中数据区的行计数对得上。

直接把下面这段存成 probe.py 跑一遍,输出就是你要核对的事实:

import pandas as pd

book = pd.ExcelFile("订单.xlsx", engine="openpyxl")
print("工作表:", book.sheet_names)

df = book.parse("Sheet1", header=0, dtype=str)
print("shape:", df.shape)
print("columns:", df.columns.tolist())
print(df.head(5).to_string())

如果 columns 里出现 Unnamed,或 shape 的行数比 Excel 里少一行,通常说明表头上方还有一行标题、或者 header 填错了行号,而不是数据丢了。

Python读取Excel文件太慢

「Python读取Excel文件太慢」对应的不是同一个环节,它落在读取链路的第一步到第二步之间:打开文件、解析 XML、构建 DataFrame 这三段各自耗时多少。判断是不是它,不要凭感觉,用 time.perf_counter() 把打开和解析分开计时,同时看一眼文件体积(ls -lh 订单.xlsx)。如果文件只有几 MB 却要几十秒,通常是表里有大量格式、图片、合并单元格,或者用了 read_only 之外的默认加载方式。

import time, pandas as pd

t0 = time.perf_counter()
book = pd.ExcelFile("大表.xlsx", engine="openpyxl")
t1 = time.perf_counter()
df = book.parse(book.sheet_names[0], usecols="A:M")
t2 = time.perf_counter()

print(book.sheet_names)
print("打开耗时", round(t1 - t0, 2), "解析耗时", round(t2 - t1, 2), "行数", len(df))

能做的收敛动作是有限的:用 pd.ExcelFile 只打开一次再多次 parse 复用;用 usecols 限定列范围;用 nrows 先抽样确认识别无误再全量读。如果同一份数据要反复读,建议先转成 CSV 或 Parquet 存一次,后续都读转换后的文件——这属于绕开解析开销,不是把 Excel 读取本身变快。

读取Excel:先把能核对的事实摆清楚

先不急着改代码,把下面几项逐条打出来,写在同一个脚本里一起跑:

Python读取Excel详细步骤
  • 对象:文件绝对路径、文件大小、扩展名是 .xlsx 还是 .xls、工作表名列表。
  • 环境:python -c "import pandas, openpyxl; print(pandas.__version__, openpyxl.__version__)",以及 pip show openpyxl 里的 Location 行,确认装在了当前解释器里。
  • 结构:df.shape、df.columns.tolist()、df.dtypes、df.isna().sum()。
  • 对照:在 Excel 里选中数据区,看状态栏的计数,与 len(df) 加表头行比对。

这些输出都不带解释,但能直接决定方向:列名是 Unnamed 就去修 header;行数不一致就去查空行和合并单元格;dtypes 全是 object 就去查数字列里混入的文本或空格。这一步先不下结论,是因为很多“读不出来”最后发现是文件格式与引擎不匹配,改参数也无效。

读取Excel最容易搞错的一点

最常见的误解是把“代码没报错”当成“数据读对了”。read_excel 顺利返回一个 DataFrame,只能说明文件能被解析,不能说明表头行、合并单元格、空行已经被正确切分。分界线很明确:columns 是正常字段名,且 len(df) 与 Excel 里实际数据行数一致,才算读对;只要出现 Unnamed 或行数差一,就属于没读对。

一个能区分两种情况的检查动作:对同一个文件分别用 header=0 和 header=None 各读一次,打印 df.head(3)。如果 header=None 时第一行内容才是真正的字段名,说明表头上方还有标题行,应改为 header=1 或直接 skiprows。另一个高频误解是拿 openpyxl 去读 .xls——引擎和格式要对应,.xlsx 用 openpyxl,老式 .xls 需要另装对应引擎,不匹配时会直接抛 Excel file format cannot be determined 或 Missing optional dependency。

读取Excel:一个照着就能做完的做法

下面这条路径从建环境到校验,每步都写了应该看到什么。

  1. 建独立环境并安装:python -m venv venv,然后 source venv/bin/activate(Windows 为 venv\Scripts\activate),再执行 pip install pandas openpyxl。应看到 Successfully installed,末尾带版本号。
  2. 确认解释器与包对齐:pip show openpyxl 的 Location 应指向当前 venv 目录,而不是系统 site-packages。
  3. 列出工作表:python -c "import pandas as pd; print(pd.ExcelFile('订单.xlsx').sheet_names)"。应看到中括号里的表名列表,而不是报错。
  4. 按表名和范围读入:df = pd.read_excel("订单.xlsx", sheet_name="Sheet1", header=0, usecols="A:M", dtype=str)。选 dtype=str 是为了先避开工号、订单号被识别成数字的问题,清洗阶段再转换。
  5. 三项校验:打印 df.shape、df.columns.tolist()、df.isna().sum()。应看到列名无 Unnamed、行数与 Excel 状态栏计数一致。
  6. 落一份中间文件:df.to_csv("订单.csv", index=False, encoding="utf-8-sig"),后续反复读取都走这个 CSV。应看到当前目录出现 csv 文件,且用 Excel 打开中文不乱码。

执行中可能撞到三种报错,按报错定位即可:FileNotFoundError 是路径问题,换成绝对路径;Missing optional dependency 'openpyxl' 是引擎没装进当前环境;ValueError: Excel file format cannot be determined 是扩展名与实际格式不符,用 file 订单.xlsx 看真实类型。版本号、引擎支持的格式这类会变的信息,以 pip show 的输出和 pandas 安装后 pd.read_excel.__doc__ 里的 engine 说明为准。