none
System.Data.OleDb如何提取Excel2007单元格的信息 RRS feed

  • 问题

  • 本人是设计行业的。在使用绘图软件的Rhino的插件Grasshopper中的C#组件工作。计划使用System.Data.OleDb的方法读取外部Excel 2007的数据表,然后对某一或某些单元格或某行列的数据进行运算和分析。可是在读取Excel表后不知怎么查询并使用表格中的数据赋值给单个变量或数组。谢谢解答。

    下面是已经进行的代码,继续不下去了。比如第一列的数据是点的坐标,读取后以这个点的数组分别增减数值。

     string connectionString = @"Provider=Microsoft.ACE.OLEDB.12.0;
      Data Source=C:\Members.xlsx;
      Extended Properties=""Excel 12.0;HDR=YES;""";
     // if you don't want to show the header row (first row) in the grid
     // use 'HDR=NO' in the string
    
     string strSQL = "SELECT * FROM [Sheet1$]";
     System.Data.OleDb.OleDbConnection excelConnection = new System.Data.OleDb.OleDbConnection(connectionString);
     excelConnection.Open(); // this will open an Excel file
     System.Data.OleDb.OleDbCommand dbCommand = new System.Data.OleDb.OleDbCommand(strSQL, excelConnection);
     System.Data.OleDb.OleDbDataAdapter dataAdapter1 = new System.Data.OleDb.OleDbDataAdapter(dbCommand);
    
     // create data table
     System.Data.DataTable dTable = new System.Data.DataTable();
    
     dataAdapter1.Fill(dTable);
    

     

     


    2011年3月27日 14:20

答案

  • 你好

    如果希望根据选择的单元格来获取数据的话,就要传递参数进来让程序知道你选择的是那些单元格。

    如果是table中除去1、2行的名称栏后的2/3/4列的数据。
       

      private void RunScript(string myPath, ref object A)
    
      {
    
       string connectionString = @"Provider=Microsoft.JET.OLEDB.4.0" + @"Data Source=" + myPath + @";Extended Properties=""Excel 8.0;HDR=YES;""";
    
       string strSQL = "SELECT * FROM [Sheet1$]";
    
       System.Data.OleDb.OleDbConnection excelConnection = new System.Data.OleDb.OleDbConnection(connectionString);
    
       excelConnection.Open();
    
       System.Data.OleDb.OleDbCommand dbCommand = new System.Data.OleDb.OleDbCommand(strSQL, excelConnection);
    
       System.Data.OleDb.OleDbDataAdapter dataAdapter1 = new System.Data.OleDb.OleDbDataAdapter(dbCommand);
    
       // create data table
    
       System.Data.DataTable dTable = new System.Data.DataTable();
    
       dataAdapter1.Fill(dTable);
    
       List<double> lis = new List<double>();
    
       for (int i = 0; i < dTable.Rows.Count; i++)
    
       {
    
        for (int j = 0; j < dTable.Columns.Count; j++)
    
        {
    
         if (i > 2 && j > 0 && j < 4) //除去第1,2数据行,除去第1,大于等于5的列。
    
         {
    
          lis.Add(Convert.ToDouble(dTable[i][j]));
    
         }
    
        }
    
       }
    
       A = lis;
    
      }
    
    
    不知道是不是满足你的需求。如果有问题,请提出来。谢谢。
    Cookie Luo[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.


    • 已标记为答案 Cookie Luo 2011年4月6日 2:11
    2011年3月30日 6:24

全部回复

  • 楼主可以遍历DataTable 对象的Rows 集合来获取每一行的数据。

    foreach(DataRow row in thisTable.Rows)
    {
        foreach(DataColumn column in thisTable.Columns)
        {
          Console.WriteLine(row[column]); //或者最简单的直接用列名字符串:row["YourColumnName“]
    
        }
    
    }
    
    


    理解的越多,需要记忆的就越少
    2011年3月27日 23:57
    版主
  • 谢谢。

    1.如果只想提取某一单元格的话,需要怎么改写?能否像矩阵一样进行数据提取,如grid[,]。
    2.我想把取出的数据赋予一个List<string>,编写如下。可是出现错误。

    Error: The best overloaded method match for 'System.Collections.Generic.List<string>.Add(string)' has some invalid arguments (line 113)
    Error: Argument '1': cannot convert from 'object' to 'string' (line 113)
    Error: The name 'myresult' does not exist in the current context (line 117)

    ------------code---------------------

     foreach (System.Data.DataRow myrow in dTable.Rows)
    
     {
    
      foreach(System.Data.DataColumn mycolumn in dTable.Columns)
    
      {
    
      //Console.WriteLine(row[column]);
    
      //or use the direct way of row name string: row["YourColumnName"]
    
      for (int i = 0;i < 10;i++)
    
      {
    
       List < string > myresult = new List<string> ();
    
       myresult.Add(myrow[i]);
    
      }
    
      }
    
     }
    
     A = myresult;
    
    

    ------------code---------------------
    2011年3月28日 3:29
  • 在文件路径的地方,能否设定一个string变量读出输入的路径。如
    string mypath; //外部输入赋予mypath

    private void RunScript(string x, ref object A)
     {
      string mypath = x;
      string connectionString = @"Provider=Microsoft.ACE.OLEDB.12.0;
       Data Source=mypath;
       Extended Properties=""Excel 12.0;HDR=YES;""";
    }
    
    
    

    直接使用好像会出错。

    2011年3月28日 4:03
  • 1.你可以使用datatable[row][column]获取特定单元格。

    2.你的myresult的作用与在for里,出了for就不能用了。另外可以使用想要添加到stringlist的对象的ToString()方法。

    2011年3月28日 4:06
  • 使用datatable[row][column]时出现错误:“Error: Cannot apply indexing with [] to an expression of type 'System.Data.DataTable' ”

    for (int i = 0;i < 10;i++)
     {
     List < string > myresults = dTable[i][i].ToString(); 
    }
    
    

     

    另问:

    在文件路径的地方,能否设定一个string变量读出输入的路径。如
    string mypath; //外部输入赋予mypath

    private void RunScript(string x, ref object A)
     {
     string mypath = x;
     string connectionString = @"Provider=Microsoft.ACE.OLEDB.12.0;
      Data Source=mypath;
      Extended Properties=""Excel 12.0;HDR=YES;""";
    }
    
    
    

    直接使用好像会出错。

    2011年3月28日 6:12
  • List < string > myresults = (dTable。Rows[i])[i].ToString();

    获取到table的collection才可以用索引.上面的如果非法的话,可以使用

    DataRow dr = dTable。Rows[i];

    DataColumn dc = dr[i];

    来获取指定的I行I列数据。

    2011年3月28日 6:55
  • 谢谢帮助。看了你的回答理解了一些内容,但由于我是外行的新手,修改了好几次还是不成功。把完整代码贴上来向你请教吧。

    最终是希望实现3种目的:

    1。 object A是一个包含dTable中如第2/3/4列除去头两行的double[][]

    2。 或是A为单独的每一列除去头两行的List<double>.

    3。 独立使用某一个如 [2,3]第二行第三列的数据。

    另外的问题我定义的string myPath希望可以使用在Data Source=myPath,直接使用不成功。

    谢谢了。

    private void RunScript(string myPath, ref object A)
    {
     string connectionString = @"Provider=Microsoft.JET.OLEDB.4.0;
      Data Source=C:\Users\wzhao\Documents\projects_GMP\Bund\planningnorms.xls;
      Extended Properties=""Excel 8.0;HDR=YES;""";
     
    
     string strSQL = "SELECT * FROM [Sheet1$]";
     System.Data.OleDb.OleDbConnection excelConnection = new System.Data.OleDb.OleDbConnection(connectionString);
     excelConnection.Open(); 
     System.Data.OleDb.OleDbCommand dbCommand = new System.Data.OleDb.OleDbCommand(strSQL, excelConnection);
     System.Data.OleDb.OleDbDataAdapter dataAdapter1 = new System.Data.OleDb.OleDbDataAdapter(dbCommand);
    
     // create data table
     System.Data.DataTable dTable = new System.Data.DataTable();
     dataAdapter1.Fill(dTable);
    
      
     foreach(System.Data.DataColumn mycolumn in dTable.Columns)
     {
      foreach (System.Data.DataRow myRow in dTable.Rows)
      {
       List < string > myresults = new List<string>();
       myresults.Add(dTable.Rows[1].ToString());
       A = myresults;
      }
    
     }
    }
    
    2011年3月28日 7:37
  • 你好

    关于这个问题,还有些不明白的。

    1. Objec A 传进来的时候是null,还是有值的?

    2. 传出去的A,是赋值给什么?

    3. 需要的是一个table除去1,2行,2、3、4列的数据?

    对于string myPath的问题,建议你把connectionString 写进配置文件里。App.Config或者web.Config。

    可以通过编程的方式修改。


    Cookie Luo[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2011年3月29日 9:28
  • 谢谢建议。

    外行人有点表述不清,我解释一下。

    1。 Object A 应该是null。在我使用的平台“绘图软件的Rhino的插件Grasshopper中的C#组件”中,A为C#组件的输出端,一般为list或tree的string/double类型等数据,或是软件中的几何模型体,如List 矩形数列。

    2。根据1。的解释,object a 就是输出的最终端。

    3。希望选择单元格来提取数据,如table中除去1、2行的名称栏后的2/3/4列的数据(这里只是举例)

    由于我的编程平台有限,凭没有你提到的其它配置文件如App.Config或者web.Config。

     

    2011年3月29日 11:11
  • 你好

    如果希望根据选择的单元格来获取数据的话,就要传递参数进来让程序知道你选择的是那些单元格。

    如果是table中除去1、2行的名称栏后的2/3/4列的数据。
       

      private void RunScript(string myPath, ref object A)
    
      {
    
       string connectionString = @"Provider=Microsoft.JET.OLEDB.4.0" + @"Data Source=" + myPath + @";Extended Properties=""Excel 8.0;HDR=YES;""";
    
       string strSQL = "SELECT * FROM [Sheet1$]";
    
       System.Data.OleDb.OleDbConnection excelConnection = new System.Data.OleDb.OleDbConnection(connectionString);
    
       excelConnection.Open();
    
       System.Data.OleDb.OleDbCommand dbCommand = new System.Data.OleDb.OleDbCommand(strSQL, excelConnection);
    
       System.Data.OleDb.OleDbDataAdapter dataAdapter1 = new System.Data.OleDb.OleDbDataAdapter(dbCommand);
    
       // create data table
    
       System.Data.DataTable dTable = new System.Data.DataTable();
    
       dataAdapter1.Fill(dTable);
    
       List<double> lis = new List<double>();
    
       for (int i = 0; i < dTable.Rows.Count; i++)
    
       {
    
        for (int j = 0; j < dTable.Columns.Count; j++)
    
        {
    
         if (i > 2 && j > 0 && j < 4) //除去第1,2数据行,除去第1,大于等于5的列。
    
         {
    
          lis.Add(Convert.ToDouble(dTable[i][j]));
    
         }
    
        }
    
       }
    
       A = lis;
    
      }
    
    
    不知道是不是满足你的需求。如果有问题,请提出来。谢谢。
    Cookie Luo[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.


    • 已标记为答案 Cookie Luo 2011年4月6日 2:11
    2011年3月30日 6:24