Excel到DataGridView

其他信息:Microsoft Office Access数据库引擎找不到对象“C:\ Users \ username \ Documents \ sampleData.xls”。 确保对象存在,并且正确拼写其名称和path名称。

该错误突出显示在

theDataAdapter.Fill(spreadSheetData); 

这里是我使用的示例数据(用.csv,.xls,.xlsx试用)

 Name Age Status Children Johnny 34 Married 3 Joey 21 Single 1 Michael 16 Dating 0 Smith 42 Divorced 4 

以下是相关的代码:

 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.IO; using System.Data.OleDb; namespace uploadExcelFile { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void btnImport_Click(object sender, EventArgs e) { var frmDialog = new System.Windows.Forms.OpenFileDialog(); if (frmDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) { string strFileName = frmDialog.FileName; System.IO.FileInfo spreadSheetFile = new System.IO.FileInfo(strFileName); scheduleGridView.DataSource = spreadSheetFile.ToString(); System.Diagnostics.Debug.WriteLine(frmDialog.FileName); System.Diagnostics.Debug.WriteLine(frmDialog.SafeFileName); String name = frmDialog.SafeFileName; String constr = String.Format(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=""Excel 12.0 Xml;HDR=YES""", frmDialog.FileName); OleDbConnection myConnection = new OleDbConnection(constr); OleDbCommand onlineConnection = new OleDbCommand("SELECT * FROM [" + frmDialog.FileName + "]", myConnection); myConnection.Open(); OleDbDataAdapter theDataAdapter = new OleDbDataAdapter(onlineConnection); DataTable spreadSheetData = myConnection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null); theDataAdapter.Fill(spreadSheetData); scheduleGridView.DataSource = spreadSheetData; } } } } 

scheduleGridView是DataGridViews名称,&btnImport是导入Button的名称。

我已经安装了2007 Office System Driver:数据连接组件; 这给了我AccessDatabaseEngine.exe,但从那里我一直卡在这里,不知道如何解决这个问题。 不用说,文件path是完全正确的。 path名中没有奇怪的字符(空格,下划线等)

迷你更新::(似乎是另一个死胡同)

虽然最初的错误说:“找不到对象'C:\ Users \ username \ Documents \ sampleData.xls'”

在debugging器中,读取的exception当我将细节看作“C:\ Users \ username \ Documents \ sampleData.xls”

所以我认为错误是它没有把path作为一个文字,但这篇文章C#逐字string文字不工作。 非常奇怪的反斜杠总是显示非常清楚,这不是我的问题。

我猜你可能会误认为从以下代码行返回什么…

 DataTable spreadSheetData = myConnection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null); 

从这行返回的DataTable将有九(9)列(TABLE_CATALOG,TABLE_SCHEMA,TABLE_NAME,TABLE_TYPE,TABLE_GUID,DESCRIPTION,TABLE_PROPID,DATE_CREATED和DATE_MODIFIED)。 这(1) DataTable返回在整个选定的Excel工作簿中简单地“描述”工作表和命名的范围(s)。 此DataTable每一行代表一个工作表或命名范围。 为了区分工作表与命名范围,此DataTable的“TABLE_NAME”列具有工作表或范围的名称,并以美元符号($)结束每个“工作表”名称。 如果行中的“TABLE_NAME”值不以美元符号结尾,那么它是一个范围而不是工作表。

所以当行

 OleDbDataAdapter theDataAdapter = new OleDbDataAdapter(onlineConnection); 

吹起来,说它不能文件的“文件名”错误…是有点期待,因为这一行正在寻找一个“工作表”的名字,而不是文件名。 在创buildselect命令的行上

 OleDbCommand onlineConnection = new OleDbCommand("SELECT * FROM [" + frmDialog.FileName + "]", myConnection); 

这是不正确的; 您已经select了文件名并用打开文件

 String constr = String.Format(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=""Excel 12.0 Xml;HDR=YES""", frmDialog.FileName); OleDbConnection myConnection = new OleDbConnection(constr); myConnection.Open(); 

正确的OleDbCommand行应该是…

 OleDbCommand onlineConnection = new OleDbCommand("SELECT * FROM [" + sheetName + "]", myConnection); 

这里的问题是,当前的代码没有得到工作表名称。 因此,我们不能从工作簿中“select”工作表,然后用工作表填充适配器。

另一个问题是将DataGridViewDataSource设置为spreadSheetData …当您从Excel“工作簿”中获取工作表时,您必须假设将有多个工作表。 因此, DataSet将作为容器来保存工作簿中的所有工作表。 DataSet中的每个DataTable都是单个工作表,并且可以推测DataGridView一次只能显示其中的一个(1)。 鉴于此,下面是描述的更改以及添加button以显示DataGridView的“下一步”工作表,因为工作簿中可能有多个工作表。 希望这是有道理的。

 int sheetIndex = 0; DataSet ds = new DataSet(); public Form1() { InitializeComponent(); } private void btnImport_Click(object sender, EventArgs e) { var frmDialog = new System.Windows.Forms.OpenFileDialog(); if (frmDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) { String constr = String.Format(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=""Excel 12.0 Xml;HDR=YES""", frmDialog.FileName); OleDbConnection myConnection = new OleDbConnection(constr); myConnection.Open(); DataTable spreadSheetData = myConnection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null); string sheetName = ""; DataTable dt; OleDbCommand onlineConnection; OleDbDataAdapter theDataAdapter; // fill the "DataSet" each table in the set is a worksheet in the Excel file foreach (DataRow dr in spreadSheetData.Rows) { sheetName = dr["TABLE_NAME"].ToString(); sheetName = sheetName.Replace("'", ""); if (sheetName.EndsWith("$")) { onlineConnection = new OleDbCommand("SELECT * FROM [" + sheetName + "]", myConnection); theDataAdapter = new OleDbDataAdapter(onlineConnection); dt = new DataTable(); dt.TableName = sheetName; theDataAdapter.Fill(dt); ds.Tables.Add(dt); } } myConnection.Close(); scheduleGridView.DataSource = ds.Tables[0]; setLabel(); } } private void setLabel() { label1.Text = "Showing worksheet " + sheetIndex + " Named: " + ds.Tables[sheetIndex].TableName + " out of a total of " + ds.Tables.Count + " worksheets"; } private void btnNextSheet_Click(object sender, EventArgs e) { if (sheetIndex == ds.Tables.Count - 1) sheetIndex = 0; else sheetIndex++; scheduleGridView.DataSource = ds.Tables[sheetIndex]; setLabel(); } 

我解决了它。 那么有一个解决方法。 我用这个线程中发现的Excel数据读取器: 如何将DataSet转换为DataTable

这导致我https://github.com/ExcelDataReader/ExcelDataReader ^自述是太棒了,只是去解决scheme资源pipe理器,右键点击引用,pipe理NuGet包,select浏览在新框中,inputExcelDataReader,然后在。 cs文件一定要包含“使用Excel” 在顶部,在第一个链接中提到的代码本质上是足够的,但这是我准确的代码为那些想知道。

 var frmDialog = new System.Windows.Forms.OpenFileDialog(); if (frmDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) { /*string strFileName = frmDialog.FileName; //System.IO.FileInfo spreadSheetFile = new System.IO.FileInfo(strFileName); System.IO.StreamReader reader = new System.IO.StreamReader(strFileName); */ string strFileName = frmDialog.FileName; FileStream stream = File.Open(strFileName, FileMode.Open, FileAccess.Read); //1. Reading from a binary Excel file ('97-2003 format; *.xls) IExcelDataReader excelReader = ExcelReaderFactory.CreateBinaryReader(stream); //... //2. Reading from a OpenXml Excel file (2007 format; *.xlsx) //IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream); //... //3. DataSet - The result of each spreadsheet will be created in the result.Tables //DataSet result = excelReader.AsDataSet(); //... //4. DataSet - Create column names from first row excelReader.IsFirstRowAsColumnNames = true; DataSet result = excelReader.AsDataSet(); DataTable data = result.Tables[0]; //5. Data Reader methods while (excelReader.Read()) { //excelReader.GetInt32(0); } scheduleGridView.DataSource = data; excelReader.Close();