使用 ClosedXML 将 Excel 个工作表读入 DataTable

Read Excel worksheet into DataTable using ClosedXML

我想将 Excel 工作表的内容读入 C# DataTable。 Excel 工作表可以有可变数量的列和行。 Excel 工作表的第一行将始终包含列名,但其他行可能为空。

我在 SO 中看到的所有建议都假定存在 Microsoft.ACE.OLEDB。我的系统上没有安装此库,因为当我尝试其中一些解决方案时出现此错误。

Microsoft.ACE.OLEDB.12.0' provider is not registered on the local machine.

奇怪,因为我安装了 Office 2016。

出于这个原因,我希望通过 Nuget 使用 ClosedXML 库,但我在他们的 wiki 中没有看到任何在 C# 中将 Excel 工作表读取到 DataTable 的示例。

这个例子不是我的。我不记得我是从哪里得到它的,因为它在我的档案中。但是,这对我有用。我 运行 遇到的唯一问题是空白单元格。根据 dicussion on the ClosedXML GitHUb wiki page 它与 Excel 不跟踪不受数据限制的空单元格有关。我发现如果我将数据添加到单元格然后删除相同的数据,则该过程有效。

public static DataTable ImportExceltoDatatable(string filePath, string sheetName)
{
  // Open the Excel file using ClosedXML.
  // Keep in mind the Excel file cannot be open when trying to read it
  using (XLWorkbook workBook = new XLWorkbook(filePath))
  {
    //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;

        foreach (IXLCell cell in row.Cells(row.FirstCellUsed().Address.ColumnNumber, row.LastCellUsed().Address.ColumnNumber))
        {
          dt.Rows[dt.Rows.Count - 1][i] = cell.Value.ToString();
          i++;
        }
      }
    }

    return dt;
  }
}

需要添加

using System.Data;
using ClosedXML.Excel;

以及 ClosedXML nuget 包

对于其他日期时间数据类型...这可能会有所帮助...reference

if (cell.Address.ColumnLetter=="J") // Column with date datatype
 {
    DateTime dtime = DateTime.FromOADate(double.Parse(cell.Value.ToString()));
                     dt.Rows[dt.Rows.Count - 1][i] = dtime;
 }
 else
 {
      dt.Rows[dt.Rows.Count - 1][i] = cell.Value.ToString();
 }

使用此代码,您可以阅读 excel sheet 的内容。您可以指定 sheet 的名称或编号,将返回一个包含 sheet 内容的数据集。

public static DataTable GetDataFromExcel(string path, dynamic worksheet)
        {
            //Save the uploaded Excel file.


            DataTable dt = new DataTable();
            //Open the Excel file using ClosedXML.
            using (XLWorkbook workBook = new XLWorkbook(path))
            {
                //Read the first Sheet from Excel file.
                IXLWorksheet workSheet = workBook.Worksheet(worksheet);

                //Create a 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())
                        {
                            if (!string.IsNullOrEmpty(cell.Value.ToString()))
                            {
                                dt.Columns.Add(cell.Value.ToString());
                            }
                            else
                            {
                                break;
                            }
                        }
                        firstRow = false;
                    }
                    else
                    {
                        int i = 0;
                        DataRow toInsert = dt.NewRow();
                        foreach (IXLCell cell in row.Cells(1, dt.Columns.Count))
                        {
                            try
                            {
                                toInsert[i] = cell.Value.ToString();
                            }
                            catch (Exception ex)
                            {

                            }
                            i++;
                        }
                        dt.Rows.Add(toInsert);
                    }
                }
                return dt;
            }