将Excel快速导入DataTable

我正在尝试将Excel文件读入Data.DataTable列表中,尽pipe使用当前的方法可能需要很长时间。 我实际上按工作表逐个工作表,而且它往往需要很长时间。 有没有更快的方法来做到这一点? 这是我的代码:

List<DataTable> List = new List<DataTable>(); // 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互操作调用。 我会读取整个范围到一个数组,然后遍历数组:

 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 = 0; 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]; Row[cCnt.ToString()] = cellVal; } } } 

请查看下面的链接

http://www.codeproject.com/Questions/376355/import-MS-Excel-to-datatable (已解答6个解决scheme)

将Excel工作表读入DataTable的最佳/最快方法?

MS Office Interop速度很慢,甚至Microsoft不推荐在服务器端使用Interop,也不能用于导入大型Excel文件。 有关更多详细信息,请参阅为什么不从Microsoft的angular度使用OLE自动化 。

相反,您可以使用任何Excel库,例如EasyXLS 。 这是一个演示如何读取Excel文件的代码示例:

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

如果您的Excel文件有多个工作表或仅导入单元格范围(为了获得更好的性能),请查看更多关于如何使用EasyXLS在C#中将Excel导入到DataTable的代码示例。

在其他人使用EPPlus的情况下。 这个实现相当幼稚,但有些评论引起了人们的注意。 如果您要在顶层添加一个方法GetWorkbookAsDataSet() ,则会执行OP所要求的操作。

  /// <summary> /// 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) /// </summary> /// <param name="worksheet"></param> /// <returns></returns> 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; } /// <summary> /// Assumption: There are no null or empty cells in the first column /// </summary> /// <param name="worksheet"></param> /// <returns></returns> 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<DataColumn> GetDataColumns(ExcelWorksheet worksheet) { return GatherColumnNames(worksheet).Select(x => new DataColumn(x)); } private static IEnumerable<string> GatherColumnNames(ExcelWorksheet worksheet) { var columns = new List<string>(); 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<string> 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() 

如何使用你的格式?

我试试这个:

  Microsoft.Office.Interop.Excel.Application xlApp; Microsoft.Office.Interop.Excel.Workbook xlWorkBook; Microsoft.Office.Interop.Excel.Worksheet xlWorkSheet; var missing = System.Reflection.Missing.Value; xlApp = new Microsoft.Office.Interop.Excel.Application(); xlWorkBook = xlApp.Workbooks.Open(openFileDialog.FileName, false, true, missing, missing, missing, true, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, '\t', false, false, 0, false, true, 0); xlWorkSheet = (Microsoft.Office.Interop.Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1); this.dataGridView1.DataSource = GetWorksheetAsDataTable(xlWorkSheet); this.label1.Text = dataGridView1.RowCount.ToString(); 

最好的方面,adisone