You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用ExcelDataReader读取XLS文件中Defined Names(命名区域)的值

ExcelDataReader读取Defined Names(命名区域)值的方法

AsDataSet() 转换过程不会保留命名区域相关元数据,命名区域信息直接挂载在IExcelDataReader实例的DefinedNames属性上,结合已加载的DataSet表数据即可读取对应值,具体实现步骤如下:

1. 读取命名区域定义

在执行完AsDataSet()加载全量表数据后,直接遍历reader.DefinedNames集合即可拿到所有命名区域的基础信息:

// 读取XLS格式文件用CreateBinaryReader,XLSX格式替换为CreateOpenXmlReader即可
using var reader = ExcelReaderFactory.CreateBinaryReader(fileStream);

var excelDataSet = reader.AsDataSet(new ExcelDataSetConfiguration 
{
    ConfigureDataTable = (_) => new ExcelDataTableConfiguration { UseHeaderRow = true }
});

// 遍历所有命名区域
foreach (var definedName in reader.DefinedNames)
{
    // 命名区域名称
    string name = definedName.Name;
    // 所属工作表索引,值为-1时代表是工作簿全局级命名
    int sheetIndex = definedName.SheetIndex;
    // 引用内容:可能是单元格/区域引用、常量、公式,格式如 "Sheet1!$A$1:$C$5"
    string referenceContent = definedName.Text;
    // 是否为Excel自动生成的隐藏命名(如打印区域、筛选范围)
    bool isHidden = definedName.IsHidden;
}

2. 解析引用获取对应值

根据referenceContent的格式判断内容类型,再从DataSet中匹配对应取值:

  • 如果是常量、公式类命名,直接取referenceContent即可拿到定义值
  • 如果是单元格/单元格区域引用,先匹配所属DataTable,再解析行列索引从表中取值
// 示例:读取指定名称的单元格类命名区域值
var targetDefinedName = reader.DefinedNames.First(item => item.Name == "你的命名区域名称");
DataTable sourceTable;

if (targetDefinedName.SheetIndex == -1)
{
    // 全局命名:从引用内容中拆分表名,自动处理表名带单引号的场景
    string rawRef = targetDefinedName.Text;
    string tableName = rawRef.Split('!')[0].Trim('\'');
    sourceTable = excelDataSet.Tables[tableName];
}
else
{
    // 工作表级命名:直接按索引取对应表
    sourceTable = excelDataSet.Tables[targetDefinedName.SheetIndex];
}

// 解析单元格引用(示例处理固定$列$行格式,多单元格区域可扩展正则匹配起止行列)
string cellPart = targetDefinedName.Text.Contains('!') 
    ? targetDefinedName.Text.Split('!')[1] 
    : targetDefinedName.Text;
cellPart = cellPart.Replace("$", "");

// 拆分列字母、行号
string columnLetters = new string(cellPart.TakeWhile(char.IsLetter).ToArray());
int excelRowNum = int.Parse(new string(cellPart.SkipWhile(char.IsLetter).ToArray()));

// 索引转换:Excel行号从1开始,开启UseHeaderRow时第一行是表头,数据行从0基索引开始,因此需要减2
int dataRowIndex = excelRowNum - 2;
// 列索引需自行实现列字母转0基数字索引的逻辑(A=0、B=1...Z=25、AA=26,按26进制转换即可)
int dataColumnIndex = ConvertColumnLetterToIndex(columnLetters);

// 最终获取命名区域对应的值
object namedRangeValue = sourceTable.Rows[dataRowIndex][dataColumnIndex];

注意事项:

  • 如果未开启UseHeaderRow,行索引转换时只需要减1(将Excel 1起始行号转为0基索引即可)
  • 不需要读取系统自动生成的隐藏命名时,可通过isHidden == false过滤掉无关项
  • 多单元格区域命名可在解析单元格部分时,拆分:前后的起止单元格,分别解析行列后遍历范围读取所有值

内容的提问来源于stack exchange,提问作者Val

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 12:57:12