Чтение листа Excel в DataTable с помощью 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.

По этой причине я надеялся использовать библиотеку ClosedXML через Nuget, но я не вижу в их вики примеров чтения листа Excel в DataTable на C #.


person webworm    schedule 12.02.2018    source источник


Ответы (2)


Это не мой пример. Я не могу вспомнить, откуда я это взял, так как это было в моих архивах. Однако у меня это работает. Единственная проблема, с которой я столкнулся, - это пустые ячейки. Согласно обсуждению на вики-странице ClosedXML GitHUb, это как-то связано с тем, что 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;

А также пакет Nuget ClosedXML

Для другого типа данных datetime ... это может быть полезно ... справочник

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();
 }
person webworm    schedule 13.02.2018
comment
Как мы работаем с типом данных даты? - person singhswat; 11.06.2019
comment
@singhswat Я относился ко всему как к строке - person webworm; 11.06.2019
comment
Выдает исключение нулевой ссылки в этой строке. foreach (ячейка IXLCell в строке.Cells (row.FirstCellUsed (). Address.ColumnNumber, row.LastCellUsed (). Address.ColumnNumber)) - person Jyotirmaya Prusty; 16.01.2020
comment
@JyotirmayaPrusty оборачивает содержимое условия else, содержащего этот цикл for, в условие if (row.FirstCellUsed ()! = Null). В противном случае он не работает с полностью пустой строкой. - person Brandon Barkley; 02.08.2020
comment
Если ваш лист содержит формулы Value, произойдет сбой. Мне кажется, что использование CachedValue дает то, что вы хотите, хотя во всех случаях, которые я тестировал. Это также работает для прямых значений, поскольку они содержат одно и то же. InnerText может быть другим вариантом. - person Brandon Barkley; 02.08.2020

С помощью этого кода вы можете прочитать содержимое таблицы Excel. Вы можете указать имя листа или номер, набор данных будет возвращен с содержимым листа.

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;
            }
person David Alejandro Restrepo Madri    schedule 29.11.2018
comment
Это должен быть принятый ответ. Работает как положено. - person Jyotirmaya Prusty; 16.01.2020