easyexcel 是阿里巴巴开源的一个简单、省内存的 Excel 读写库,特别适合处理大数据量的 Excel 文件,因为它不会一次性将整个文件加载到内存中。

获取行数主要有两种场景:
- 读取 Excel 文件时:获取某个工作表的行数。
- 写入 Excel 文件时:获取你已经写入数据的行数。
读取 Excel 文件时获取行数
这是最常见的需求。easyexcel 的读取方式是基于 监听器(Listener) 的,你需要创建一个监听器类来处理每一行的数据。
核心思路
easyexcel 在读取时会逐行调用你监听器中的 invoke 方法,你只需要在你的监听器里设置一个计数器,每处理一行数据,计数器就加一,读取完成后,这个计数器的值就是总行数。
示例代码
假设我们有一个名为 user_info.xlsx 的文件,内容如下:

| 姓名 | 年龄 |
|---|---|
| 张三 | 25 |
| 李四 | 30 |
| 王五 | 28 |
我们想要获取这个文件的行数。
步骤 1:创建一个监听器类
from easyexcel import read_excel
from typing import List
class RowCountListener:
def __init__(self):
# 初始化一个计数器
self.row_count = 0
def invoke(self, data: List[dict], context):
"""
easyexcel 每读取一行数据,就会调用这个方法一次。
:param data: 当前行数据,是一个字典列表
:param context: 读取上下文
"""
# 每调用一次,行数加 1
self.row_count += 1
# (可选) 你可以在这里打印每一行的数据,方便调试
# print(f"读取到第 {self.row_count} 行: {data}")
def doAfterAllAnalysed(self, context):
"""
所有行都读取完毕后,会调用这个方法。
"""
print("所有数据读取完毕!")
def get_row_count(self) -> int:
"""
获取最终的行数。
"""
return self.row_count
步骤 2:使用监听器读取文件并获取行数
# 1. 创建监听器实例
listener = RowCountListener()
# 2. 读取 Excel 文件
# 注意:这里我们读取的是包含数据的部分,通常会跳过表头。
# easyexcel 默认会把第一行作为表头,然后从第二行开始读取数据。
# 如果你有表头,最终得到的行数是数据行数。
read_excel("user_info.xlsx", read_row listener=listener)
# 3. 从监听器中获取行数
total_rows = listener.get_row_count()
print(f"Excel 文件中的数据总行数为: {total_rows}")
输出结果:

所有数据读取完毕!
Excel 文件中的数据总行数为: 3
重要说明:如何处理表头?
easyexcel 的 read_excel 方法默认会将第一行识别为表头(Header),然后从第二行开始读取数据并调用 invoke 方法。
- 如果你的文件有表头:
row_count的值就是 数据行数(不包括表头),这在绝大多数情况下是符合预期的。 - 如果你的文件没有表头:你可以设置
header=False,这样easyexcel就不会跳过任何一行,row_count会包含所有行。
# 读取没有表头的文件,计算所有行数
read_excel("no_header.xlsx", read_row listener=listener, header=False)
写入 Excel 文件时获取行数
在写入场景下,情况更简单,因为你已经知道你写了多少数据。easyexcel 提供了 ExcelWriter 对象,它有一个 rows 属性可以告诉你当前已经写入了多少行。
示例代码
from easyexcel import ExcelWriter
from typing import List
# 准备要写入的数据
data_to_write = [
{"姓名": "赵六", "年龄": 22},
{"姓名": "钱七", "年龄": 35},
{"姓名": "孙八", "年龄": 29},
{"姓名": "周九", "年龄": 40}
]
# 1. 创建一个 ExcelWriter 对象
# 使用 'with' 语句可以确保文件被正确关闭
with ExcelWriter("output.xlsx") as writer:
# 2. 写入数据
# write_excel 会返回一个整数,表示成功写入的行数
# 这里的行数同样不包括表头
rows_written = writer.write_excel(data_to_write, sheet_name="员工信息")
# 3. 获取并打印写入的行数
print(f"成功写入 {rows_written} 行数据到 '员工信息' 工作表。")
# 你也可以直接访问 writer.rows 属性
print(f"通过 writer.rows 属性获取的行数: {writer.rows}")
# 读取文件验证一下
listener = RowCountListener()
read_excel("output.xlsx", read_row listener=listener)
print(f"读取验证得到的行数: {listener.get_row_count()}")
输出结果:
成功写入 4 行数据到 '员工信息' 工作表。
通过 writer.rows 属性获取的行数: 4
读取验证得到的行数: 4
总结与对比
| 场景 | 方法 | 代码示例 | 说明 |
|---|---|---|---|
| 读取文件 | 使用监听器计数 | class MyListener:<br> def __init__(self):<br> self.row_count = 0<br> def invoke(self, data, context):<br> self.row_count += 1 |
easyexcel 的核心读取方式,适用于大文件,内存占用低。row_count 默认为数据行数(不含表头)。 |
| 写入文件 | 使用 ExcelWriter.rows |
with ExcelWriter(...) as writer:<br> rows = writer.write_excel(data) |
最直接的方法。rows 属性或 write_excel 的返回值都直接告诉你写了多少行数据(不含表头)。 |
最佳实践建议
- 对于读取:始终使用监听器模式,这是
easyexcel设计的核心思想,也是它能处理大文件的秘诀,不要尝试将整个 Excel 读入一个列表或 Pandas DataFrame 再去获取行数,那样会失去easyexcel的内存优势。 - 对于写入:直接使用
writer.rows或write_excel的返回值,这是最简单、最准确的方式。 - 注意表头:时刻记得
easyexcel默认会处理表头,因此读取和写入的“行数”通常指的是 数据行数,如果需要包含表头,请手动在计算结果上加 1。
