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

如何使用OpenXML读取Excel中指定行的单元格范围

使用OpenXML读取Excel指定行的单元格范围

看起来你已经走对路了——用OpenXML操作Excel的核心就是拿到SheetData对象,接下来咱们把精准读取指定行范围的逻辑补上,还要处理OpenXML里空单元格不存储的坑。

先理清楚需求对应的参数

你需要读取的两个范围,咱们先整理成结构化的集合,方便后续循环处理(注意:OpenXML里的行号和列号都是从1开始计数的,和Excel界面保持一致):

// 键是目标行号,值是列的起始/结束索引
var targetCellRanges = new Dictionary<int, (int StartColumn, int EndColumn)>
{
    { 3, (8, 25) },
    { 7, (4, 32) }
};

核心实现逻辑

基于你已经拿到的SheetData,咱们先定位到目标行,再筛选该行中指定列范围的单元格,同时处理空单元格的情况:

WorkbookPart workbookPart = spreadsheetDocument.WorkbookPart;
WorksheetPart worksheetPart = workbookPart.WorksheetParts.First();
SheetData sheetData = worksheetPart.Worksheet.Elements<SheetData>().First();

// 先拿到共享字符串表(Excel会把重复文本存在这里,单元格只存索引)
SharedStringTablePart sharedStringTable = workbookPart.GetPartsOfType<SharedStringTablePart>().FirstOrDefault();

foreach (var range in targetCellRanges)
{
    int targetRowNumber = range.Key;
    var (startCol, endCol) = range.Value;

    // 找到目标行:Row.RowIndex就是Excel里的行号
    Row targetRow = sheetData.Elements<Row>().FirstOrDefault(row => row.RowIndex == targetRowNumber);

    if (targetRow == null)
    {
        Console.WriteLine($"第{targetRowNumber}行不存在或完全为空");
        continue;
    }

    Console.WriteLine($"=== 读取第{targetRowNumber}行,列{startCol}到{endCol} ===");

    // 遍历指定列范围,逐个处理单元格
    for (int currentCol = startCol; currentCol <= endCol; currentCol++)
    {
        // 找到当前列对应的单元格:需要解析CellReference(比如"H3")里的列索引
        Cell targetCell = targetRow.Elements<Cell>().FirstOrDefault(cell => GetColumnIndexFromCellRef(cell.CellReference) == currentCol);
        string cellContent = GetCellActualValue(targetCell, sharedStringTable);

        // 空单元格咱们统一显示"空",避免输出null
        Console.WriteLine($"列{currentCol}:{cellContent ?? "空"}");
    }
}

两个必备的辅助方法

上面用到了两个工具方法,用来解析列索引和获取单元格的真实值:

解析单元格引用的列索引

比如把"H3"转换成列号8:

private static int GetColumnIndexFromCellRef(string cellReference)
{
    int columnIndex = 0;
    foreach (char c in cellReference)
    {
        if (char.IsLetter(c))
        {
            // 把字母转换成数字:A=1,B=2...Z=26,AA=27以此类推
            columnIndex = columnIndex * 26 + (c - 'A' + 1);
        }
        else
        {
            // 遇到数字就停止,后面是行号
            break;
        }
    }
    return columnIndex;
}

获取单元格的实际文本值

处理共享字符串和普通文本的情况:

private static string GetCellActualValue(Cell cell, SharedStringTablePart sharedStringTable)
{
    if (cell == null) return null;

    string rawValue = cell.CellValue?.InnerText;
    if (string.IsNullOrEmpty(rawValue)) return null;

    // 如果是共享字符串类型,从共享字符串表中取出真实文本
    if (cell.DataType != null && cell.DataType.Value == CellValues.SharedString)
    {
        if (sharedStringTable != null && int.TryParse(rawValue, out int stringIndex))
        {
            return sharedStringTable.SharedStringTable.Elements<SharedStringItem>().ElementAtOrDefault(stringIndex)?.InnerText;
        }
    }

    // 普通文本直接返回
    return rawValue;
}

几个要注意的细节

  1. 空单元格处理:OpenXML不会为空白单元格生成Cell元素,所以咱们必须主动遍历列范围,而不是直接遍历行里的所有单元格,不然会漏掉空单元格。
  2. 共享字符串:Excel为了节省空间,会把重复的文本存在共享字符串表中,单元格只存储索引,所以必须判断DataType才能拿到真实内容。
  3. 索引计数:OpenXML的行号和列号都是从1开始的,和Excel界面一致,别搞成0开始的索引了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 03:39:52