【问题标题】:Convert Excel Range to ADO.NET DataSet or DataTable, etc将 Excel 范围转换为 ADO.NET 数据集或数据表等
【发布时间】:2011-01-28 08:17:41
【问题描述】:

我有一个 Excel 电子表格,将放在网络共享驱动器上。我的 Winforms C# 3.0 应用程序需要访问它(许多用户可能正在使用该应用程序并同时点击此电子表格)。一张工作表上有很多数据。这些数据被分解成我命名为范围的区域。我需要能够单独访问这些范围,将每个范围作为数据集返回,然后将其绑定到网格。

我找到了使用 OLE 的示例,并且已经让这些示例发挥作用。但是,我看到了一些关于使用这种方法的警告,而且在工作中我们一直使用 Microsoft.Office.Interop.Excel 作为标准。我真的不想偏离这个,除非我必须这样做。据我所知,我们的用户将使用 Office 2003。

我可以通过以下代码得到我需要的范围:

MyDataRange = (Microsoft.Office.Interop.Excel.Range)
    MyWorkSheet.get_Range("MyExcelRange", Type.Missing);

OLE 方式很好,因为它会占用我的第一行并将它们变成列。我的范围(总共 12 个)在大多数情况下在列数上彼此不同。不知道此信息是否会影响任何建议。

有什么方法可以使用 Interop 并将返回的范围返回到数据集中?

【问题讨论】:

    标签: c# excel dataset range


    【解决方案1】:

    在读取/写入 Excel 2003 XLS 文件时,值得一看 NPOI。 NPOI 是救生员。

    我认为您必须迭代您的范围并创建 DataRows 以放入您的 DataTable。

    StackOverflow 上的这个问题提供了更多资源:

    Create Excel (.XLS and .XLSX) file from C#

    【讨论】:

    • 我会在以后的项目中记住这一点。截至目前,我无法在我们的应用程序中引入新库。
    【解决方案2】:

    我不知道内置函数,但自己写应该不难。伪代码:

    DataTable MakeTableFromRange(Range range)
    {
       table = new DataTable
       for every column in range
       {
          add new column to table
       }
       for every row in range
       {
          add new datarow to table
          for every column in range
          {
             table.cells[column, row].value = range[column, row].value
          }
       }
       return table
    }
    

    【讨论】:

    • 感谢所有回复。因为我找不到任何内置的东西,所以我继续前进,只是在范围内滚动并即时创建了一个数据表。此处列出的所有建议都确实有效,只是我不想使用 OLEDB 并且此时我无法引入 3rd 方库。感谢您的快速回复。非常感谢。
    【解决方案3】:

    我不知道你有什么类型的数据。但是对于这个链接http://www.freeimagehosting.net/image.php?f8d4ef4173.png中显示的excel数据,你可以使用以下代码加载到数据表中。

        private void Form1_Load(object sender, EventArgs e)
        {   
           try
           {        
                DataTable sheetTable = loadSingleSheet(@"C:\excelFile.xls", "Sheet1$");
                dataGridView1.DataSource = sheetTable;
           }
           catch (Exception Ex)
           {
                MessageBox.Show(Ex.Message, "");
           }  
        }        
    
        private OleDbConnection returnConnection(string fileName)
        {
            return new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + fileName + "; Jet OLEDB:Engine Type=5;Extended Properties=\"Excel 8.0;\"");
        }
    
        private DataTable loadSingleSheet(string fileName, string sheetName)
        {           
            DataTable sheetData = new DataTable();
            using (OleDbConnection conn = this.returnConnection(fileName))
            {
               conn.Open();
               // retrieve the data using data adapter
               OleDbDataAdapter sheetAdapter = new OleDbDataAdapter("select * from [" + sheetName + "]", conn);
                sheetAdapter.Fill(sheetData);
            }                        
            return sheetData;
        }
    

    【讨论】:

    • 欣赏代码,OLEDB 确实让这一切变得简单,但我现在需要坚持使用 Excel 互操作。
    【解决方案4】:

    当 Excel 电子表格中的同一列同时包含文本和数字时,此方法效果不佳。例如,如果Range("A3")=HelloRange("A7")=5 只读取Hello 并且Range("A7") 的值是DBNULL

    private void Form1_Load(object sender, EventArgs e)
    {   
       try
       {        
            DataTable sheetTable = loadSingleSheet(@"C:\excelFile.xls", "Sheet1$");
            dataGridView1.DataSource = sheetTable;
       }
       catch (Exception Ex)
       {
            MessageBox.Show(Ex.Message, "");
       }  
    }        
    
    private OleDbConnection returnConnection(string fileName)
    {
        return new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + fileName + "; Jet OLEDB:Engine Type=5;Extended Properties=\"Excel 8.0;\"");
    }
    
    private DataTable loadSingleSheet(string fileName, string sheetName)
    {           
        DataTable sheetData = new DataTable();
        using (OleDbConnection conn = this.returnConnection(fileName))
        {
           conn.Open();
           // retrieve the data using data adapter
           OleDbDataAdapter sheetAdapter = new OleDbDataAdapter("select * from [" + sheetName + "]", conn);
            sheetAdapter.Fill(sheetData);
        }                        
        return sheetData;
    

    【讨论】:

      【解决方案5】:

      我制作的方法可以从 Excel 中获取已过滤数据 以 Range 格式获取过滤数据

              Worksheet sheet = null;
              sheet = (Worksheet)context.cDocumentExcel.Sheets[requiredSheetName];
      
              DataTable dt = new DataTable();
              sheet.Activate();
              sheet.UsedRange.Select();
              List<Range> ranges = new List<Range>();
              Range usedrange = sheet.UsedRange;
      
              foreach (var oneRange in usedrange.SpecialCells(XlCellType.xlCellTypeVisible))
              {
                  ranges.Add(oneRange);
              }
      
      
              dt = (_makeTableFromRange(ranges));
      

      从范围转换为数据表

       private static DataTable _makeTableFromRange(List<Range> ranges)
          {
              var table = new DataTable();
      
      
              foreach (var range in ranges)
              {
                  while (table.Columns.Count < range.Column)
                  {
                      table.Columns.Add();
                  }
      
                  while (table.Rows.Count < range.Row)
                  {
                      table.Rows.Add();
                  }
      
                  table.Rows[range.Row - 1][range.Column - 1] = range.Value2;
              }
      
      
              //clean from empty rows
              var filteredRows = table.Rows.Cast<DataRow>().
                              Where(row => !row.ItemArray.All(field => field is System.DBNull ||
                                                                       string.Compare((field as string).Trim(), string.Empty) ==
                                                                       0));
              table = filteredRows.CopyToDataTable();
              return table;
          }
      

      【讨论】:

        猜你喜欢
        • 2014-04-09
        • 1970-01-01
        • 2021-10-23
        • 2018-02-08
        • 2012-02-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多