首页 > 解决方案 > 如何始终使用 DocumentFormat.OpenXml 跳过指定的行数

问题描述

我使用 DocumentFormat.OpenXml 遍历行,有时我需要从第 4、8、11 行开始。我用下面的“skipRows”和“If”定义了应该跳过多少行让我跳过不必要的行:

var rows = sheet.Descendants<Row>();
foreach (Row row in rows)
{
    if (dataRowIndex < skipRows)
    {
         dataRowIndex++;
         continue;
    }

问题是有时当行完全为空时,它不会自动迭代它。有时当它为空时,它会遍历它。当所述行中写入任何单元格时,它总是迭代。这是为什么?无论这些行中的单元格中是否有任何数据,我如何确保它总是跳过例如 6 行?

标签: c#openxml

解决方案


有时当它为空时,它会遍历它。当所述行中写入任何单元格时,它总是迭代。这是为什么?

这是由于定义 XML 模式的方式。模式中的一行是完全可选的;如果一行中没有数据,则不需要将其写入 XML(尽管也没有什么可以阻止它被写入)。如果一行中有一个单元格,则该行必须写入 XML,因为一个单元格是一行的子单元;没有该行,就无处可写单元格。

无论这些行中的单元格中是否有任何数据,我如何确保它总是跳过例如 6 行?

您可以使用 的RowIndex属性Row来找出Row正在读取的实际索引。

下面的例子应该做你所追求的:

using (SpreadsheetDocument document = SpreadsheetDocument.Open(filePath, false))
{
    WorkbookPart workbookPart = document.WorkbookPart;
    WorksheetPart worksheetPart = workbookPart.WorksheetParts.First();
    SheetData sheetData = worksheetPart.Worksheet.Elements<SheetData>().First();

    SharedStringTablePart stringTable = workbookPart.GetPartsOfType<SharedStringTablePart>().FirstOrDefault();

    var rows = sheetData.Descendants<Row>();

    foreach (Row row in rows)
    {
        if (row.RowIndex <= skipRows)
        {
            continue;
        }

        //this is just to show that it's outputting from the first non-skipped row
        Cell cell = row.GetFirstChild<Cell>();
        string contents;

        if (cell.DataType == CellValues.SharedString)
        {
            int index = int.Parse(cell.CellValue.InnerText);
            contents = stringTable.SharedStringTable.ElementAt(index).InnerText;
        }
        else
        {
            contents = cell.InnerText;
        }
        Console.WriteLine(contents);
    }
}

推荐阅读