2017-07-03 69 views
0

附加信息:Microsoft Office Access数据库引擎找不到对象'C:\ Users \ username \ Documents \ sampleData.xls'。确保对象存在,并且正确拼写其名称和路径名。Excel到DataGridView

错误是在

theDataAdapter.Fill(spreadSheetData); 

强调这里的样本数据I使用(以.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是导入Bu的名称tton。

我已经安装了2007 Office System Driver:Data Connectivity Components;这给了我AccessDatabaseEngine.exe,但从那里我一直卡在这里,不理解如何解决这个问题。不用说,文件路径的完整性是正确的。有一个在路径名中没有奇怪的字符或者(空格,下划线等)

迷你更新::(另一个死胡同好像)

虽然最初的错误说“无法找到对象'C:\用户\用户名\ Documents \ sampleData.xls'“

在调试器中,异常读取为 当我查看详细信息”C:\ Users \ username \ Documents \ sampleData.xls “

所以我认为错误是它没有把路径作为一个迭代,但这篇文章C# verbatim string literal not working. Very Strange backslash always double 非常清楚地表明,这不是我的问题。

+0

你有没有试过相对路径,即只有文件名没有目录? –

+0

只是试了一下,得到了同样的错误。相对而言,你的意思只是文件名。扩展名,是否正确? **其他信息:Microsoft Office Access数据库引擎找不到对象'sampleData.xls'。 ** – JoeyG2677

+0

只是想知道您是否仔细检查了文件扩展名是xls,而不是xls.xls? –

回答

1

我猜你可能什么是从下面的代码行返回被误认为...

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)。此ONE(1)DataTable只返回“描述”整个选定Excel工作簿中的工作表和命名范围。 DataTable中的每一行代表工作表或命名范围。为了区分工作表与命名范围,此DataTable中的“TABLE_NAME”列具有工作表或范围的名称,并且每个“工作表”名称都带有美元符号($)。如果行中的“TABLE_NAME”值不以美元符号结尾,那么它是一个范围而不是工作表。

因此,当行

OleDbDataAdapter theDataAdapter = new OleDbDataAdapter(onlineConnection); 

吹灯并说,它无法文件中使用“文件名”的错误...有所预料的,因为这条线正在寻找一个“工作”的名字,而不是一个文件名。在创建选择命令的行上...

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

这是不正确的;你已经选择了文件名,打开该文件

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); 

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

的另一个问题是设置DataGridViewDataSourcespreadSheetData ...当你从Excel‘工作表’工作表上,你必须假设会有多张。因此,DataSet将作为容器来保存工作簿中的所有工作表。 DataSet中的每个DataTable都是单个工作表,并且可以推测DataGridView一次只能显示其中的一个(1)。鉴于此,下面是描述的更改以及添加按钮以显示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(); 
} 
+0

感谢您的全面回答。 http://imgur.com/rPNCqww – JoeyG2677

0

我解决了它。那么有一个解决方法。我曾经在这个线程中发现的Excel数据读取器:How to Convert DataSet to DataTable

害得我https://github.com/ExcelDataReader/ExcelDataReader ^自述是太棒了,刚去的解决方案资源管理器中,右键单击引用,在新箱管理的NuGet软件包,选择浏览,输入ExcelDataReader,然后在.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(); 
+0

这只是一个解决方案,但你最好找出并告诉我们为什么**'Microsoft Office Access数据库引擎找不到对象' –

+0

嗯,这是做同样任务的另一种方式。约翰的回答是正确的。两种方法都有效,但他解释了为什么我的想法不正确。我当前的解决方案不允许上传.csv文件,但如果我真的需要它们,我总是可以回到这里并利用John的解决方案。 – JoeyG2677