Python读取Excel指定Sheet、行或列的方法
详细讲解使用Python精准读取Excel文件中指定工作表(Sheet)、特定行以及特定列的实用方法。涵盖Pandas与Openpyxl两种主流方案的核心参数、切片机制、坐标体系差异及避坑指南。
在日常数据处理与办公自动化任务中,Excel 文件往往体量庞大且结构复杂,直接全量加载不仅消耗大量内存,还会降低程序执行效率。在 Python 生态中,读取 Excel 指定工作表(Sheet)、特定行或特定列最成熟的解决方案主要有两个:一个是面向数据分析的高阶库 Pandas,另一个是面向单元格底层操作的专用库 Openpyxl。本文将系统讲解这两种工具的具体操作步骤、核心参数配置、坐标索引差异以及大文件读取时的优化策略。
一、环境准备与依赖安装
在开始编写代码前,需要确保运行环境中已安装相关依赖。Pandas 在底层处理现代 .xlsx 格式文件时默认依赖 openpyxl 引擎,因此推荐同时安装这两个库:
pip install pandas openpyxl
安装完成后,建议准备一个具有多个工作表及多种字段的测试文件 data.xlsx,便于对照输出验证切片结果。
二、使用 Pandas 精准读取指定 Sheet、行或列
Pandas 的 pd.read_excel() 函数封装了非常强大的按需加载参数。它能够在将文件读入内存的阶段,直接过滤掉无关的工作表、行或列,极大提高程序性能。
1. 读取指定 Sheet(工作表)
通过参数 sheet_name 可以指定要加载的一个或多个工作表:
- 按工作表名称:传入字符串,例如
sheet_name="销售明细"。 - 按索引顺序:传入从 0 开始的整数,例如
sheet_name=0读取第一个工作表,sheet_name=1读取第二个工作表。 - 同时读取多个 Sheet:传入列表,例如
sheet_name=["Sheet1", "Sheet2"]或sheet_name=[0, 1],返回值为一个字典,键为工作表名称或序号,值为对应的 DataFrame。 - 读取全部 Sheet:设置
sheet_name=None,返回包含所有工作表的字典。
2. 读取指定列
通过参数 usecols 可以精准锁定需要的列,避免加载整张表格的无关数据:
- 使用 Excel 列字母:支持单列与区间语法,例如
usecols="A,C,E"或usecols="A:C,E"。 - 使用整数列索引:传入列表,例如
usecols=[0, 2, 4](从 0 开始计数)。 - 使用列名列表:传入包含目标表头名称的列表,例如
usecols=["姓名", "薪资"]。 - 使用函数过滤:传入可调用对象(Callable),例如
usecols=lambda col: "金额" in str(col)。
3. 读取指定行
控制行范围通常结合 skiprows、nrows 以及加载后的切片索引实现:
- 跳过顶部无用行:使用
skiprows=N跳过文件前 N 行(常用于跳过非结构化说明、大标题)。如果需要跳过指定行号,可传入列表如skiprows=[0, 2, 5]。 - 限制读取总行数:使用
nrows=M只读取表头下方的前 M 行有效数据,适合在大文件快速预览或小批量测试。 - 加载后切片:读入后使用
df.iloc[start:end]进行行切片。例如df.iloc[10:20]获取第 11 行至第 20 行数据。
4. 完整 Pandas 切片读取示例
以下代码展示如何组合运用上述参数,从名为 data.xlsx 的表格中,指定读取名为 员工名册 的 Sheet,跳过第 1 行标题,仅获取 姓名、职级、基本薪资 三列,且只提取前 5 条记录:
import pandas as pd
file_path = "data.xlsx"
# 组合读取:指定Sheet、指定列字母、跳过前1行、仅读5行
df = pd.read_excel(
file_path,
sheet_name="员工名册",
skiprows=1, # 跳过第1行说明
nrows=5, # 仅获取5条数据行
usecols="A,C,D" # 仅加载 A、C、D 列
)
print("--- Pandas 读取结果 ---")
print(df)
print("\n数据维度 (行, 列):", df.shape)
示例输出:
--- Pandas 读取结果 ---
员工姓名 当前职级 基本薪资
0 张伟 P6 18500
1 李娜 P5 14000
2 王强 P7 23000
3 刘敏 P5 15000
4 陈杰 P6 19000
数据维度 (行, 列): (5, 3)
三、使用 Openpyxl 逐层定位 Sheet、行与列
当任务不仅是读取数值,还需要保留单元格样式、公式、合并单元格信息,或者面对几百兆的超大 Excel 文件时,openpyxl 是更合适的选择。它以工作簿(Workbook)、工作表(Worksheet)、单元格(Cell)为层级,提供了细粒度的坐标访问能力。
1. 加载工作簿与定位 Sheet
from openpyxl import load_workbook
# 加载工作簿;若只需读取数据,务必设置 data_only=True 以获取公式计算后的值
wb = load_workbook("data.xlsx", data_only=True)
# 方式一:按名称定位 Sheet
ws = wb["员工名册"]
# 方式二:按索引序号定位(0代表第一个工作表)
ws = wb.worksheets[0]
# 获取当前工作簿中所有的 Sheet 名称列表
all_sheets = wb.sheetnames
print("所有工作表:", all_sheets)
2. 定位与读取指定行
Openpyxl 提供了多种按行提取的方式:
- 读取单行:使用数字索引
ws[3]获取第 3 行的所有单元格元组。 - 遍历行范围(iter_rows):使用
ws.iter_rows(min_row=2, max_row=6, values_only=True),直接获取第 2 行至第 6 行的单元格纯数值。
3. 定位与读取指定列
针对列的提取同样直观:
- 读取单列:使用列字母
ws['B']获取 B 列的所有单元格元组;若提取列中前几行,可使用切片ws['B1:B10']。 - 遍历列范围(iter_cols):使用
ws.iter_cols(min_col=1, max_col=3, min_row=2, max_row=6, values_only=True),按列迭代获取特定范围的值。
4. 完整 Openpyxl 坐标定位示例
from openpyxl import load_workbook
wb = load_workbook("data.xlsx", data_only=True)
ws = wb["员工名册"]
# 需求:获取第 2 行到第 5 行中,A列(第1列)与 D列(第4列)的数据
extracted_data = []
for row_idx in range(2, 6):
name = ws.cell(row=row_idx, column=1).value # A列为column 1
salary = ws.cell(row=row_idx, column=4).value # D列为column 4
extracted_data.append({"姓名": name, "薪资": salary})
print("--- Openpyxl 提取结果 ---")
for item in extracted_data:
print(item)
示例输出:
--- Openpyxl 提取结果 ---
{'姓名': '张伟', '薪资': 18500}
{'姓名': '李娜', '薪资': 14000}
{'姓名': '王强', '薪资': 23000}
{'姓名': '刘敏', '薪资': 15000}
四、核心机制差异与注意事项
在实际编码中,很多错误源于对底层索引与表头处理逻辑的混淆。理解以下关键差异有助于写出稳健的代码:
1. 坐标体系的根本差异(0-Based vs 1-Based)
这是初学者最容易踩坑的地方:
- Pandas:采用程序员熟悉的 0 基数索引。第一列对应
0,读入 DataFrame 后的第一行索引也是0。切片遵循 Python 原生规则(前闭后开,[0:3]仅包含 0、1、2)。 - Openpyxl:采用与 Excel 界面严格一致的 1 基数坐标。第一行是
row=1,第一列是column=1(即 A 列)。iter_rows(min_row=1, max_row=3)是全闭区间,会真实输出第 1、2、3 行。
2. 表头(Header)识别机制
pd.read_excel 默认将有效数据的第一行(header=0)识别为列名,不会将其计入数据行。如果你的表格本身没有表头,或者前几行是说明文本,务必显式指定:
- 没有表头:设置
header=None,此时列名会自动变为 0, 1, 2...,避免第一行真实数据被当成列名吞噬。 - 表头位于第 3 行:配合
header=2(0基数),Pandas 会自动跳过前两行并将第 3 行设为列名。
3. 超大文件流式读取(Read-Only 模式)
当 Excel 文件达到几十兆或上百兆时,Pandas 或常规 Openpyxl 会将全部 XML 树解析进内存,容易导致内存溢出(OOM)。针对这种情况,建议使用 Openpyxl 的只读流式模式:
from openpyxl import load_workbook
# 开启 read_only 模式,按需流式读取,内存占用极低且恒定
wb = load_workbook("huge_data.xlsx", read_only=True)
ws = wb["数据记录"]
# 流式迭代读取指定的 1000 到 2000 行
for row in ws.iter_rows(min_row=1000, max_row=2000, values_only=True):
col_a_val = row[0] # 第一列值
col_d_val = row[3] # 第四列值
# 执行业务逻辑...
wb.close() # 只读模式完成后建议显式关闭
五、常见问题与排查方法
Q1: 报 KeyError: "Worksheet xxx does not exist" 怎么处理?
原因通常是工作表名称存在首尾多余空格、大小写不匹配或特殊不可见字符。排查方法:先通过 pd.ExcelFile(path).sheet_names 或 openpyxl.load_workbook(path).sheetnames 打印出文件中所有 Sheet 的确切字符串列表,确认名称无误后再进行读取。
Q2: 为什么读取出来的公式单元格全是 None?
使用 openpyxl 设定 data_only=True 时,返回的是 Excel 上一次保存时计算缓存的值。如果该 Excel 文件是由某些第三方程序直接生成但未曾用 Excel 软件打开保存过,公式缓存值可能为空。解决办法是在 Excel 中打开并按保存,或使用无 data_only 模式读取公式字面量。
Q3: 读取特定列时,出现大量空行(NaN / None)?
Excel 工作表中曾被赋予格式(如底色、边框)的空白单元格会被识别为有效数据范围。在 Pandas 中可以使用 df.dropna(how='all') 快速剔除全空行;在 Openpyxl 中,可以在迭代行时加入 if any(cell is not None for cell in row): 进行有效性校验。
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









