Импорт Excel в DataTable Быстро

Я пытаюсь прочитать файл Excel в списке Data.DataTable, хотя с моим текущим методом это может занять очень много времени. Я по существу иду Worksheet по листу, ячейке по ячейке, и он имеет тенденцию занимать очень много времени. Есть ли более быстрый способ сделать это? Вот мой код:

List List = new List(); // Counting sheets for (int count = 1; count < WB.Worksheets.Count; ++count) { // Create a new DataTable for every Worksheet DATA.DataTable DT = new DataTable(); WS = (EXCEL.Worksheet)WB.Worksheets.get_Item(count); textBox1.Text = count.ToString(); // Get range of the worksheet Range = WS.UsedRange; // Create new Column in DataTable for (cCnt = 1; cCnt <= Range.Columns.Count; cCnt++) { textBox3.Text = cCnt.ToString(); Column = new DataColumn(); Column.DataType = System.Type.GetType("System.String"); Column.ColumnName = cCnt.ToString(); DT.Columns.Add(Column); // Create row for Data Table for (rCnt = 0; rCnt <= Range.Rows.Count; rCnt++) { textBox2.Text = rCnt.ToString(); try { cellVal = (string)(Range.Cells[rCnt, cCnt] as EXCEL.Range).Value2; } catch (Microsoft.CSharp.RuntimeBinder.RuntimeBinderException) { ConvertVal = (double)(Range.Cells[rCnt, cCnt] as EXCEL.Range).Value2; cellVal = ConvertVal.ToString(); } // Add to the DataTable if (cCnt == 1) { Row = DT.NewRow(); Row[cCnt.ToString()] = cellVal; DT.Rows.Add(Row); } else { Row = DT.Rows[rCnt]; Row[cCnt.ToString()] = cellVal; } } } // Add DT to the list. Then go to the next sheet in the Excel Workbook List.Add(DT); } 

Caling .Value2 – дорогостоящая операция, потому что это COM-interop-вызов. Вместо этого я прочитал бы весь диапазон в массиве, а затем пропустил бы массив:

 object[,] data = Range.Value2; // Create new Column in DataTable for (int cCnt = 1; cCnt <= Range.Columns.Count; cCnt++) { textBox3.Text = cCnt.ToString(); var Column = new DataColumn(); Column.DataType = System.Type.GetType("System.String"); Column.ColumnName = cCnt.ToString(); DT.Columns.Add(Column); // Create row for Data Table for (int rCnt = 1; rCnt <= Range.Rows.Count; rCnt++) { textBox2.Text = rCnt.ToString(); string CellVal = String.Empty; try { cellVal = (string)(data[rCnt, cCnt]); } catch (Microsoft.CSharp.RuntimeBinder.RuntimeBinderException) { ConvertVal = (double)(data[rCnt, cCnt]); cellVal = ConvertVal.ToString(); } DataRow Row; // Add to the DataTable if (cCnt == 1) { Row = DT.NewRow(); Row[cCnt.ToString()] = cellVal; DT.Rows.Add(Row); } else { Row = DT.Rows[rCnt + 1]; Row[cCnt.ToString()] = cellVal; } } } 

Пожалуйста, ознакомьтесь с приведенными ниже ссылками.

http://www.codeproject.com/Questions/376355/import-MS-Excel-to-datatable (опубликовано 6 решений)

Лучший / самый быстрый способ чтения листа Excel в DataTable?

MS Office Interop работает медленно, и даже Microsoft не рекомендует использовать Interop на стороне сервера и не может использоваться для импорта больших файлов Excel. Для получения дополнительной информации см. Почему не использовать OLE Automation с точки зрения Microsoft.

Вместо этого вы можете использовать любую библиотеку Excel, например, EasyXLS . Это пример кода, который показывает, как читать файл Excel:

 ExcelDocument workbook = new ExcelDocument(); DataSet ds = workbook.easy_ReadXLSActiveSheet_AsDataSet("excel.xls"); DataTable dataTable = ds.Tables[0]; 

Если ваш файл Excel имеет несколько листов или для импорта только диапазонов ячеек (для повышения производительности), посмотрите на дополнительные примеры кода о том, как импортировать Excel в DataTable на C # с помощью EasyXLS .

Если кто-то еще использует EPPlus. Эта реализация довольно наивна, но есть замечания, которые привлекают внимание к такому. Если бы вы GetWorkbookAsDataSet() еще один метод GetWorkbookAsDataSet() он будет делать то, что просит OP.

  ///  /// Assumption: Worksheet is in table format with no weird padding or blank column headers. /// /// Assertion: Duplicate column names will be aliased by appending a sequence number (eg. Column, Column1, Column2) ///  ///  ///  public static DataTable GetWorksheetAsDataTable(ExcelWorksheet worksheet) { var dt = new DataTable(worksheet.Name); dt.Columns.AddRange(GetDataColumns(worksheet).ToArray()); var headerOffset = 1; //have to skip header row var width = dt.Columns.Count; var depth = GetTableDepth(worksheet, headerOffset); for (var i = 1; i <= depth; i++) { var row = dt.NewRow(); for (var j = 1; j <= width; j++) { var currentValue = worksheet.Cells[i + headerOffset, j].Value; //have to decrement b/c excel is 1 based and datatable is 0 based. row[j - 1] = currentValue == null ? null : currentValue.ToString(); } dt.Rows.Add(row); } return dt; } ///  /// Assumption: There are no null or empty cells in the first column ///  ///  ///  private static int GetTableDepth(ExcelWorksheet worksheet, int headerOffset) { var i = 1; var j = 1; var cellValue = worksheet.Cells[i + headerOffset, j].Value; while (cellValue != null) { i++; cellValue = worksheet.Cells[i + headerOffset, j].Value; } return i - 1; //subtract one because we're going from rownumber (1 based) to depth (0 based) } private static IEnumerable GetDataColumns(ExcelWorksheet worksheet) { return GatherColumnNames(worksheet).Select(x => new DataColumn(x)); } private static IEnumerable GatherColumnNames(ExcelWorksheet worksheet) { var columns = new List(); var i = 1; var j = 1; var columnName = worksheet.Cells[i, j].Value; while (columnName != null) { columns.Add(GetUniqueColumnName(columns, columnName.ToString())); j++; columnName = worksheet.Cells[i, j].Value; } return columns; } private static string GetUniqueColumnName(IEnumerable columnNames, string columnName) { var colName = columnName; var i = 1; while (columnNames.Contains(colName)) { colName = columnName + i.ToString(); i++; } return colName; } 
 Dim sSheetName As String Dim sConnection As String Dim dtTablesList As DataTable Dim oleExcelCommand As OleDbCommand Dim oleExcelReader As OleDbDataReader Dim oleExcelConnection As OleDbConnection sConnection = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Test.xls;Extended Properties=""Excel 12.0;HDR=No;IMEX=1""" oleExcelConnection = New OleDbConnection(sConnection) oleExcelConnection.Open() dtTablesList = oleExcelConnection.GetSchema("Tables") If dtTablesList.Rows.Count > 0 Then sSheetName = dtTablesList.Rows(0)("TABLE_NAME").ToString End If dtTablesList.Clear() dtTablesList.Dispose() If sSheetName <> "" Then oleExcelCommand = oleExcelConnection.CreateCommand() oleExcelCommand.CommandText = "Select * From [" & sSheetName & "]" oleExcelCommand.CommandType = CommandType.Text oleExcelReader = oleExcelCommand.ExecuteReader nOutputRow = 0 While oleExcelReader.Read End While oleExcelReader.Close() End If oleExcelConnection.Close() 
Interesting Posts

Редактирование файла hosts

Очистить кэш в приложении Android программно

Получить список сертификатов из хранилища сертификатов в C #

Список распространенных методов оптимизации на C ++

Поле электронной почты Facebook возвращает null (даже если разрешение «электронная почта» установлено и принято)

Насколько быстрее C ++, чем C #?

Кабели HDMI для VGA действительно работают так, как рекламируются?

Способы перебора списка в Java

Получить размеры экрана в пикселях

Запуск пользовательского приложения для Android от браузера android

Существует ли NAS, который может действовать как «простой», «немой» USB-накопитель?

Имея как созданные, так и обновленные столбцы временной отметки в MySQL 4.0

Может ли веб-сайт видеть / знать мой MAC-адрес, даже если я использую VPN?

Получение фактической ширины элемента с плавающей запятой

инициализация C ++ std :: istringstream из буфера памяти?

Давайте будем гением компьютера.