如何在.NET Core中通过NPOI获取Excel工作表的已使用区域
NPOI获取Excel工作表已使用区域实现方法
NPOI本身没有直接等同于Interop中UsedRange的原生属性,但可以通过以下两种兼容.NET Core环境的方案实现,完全不需要依赖Office COM组件。
方案1:快速获取物理存在的单元格区域(性能最优)
适合大部分常规场景,直接读取工作表内有物理存储记录的行和列范围,性能很高:
using NPOI.SS.UserModel; public (int firstRow, int lastRow, int firstCol, int lastCol) GetUsedRange(ISheet sheet) { if (sheet.PhysicalNumberOfRows == 0) { return (0, -1, 0, -1); // 无内容空表返回 } int firstRow = sheet.FirstRowNum; int lastRow = sheet.LastRowNum; int firstCol = int.MaxValue; int lastCol = int.MinValue; // 遍历所有有物理记录的行计算列范围 for (int i = firstRow; i <= lastRow; i++) { IRow row = sheet.GetRow(i); if (row == null) continue; firstCol = Math.Min(firstCol, row.FirstCellNum); lastCol = Math.Max(lastCol, row.LastCellNum - 1); // LastCellNum是总列数,减1得到最后一列索引 } // 全表都是空行的情况处理 if (firstCol > lastCol) { return (0, -1, 0, -1); } return (firstRow, lastRow, firstCol, lastCol); }
该方案特点:
- 仅遍历有物理存储的行,大文件场景下性能优秀
- 注意:如果行/单元格曾经被编辑后来仅清空内容、没有彻底删除,也会被计入范围,需要排除这类纯空内容的场景请用方案2
方案2:精准获取实际有内容的区域
适合需要排除空内容单元格(比如编辑后清空的残留记录)的场景,返回结果和Excel中用户可见的已使用范围完全一致:
using NPOI.SS.UserModel; using System.Linq; public (int firstRow, int lastRow, int firstCol, int lastCol) GetActualUsedRange(ISheet sheet) { var validRows = Enumerable.Range(sheet.FirstRowNum, sheet.LastRowNum - sheet.FirstRowNum + 1) .Select(i => new { RowIndex = i, Row = sheet.GetRow(i) }) .Where(r => r.Row != null && r.Row.Cells.Any(c => !string.IsNullOrWhiteSpace(c?.ToString()))) .ToList(); if (!validRows.Any()) { return (0, -1, 0, -1); } int firstRow = validRows.Min(r => r.RowIndex); int lastRow = validRows.Max(r => r.RowIndex); int firstCol = int.MaxValue; int lastCol = int.MinValue; foreach (var rowItem in validRows) { var validCells = rowItem.Row.Cells .Where(c => !string.IsNullOrWhiteSpace(c.ToString())) .ToList(); if (!validCells.Any()) continue; firstCol = Math.Min(firstCol, validCells.Min(c => c.ColumnIndex)); lastCol = Math.Max(lastCol, validCells.Max(c => c.ColumnIndex)); } return (firstRow, lastRow, firstCol, lastCol); }
调用示例
// 读取文件示例 IWorkbook workbook = WorkbookFactory.Create("你的Excel文件路径"); ISheet sheet = workbook.GetSheetAt(0); // 读取第一个工作表 var usedRange = GetUsedRange(sheet); // 高精度场景替换为GetActualUsedRange(sheet) // 转换为用户习惯的从1开始的行列号输出 Console.WriteLine($"已使用区域:第{usedRange.firstRow+1}行到第{usedRange.lastRow+1}行,第{usedRange.firstCol+1}列到第{usedRange.lastCol+1}列");
注意事项
- NPOI的行、列索引默认从0开始,需要展示给用户的话自行+1即可
- 以上代码同时兼容
.xls(HSSF)和.xlsx(XSSF)两种格式,无需单独适配
内容的提问来源于stack exchange,提问作者Xie Steven
相关产品推荐
相关产品推荐

