如何将特定的列和行的Excel数据导入到datagridview WITHOUT OLEDB在C#

我为自动映射networking驱动器做了一个简单的独立程序。 该程序使用DataGridView列出所有的驱动器号和path,我写的代码读取DataGridView的条目,并映射基于此的驱动器 – 也从特定的Excel表中获取驱动器号和path。

该特定的Excel文件使用VB代码跟踪用户计算机的某些信息。 名为“驱动器”的第三张工作表是networking驱动器所在的位置。驱动器号和path位于列C和D中。除了在行3上的名称“networking驱动器”在行3上开始之前,没有标题不幸的是,在第29行之后,outlook pst文件的条目开始了。

有了我对C#的有限知识(我是C#的新手),我设法创build了这个:

 public void FileSelect() { string filePath = string.Empty; string fileExt = string.Empty; OpenFileDialog file = new OpenFileDialog(); //open dialog to choose file file.Filter = "Discovery Excel|*.xlsm| CSV (Coming Soon)| *.csv"; file.Title = "Please select a valid data file"; if (file.ShowDialog() == System.Windows.Forms.DialogResult.OK) //if there is a file choosen by the user { filePath = file.FileName; //get the path of the file fileExt = Path.GetExtension(filePath); //get the file extension if (fileExt.CompareTo(".xls") == 0 || fileExt.CompareTo(".xlsm") == 0) { try { DataTable dtExcel = new DataTable(); dtExcel = ReadExcel(filePath, fileExt); //read file InfoTB.Visible = false; dataGridView1.Visible = true; FileSelectBT.Visible = false; ManualBT.Visible = false; RunBT.Visible = true; ExitBT.Visible = true; RunBT.Location = new System.Drawing.Point(109, 334); ExitBT.Location = new System.Drawing.Point(190, 334); dataGridView1.DataSource = dtExcel; dataGridView1.AutoResizeColumns(); dataGridView1.Columns[0].HeaderText = "Drive Letter"; dataGridView1.Columns[1].HeaderText = "Drive Path"; for (int i = 1; i < dataGridView1.RowCount - 1; i++) { if (dataGridView1.Rows[i].Cells[0].Value.ToString() == "" || dataGridView1.Rows[i].Cells[1].Value.ToString() == "") { dataGridView1.Rows.RemoveAt(i); i--; } } } catch (Exception ex) { MessageBox.Show("Oops! Something went wrong! We'll make a log of that.\nDon't worry, we'll open the Excel File and switch to manuel mode for you!", "FAIL!", MessageBoxButtons.OK, MessageBoxIcon.Error); ManualMode(); OpenExcel(filePath); TextWriter txt = new StreamWriter(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "NDrive_Error_Log.txt"); //Saving the info from the results textbox to an actual text file txt.Write(ex.ToString()); txt.Close(); } } else { MessageBox.Show("Please choose .xlsm or .CSV file only.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Error); //custom messageBox to show error } } } public DataTable ReadExcel(string fileName, string fileExt) { string conn = string.Empty; DataTable dtexcel = new DataTable(); conn = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source =" + fileName + ";Extended Properties=\"Excel 12.0 Xml;HDR=YES;IMEX=1\";"; //loading the Access engine to load/read the Excel file using (OleDbConnection con = new OleDbConnection(conn)) { try { OleDbDataAdapter oleAdpt = new OleDbDataAdapter("Select TOP 24 F3,F4 FROM [Drives$]", conn); //read data from sheet 3 which should be the drives oleAdpt.Fill(1, 24, dtexcel); //fill excel data into dataTable } catch (InvalidOperationException ex) { MessageBox.Show("Oops! Something went wrong! We'll make a log of that.\nDon't worry, we'll open the Excel File and switch to manuel mode for you!", "FAIL!", MessageBoxButtons.OK, MessageBoxIcon.Error); ManualMode(); OpenExcel(fileName); TextWriter txt = new StreamWriter(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)+ "NDrive_Error_Log.txt"); //Saving the info from the results textbox to an actual text file txt.Write(ex.ToString()); txt.Close(); } } return dtexcel; } 

而这个代码工作!

这是当程序有一些条目时,程序的样子

不幸的是,当将程序从一台计算机移到另一台计算机时,Microsoft.ACE.OLEDB.12.0并不可靠。 我无法在工作中的每台计算机上安装ACE,因此我必须find另一种方法来专门读取Excel文件,而无需使用OLEDB。

我曾四处寻找替代解决scheme,但我发现的东西似乎是专注于特定的起始行而不是结束行。

虽然公平,但我是C#的新手,所以我可能忽略了一些对我的程序有帮助的东西。

也就是说,这种情况下是否有OLEDB的替代品?

正如PaulF的评论所述,Excel Interop是一个可行的解决scheme,可以节省使用任何外部库的需求。

以下是假定您的数据将始终在C3:D29 ,并假定工作表中的数据是有效的:

 public DataTable ReadExcel(string fileName) { var excel = new Excel.Application(); var wkb = excel.Workbooks.Open(fileName, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing); var sheet = wkb.Sheets["Drives"] as Excel.Worksheet; var range = sheet.Range[sheet.Cells[3, 3], sheet.Cells[29, 4]]; var data = range.Value2; var dt = new DataTable(); dt.Columns.Add("Drive"); dt.Columns.Add("Path"); for (int i = 1; i <= range.Rows.Count; i++) { dt.Rows.Add(data[i, 1], data[i, 2]); } return dt; }