
本文介绍如何利用 go 语言的 `tealeg/xlsx` 库遍历 excel 工作表,动态识别并返回最后一个含有非空单元格的行索引(即“最后填充行”),适用于数据导入、自动化处理等场景。
在使用 Go 处理 Excel 文件时,常需定位有效数据的边界——尤其是最后一行实际有内容的行(last filled row)。tealeg/xlsx 是一个成熟稳定的纯 Go 实现 Excel(.xlsx)读写库,虽不提供内置的 GetLastRow() 方法,但可通过遍历逻辑高效实现该功能。
核心思路是:逐行扫描每个工作表(Sheet)的所有行与单元格,只要某一行中存在至少一个非空单元格,就更新当前最大行索引。注意:range sheet.Rows 返回的索引 r 是从 0 开始的(对应 Excel 中第 1 行),因此最终结果需 +1 才为用户习惯的“行号”。以下是完整、健壮的示例代码:
package main
import (
"fmt"
"log"
"github.com/tealeg/xlsx"
)
func getLastFilledRow(xlFile *xlsx.File) map[string]int {
lastRows := make(map[string]int)
for _, sheet := range xlFile.Sheets {
rmax := -1 // 初始化为 -1,便于区分全空表
for r, row := range sheet.Rows {
hasContent := false
for _, cell := range row.Cells {
if cell != nil && cell.String() != "" {
hasContent = true
break // 当前行已确认非空,无需检查其余单元格
}
}
if hasContent {
rmax = r
}
}
// rmax 为 0-based 索引;若需 Excel 行号(1-based),则 rmax + 1
lastRows[sheet.Name] = rmax + 1
}
return lastRows
}
func main() {
xlFile, err := xlsx.OpenFile("data.xlsx")
if err != nil {
log.Fatal(err)
}
defer xlFile.Close()
lastRows := getLastFilledRow(xlFile)
for sheetName, rowNum := range lastRows {
fmt.Printf("Sheet '%s': last filled row = %d\n", sheetName, rowNum)
}
}✅ 关键注意事项:
- row.Cells 可能包含 nil 单元格(尤其跨列稀疏数据),务必先判空再调用 .String(),避免 panic;
- 若整张表为空,rmax 保持 -1,返回 0(即 rmax + 1),可据此做空表校验;
- 此方法按物理行顺序扫描,保证准确性,不受 Excel “已使用区域”(UsedRange)API 误判影响;
- 性能友好:每行一旦发现非空单元格即短路跳出内层循环,避免冗余遍历。
总结:通过合理利用 range 的索引和 cell.String() 的内容判断,即可在 tealeg/xlsx 中稳定、高效地获取最后一行有效数据的位置。该方案简洁、可移植,是 Excel 数据预处理的基础能力之一。










