OpenXML - 不从行C#中读取空白单元格

时间:2016-12-16 12:00:27

标签: c# openxml openxml-sdk

我有一个.xlsx文件,其中包含3列SrNumber,Name,Active,分别为A,B和C列。

我正在使用以下问题的答案中给出的源代码在DataTable中阅读此文件的内容

From Excel to DataTable in C# with Open XML

我也做了Sourabh建议的修改

当我的内容如下时,它工作正常

    A           B       C
1   SrNumber    Name    Active
2   1           test1   Yes
3   2           test2   Yes
4   3           test3   Yes
5   4           test4   Yes

现在,当我尝试在第6个位置添加一行时,我只在B6和C6单元格中输入数据。 我没有触及过A6 Cell。

运行该代码后,我将按以下方式填写DataTable

enter image description here

您可以看到在B6中输入的值在第一列中,而在C6中输入的值在第二列中输入。 此外row.Descendants<Cell>()仅为新输入的行返回2个单元格。

如果要在源代码中进行任何修改,请告诉我。

2 个答案:

答案 0 :(得分:0)

//Read the first Sheet from Excel file.
            IXLWorksheet workSheet = workBook.Worksheet(1);

            //Create a new DataTable.
            DataTable dt = new DataTable();

            //Loop through the Worksheet rows.
            bool firstRow = true;
            foreach (IXLRow row in workSheet.Rows())
            {
                //Use the first row to add columns to DataTable.
                if (firstRow)
                {
                    foreach (IXLCell cell in row.Cells())
                    {
                        dt.Columns.Add(cell.Value.ToString());
                    }
                    firstRow = false;
                }
                else
                {
                    //Add rows to DataTable.
                    dt.Rows.Add();
                    int i = 0;
                    //for (IXLCell cell in row.Cells())
                    for (int j=1;j<= dt.Columns.Count;j++)
                    {
                        if (string.IsNullOrEmpty(row.Cell(j).Value.ToString()))
                            dt.Rows[dt.Rows.Count - 1][i] = "";
                        else
                            dt.Rows[dt.Rows.Count - 1][i] = row.Cell(j).Value.ToString();
                        i++;
                    }
                }
            }

答案 1 :(得分:0)

下面的代码应该为您提供帮助。当我们遇到空单元格时,CellReferenceToIndex非常重要,可用于计算实际单元格索引:

using System;
using System.Data;
using System.Linq;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;

public static DataTable ReadAsDataTable(string fileName)
{
    DataTable dataTable = new DataTable();
    using (SpreadsheetDocument spreadSheetDocument = SpreadsheetDocument.Open(fileName, false))
    {
        WorkbookPart workbookPart = spreadSheetDocument.WorkbookPart;
        IEnumerable<Sheet> sheets = spreadSheetDocument.WorkbookPart.Workbook.GetFirstChild<Sheets>().Elements<Sheet>();
        string relationshipId = sheets.First().Id.Value;
        WorksheetPart worksheetPart = (WorksheetPart)spreadSheetDocument.WorkbookPart.GetPartById(relationshipId);
        Worksheet workSheet = worksheetPart.Worksheet;
        SheetData sheetData = workSheet.GetFirstChild<SheetData>();
        IEnumerable<Row> rows = sheetData.Descendants<Row>();

        foreach (Cell cell in rows.ElementAt(0))
        {
            dataTable.Columns.Add(GetCellValue(spreadSheetDocument, cell));
        }

        foreach (Row row in rows)
        {
            DataRow dataRow = dataTable.NewRow();
            for (int i = 0; i < row.Descendants<Cell>().Count(); i++)
            {
                 Cell cell = row.Descendants<Cell>().ElementAt(i);
                 int actualCellIndex = CellReferenceToIndex(cell);
                 dataRow[actualCellIndex] = GetCellValue(spreadSheetDocument, cell);
            }

            dataTable.Rows.Add(dataRow);
        }

    }
    dataTable.Rows.RemoveAt(0);

    return dataTable;
}

private static string GetCellValue(SpreadsheetDocument document, Cell cell)
{
    SharedStringTablePart stringTablePart = document.WorkbookPart.SharedStringTablePart;
    string value = cell.CellValue.InnerXml;

    if (cell.DataType != null && cell.DataType.Value == CellValues.SharedString)
    {
        return stringTablePart.SharedStringTable.ChildElements[Int32.Parse(value)].InnerText;
    }
    else
    {
        return value;
    }
}

private static int CellReferenceToIndex(Cell cell)
{
    int index = 0;
    string reference = cell.CellReference.ToString().ToUpper();
    foreach (char ch in reference)
    {
        if (Char.IsLetter(ch))
        {
            int value = (int)ch - (int)'A';
            index = (index == 0) ? value : ((index + 1) * 26) + value;
        }
        else
            return index;
    }
    return index;
}