Python怎么读取Excel指定Sheet、行或列数据

Ruby
Ruby
发布时间:2026-11-05 | 9人浏览过
原创

详细讲解在Python中使用pandas与openpyxl读取Excel指定工作表(Sheet)、指定行和指定列数据的实用方法、参数技巧与避坑指南。

在Python中读取Excel指定Sheet、行或列数据,最通用高效的方案是使用 pandas 库(底层配合 openpyxl 解析引擎);如果项目追求轻量依赖或需要保留单元格格式与原始公式,也可以直接使用原生 openpyxl。在 pandas.read_excel() 函数中,通过 sheet_name 参数可直接锁定目标工作表,搭配 usecols 能按列字母或列名精准过滤列,结合 skiprows 与 nrows 或加载后的 iloc 则能自由截取目标行。本文将以清晰的步骤、对照示例和常见避坑点,完整讲解这两种方案在指定抽取数据时的具体操作方式。
Python怎么读取Excel指定Sheet、行或列数据
图 0:Excel 多维数据定位提取架构示意(工作表、行切片与列筛选)

一、准备工作与环境依赖

处理 .xlsx 格式的 Excel 表格前,需要准备对应的 Python 运行环境。建议在终端或命令行中安装 pandas 与 openpyxl:

终端命令行Bash
pip install pandas openpyxl

为了使后文的所有示例统一且易于对照验证,我们假设当前目录下存在一个名为 sales_data.xlsx 的工作簿,其内容包含多个工作表,其中名为 "2026年销售明细" 的表格结构如下所示:

物理行号 A列 (订单编号) B列 (客户名称) C列 (商品品类) D列 (销售数量) E列 (成交金额)
第 1 行 (表头) 订单编号 客户名称 商品品类 销售数量 成交金额
第 2 行 ORD-2026-001 华东科技 显示器 15 19500.00
第 3 行 ORD-2026-002 北方数码 机械键盘 40 11960.00
第 4 行 ORD-2026-003 南方通信 固态硬盘 80 38400.00
第 5 行 ORD-2026-004 西南实业 人体工学椅 10 12800.00
Python怎么读取Excel指定Sheet、行或列数据
图 1:读取 Excel 目标数据的三步标准化操作流程

二、读取指定 Sheet (工作表)

一个 Excel 工作簿往往包含多个 Sheet。pandas.read_excel() 默认只会读取第 1 个工作表(索引为 0)。若要读取指定 Sheet,只需配置 sheet_name 参数。

1. 按工作表名称读取

直接将目标工作表的名称字符串传递给 sheet_name:

Python 代码按名称读取指定Sheet
import pandas as pd

file_name = "sales_data.xlsx"

# 通过完整名称读取指定工作表
df_target = pd.read_excel(file_name, sheet_name="2026年销售明细")
print(df_target.head(2))
示例运行输出
订单编号 客户名称 商品品类 销售数量 成交金额
0 ORD-2026-001 华东科技 显示器 15 19500.0
1 ORD-2026-002 北方数码 机械键盘 40 11960.0

2. 按工作表数字索引读取

如果不确定 Sheet 确切名称,或者名称可能会动态变动,可以传入从 0 开始的整数索引。例如 0 代表第 1 个工作表,1 代表第 2 个工作表:

Python 代码按索引读取指定Sheet
# 读取工作簿中的第 2 个工作表
df_second = pd.read_excel(file_name, sheet_name=1)

3. 一次读取多个或全部 Sheet

如果需要同时处理工作簿中的多张表,可以传入名称/索引列表,或者传入 sheet_name=None:

Python 代码批量读取多个工作表
# 传入列表:返回字典,键为 Sheet 名称,值为对应 DataFrame
multi_sheets = pd.read_excel(file_name, sheet_name=["2026年销售明细", 1])

# 传入 None:返回包含该工作簿所有工作表的有序字典
all_sheets = pd.read_excel(file_name, sheet_name=None)
for sheet, df in all_sheets.items():
    print(f"工作表 [{sheet}] 共有 {len(df)} 行数据")

三、读取指定 行 (Rows) 数据

读取指定行有两种常用思路:一种是在加载阶段直接限制(适用于大文件,避免无谓内存消耗),另一种是在读入内存后利用 DataFrame 切片(适用于灵活查找)。

1. 加载阶段通过参数限制行:skiprows 与 nrows

许多业务报表前几行是标题、填表说明或制表人信息,真正的数据行从第 3 行或第 4 行才开始。此时可以通过 skiprows 跳过无效行,再用 nrows 限制读取行数:

Python 代码利用 skiprows 与 nrows 读取指定范围行
# 跳过前 2 行(例如前两行为合并标题和批注),随后只读取接下来的 10 行数据
df_rows = pd.read_excel(
    file_name,
    sheet_name="2026年销售明细",
    skiprows=2,
    nrows=10
)

2. 读入内存后通过 iloc 进行纯数字行切片

当工作表已读入 DataFrame 后,使用 .iloc 可以像 Python 列表一样按行下标连续截取:

Python 代码利用 iloc 截取指定行
df = pd.read_excel(file_name, sheet_name="2026年销售明细")

# 截取第 1 行至第 3 行(不包含第 4 行,左闭右开)
sub_rows = df.iloc[0:3]

# 截取指定的离散单行(例如第 1 行与第 3 行)
specific_rows = df.iloc[[0, 2]]
print(specific_rows[["订单编号", "客户名称"]])
示例运行输出
订单编号 客户名称
0 ORD-2026-001 华东科技
2 ORD-2026-003 南方通信
Python怎么读取Excel指定Sheet、行或列数据
图 2:Excel 物理表格坐标与 Python 内存切片坐标映射关系

四、读取指定 列 (Columns) 数据

在面对几十列的复杂报表时,全量加载不仅占用显存/内存,还会降低执行速度。通过 usecols 参数可以在读取时直接滤除非目标列。

1. 按 Excel 列字母范围读取 (推荐直观写法)

usecols 允许直接传递类似 Excel 坐标的列字母区间字符串,例如 "A:C" 或 "A, C:E":

Python 代码按列字母范围过滤
# 仅读取 A 列、以及 C 列到 E 列,排除 B 列
df_cols_letter = pd.read_excel(
    file_name,
    sheet_name="2026年销售明细",
    usecols="A, C:E"
)
print(df_cols_letter.columns.tolist())
示例运行输出
['订单编号', '商品品类', '销售数量', '成交金额']

2. 按列名称列表读取 (推荐业务代码写法)

如果报表的列顺序容易变动,但列名相对固定,直接传入表头名称列表是最健壮的写法:

Python 代码按列名列表过滤
# 仅载入业务关心的两列
df_cols_named = pd.read_excel(
    file_name,
    sheet_name="2026年销售明细",
    usecols=["客户名称", "成交金额"]
)

3. 按列位置索引读取 (从 0 开始计数)

也可以传入列的下标列表。例如提取第 1 列(索引 0)与第 5 列(索引 4):

Python 代码按数字索引过滤列
df_cols_indexed = pd.read_excel(
    file_name,
    sheet_name="2026年销售明细",
    usecols=[0, 4]
)

五、综合实战:同时指定 Sheet、行范围与指定列

在实际工程中,最常见的场景是:在指定工作表中,只截取某一段行,并且只保留关键列。通过组合参数可以一行代码精准定位:

Python 代码综合提取特定区域数据
import pandas as pd

# 目标:从工作表 "2026年销售明细" 中,只取第 2~4 行(前3笔数据),且只要“客户名称”与“成交金额”两列
target_data = pd.read_excel(
    "sales_data.xlsx",
    sheet_name="2026年销售明细",
    usecols=["客户名称", "成交金额"],
    nrows=3
)

print(target_data)
示例运行输出
客户名称 成交金额
0 华东科技 19500.00
1 北方数码 11960.00
2 南方通信 38400.00

六、原生轻量方案:使用 openpyxl 定位读取

如果所在运行环境对体积有严格限制(例如 AWS Lambda / 轻量 Docker 容器中不希望引入庞大的 pandas 与 numpy),直接使用 openpyxl 是官方推荐的轻量读写方案。

Python 代码openpyxl 读取指定Sheet与行列区间
from openpyxl import load_workbook

# 加载工作簿 (data_only=True 表示读取公式计算结果而非公式原文)
wb = load_workbook("sales_data.xlsx", data_only=True)

# 1. 指定 Sheet:通过键值访问
ws = wb["2026年销售明细"]

# 2. 读取指定行列区域:例如第2行到第4行,第2列到第5列 (B2:E4)
# 注意:openpyxl 的行号和列号均从 1 开始计数
rows_data = []
for row in ws.iter_rows(min_row=2, max_row=4, min_col=2, max_col=5, values_only=True):
    rows_data.append(row)

for r in rows_data:
    print(r)
示例运行输出
('华东科技', '显示器', 15, 19500.0)
('北方数码', '机械键盘', 40, 11960.0)
('南方通信', '固态硬盘', 80, 38400.0)
Python怎么读取Excel指定Sheet、行或列数据
图 3:pandas 与 openpyxl 在读取指定数据时的机制与选型对比

七、两种方案的关键机制差异与选型依据

理解 pandas 与 openpyxl 的底层差异,能够帮助我们在面对不同业务场景时做出合理选择:

  • 索引基数的根本区别: pandas 的切片与行号基于计算机常规的 0-based(从 0 开始),而且默认把物理第 1 行作为 DataFrame 的列名;而 openpyxl 忠实于 Excel 的物理标号体系,是 1-based(从 1 开始),min_row=1 对应的就是 Excel 界面上行号为 1 的单元格。混用两者时切忌直接代入相同数值。
  • 内存解析模型的差异: pandas 在执行 read_excel 时将整块数据解析并转换为连续内存的 C 数组/NumPy 结构,运算处理速度极快;而 openpyxl 将单元格包装成 Python 原生 Cell 对象,元数据丰富,但在十万行级别以上全量遍历时对象创建开销较高。
  • 选型结论: 凡是后续涉及数据统计、关联合并、清洗或导出的分析任务,优先使用 pandas;凡是轻量化脚本、微服务、只需抽取单点单元格或必须保留单元格样式与批注的场景,使用 openpyxl。
Python怎么读取Excel指定Sheet、行或列数据
图 4:技术全景总结与高频避坑决策图

八、常见问题与实用避坑指南

⚠️ 1. Sheet 名称存在隐藏尾部空格导致找不到工作表

日常业务中,人工导出的 Excel 工作表名称末尾经常带有一个看不见的半角空格(例如 "Sheet1 ")。直接传入 sheet_name="Sheet1" 会抛出 ValueError: Worksheet named 'Sheet1' not found。排查时建议先用代码打印所有工作表名:

# 查看工作簿内所有真实存在的 Sheet 完整名称
excel_file = pd.ExcelFile("sales_data.xlsx")
print(excel_file.sheet_names)
⚠️ 2. 表头 header 参数导致的行数偏移

pd.read_excel() 默认设置 header=0,即把 Excel 物理第 1 行提取作为列标题,实际数据从物理第 2 行开始算作第 0 行。如果你的 Excel 文件没有表头,第 1 行就是纯数据,务必显式声明 header=None,否则第 1 行数据会被吞掉变成列名:

# 表格无表头时的安全读取写法
df_no_header = pd.read_excel("sales_data.xlsx", sheet_name=0, header=None)
⚠️ 3. openpyxl 读取带公式单元格得到 None 或公式字符串

如果单元格内是 =SUM(E2:E10) 这样的计算公式,openpyxl 默认加载时会读出字符串 "=SUM(E2:E10)"。若需要取得 Excel 保存时的实际数值结果,必须在打开工作簿时传递 data_only=True:

wb = load_workbook("sales_data.xlsx", data_only=True)

注意:如果该 Excel 文件是由第三方程序生成且从未在 Excel 软件中打开保存过,公式缓存值可能为空,此时读取结果可能为 None。

⚠️ 4. 连续空行与多余空列的过滤

有时 Excel 底部或右侧残留有格式的空白单元格,导致读入的 DataFrame 尾部出现大量 NaN。可以在加载后立即调用 dropna 快速清理:

# 丢弃完全为空的行和列
df_clean = df.dropna(how="all", axis=0).dropna(how="all", axis=1)

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表