2013-08-01 15 views
5

Tôi đã tìm kiếm trên Internet về điều này và không thể tìm thấy câu hỏi như vậy. Mọi người đều đang tìm cách nhập một trang tính riêng lẻ trong tệp excel nhưng những gì tôi muốn là nhập tất cả các trang tính trong tệp vào DataTable trong DataSet mà không biết tên trang tính.Cách nhập tất cả các trang tính Excel vào DataSet trong C#

Tôi chưa làm nhiều việc với Excel trước đây. Đây là một mẫu và mã một phần làm việc tôi đã tìm thấy trên internet và nó chỉ phân tích các tên sheet đưa ra:

public static DataSet Parse(string fileName, string workSheetName) 
{ 
    string connectionString = string.Format("provider=Microsoft.Jet.OLEDB.4.0; data source={0};Extended Properties=Excel 8.0;", fileName); 
    string query = string.Format("SELECT * FROM [{0}$]", workSheetName); 

    DataSet data = new DataSet(); 
    using (OleDbConnection con = new OleDbConnection(connectionString)) 
    { 
     con.Open(); 
     OleDbDataAdapter adapter = new OleDbDataAdapter(query, con); 
     adapter.Fill(data); 
    } 

    return data; 
} 

Trong đoạn mã trên, như bạn thấy, workSheetName nên được thông qua trong quá truy vấn có thể biết được nơi để xem xét nhập. Trong trường hợp của tôi, tôi muốn nó đi qua tất cả các trang tính bất kể chúng được đặt tên như thế nào và nhập chúng vào từng số riêng lẻ của DataSet.

Vì vậy, về bản chất, điều cuối cùng sẽ là DataSet trong đó mỗi DataTable lưu giữ các hàng cho mỗi trang tính trong tệp được nhập.

+0

Bạn thực sự muốn làm việc với file 'csv' khá hơn' xls' . Bạn có thể lưu nó dưới dạng 'csv' không? – zsong

Trả lời

14

Đây là một mã tôi đã đưa ra và nó hoạt động hoàn hảo nhưng tôi thấy người nào khác đã thêm một câu trả lời:

static DataSet Parse(string fileName) 
{ 
    string connectionString = string.Format("provider=Microsoft.Jet.OLEDB.4.0; data source={0};Extended Properties=Excel 8.0;", fileName); 


    DataSet data = new DataSet(); 

    foreach(var sheetName in GetExcelSheetNames(connectionString)) 
    { 
     using (OleDbConnection con = new OleDbConnection(connectionString)) 
     {  
      var dataTable = new DataTable(); 
      string query = string.Format("SELECT * FROM [{0}]", sheetName); 
      con.Open(); 
      OleDbDataAdapter adapter = new OleDbDataAdapter(query, con); 
      adapter.Fill(dataTable); 
      data.Tables.Add(dataTable); 
     } 
    } 

    return data; 
} 

static string[] GetExcelSheetNames(string connectionString) 
{ 
     OleDbConnection con = null; 
     DataTable dt = null; 
     con= new OleDbConnection(connectionString); 
     con.Open(); 
     dt = con.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null); 

     if (dt == null) 
     { 
      return null; 
     } 

     String[] excelSheetNames = new String[dt.Rows.Count]; 
     int i = 0; 

     foreach (DataRow row in dt.Rows) 
     { 
      excelSheetNames[i] = row["TABLE_NAME"].ToString(); 
      i++; 
     } 

     return excelSheetNames; 
} 
+0

tôi có thể nhận được nó bằng cách sử dụng sqlconnection? –

13

Bởi vì tôi đã chán:

static void Main(string[] args) 
{ 
      string filename = @"c:\temp\myfile.xlsx";  
      System.Data.OleDb.OleDbConnection myConnection = new System.Data.OleDb.OleDbConnection( 
         "Provider=Microsoft.ACE.OLEDB.12.0; " + 
         "data source='" + filename + "';" + 
          "Extended Properties=\"Excel 12.0;HDR=YES;IMEX=1\" "); 
      myConnection.Open(); 
      DataTable mySheets = myConnection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" });     
      DataSet ds = new DataSet(); 
      DataTable dt; 

      for (int i = 0; i <= mySheets.Rows.Count; i++) 
      { 
        dt = makeDataTableFromSheetName(filename, mySheets.Rows[i]["TABLE_NAME"].ToString()); 
        ds.Tables.Add(dt); 
      } 
} 

private static DataTable makeDataTableFromSheetName(string filename, string sheetName) 
{  
    System.Data.OleDb.OleDbConnection myConnection = new System.Data.OleDb.OleDbConnection(
    "Provider=Microsoft.ACE.OLEDB.12.0; " + 
    "data source='" + filename + "';" + 
    "Extended Properties=\"Excel 12.0;HDR=YES;IMEX=1\" "); 

    DataTable dtImport = new DataTable(); 
    System.Data.OleDb.OleDbDataAdapter myImportCommand = new System.Data.OleDb.OleDbDataAdapter("select * from [" + sheetName + "$]", myConnection); 
    myImportCommand.Fill(dtImport); 
    return dtImport; 
} 
+0

thực sự hữu ích cho tôi :) – Rebecca

3

Các chức năng đó đã được đề xuất bởi Avitus là chính xác nhưng có lỗi logica, bạn phải viết lại trong:

DataTable dtImport = new DataTable(); 
using (System.Data.OleDb.OleDbConnection myConnection = new System.Data.OleDb.OleDbConnection(
      "Provider=Microsoft.ACE.OLEDB.12.0; " + 
      "data source='" + filename + "';" + 
       "Extended Properties=\"Excel 12.0;HDR=YES;IMEX=1\" ")){ 


using (System.Data.OleDb.OleDbDataAdapter myImportCommand = new System.Data.OleDb.OleDbDataAdapter("select * from [" + sheetName + "$]", myConnection)) 
myImportCommand.Fill(dtImport); 
} return dtImport; 

điều này là đúng, otherwis e bạn phải vứt bỏ kết nối và dataadapter theo cách thủ công.

0

Điều này có thể không phải là tốt nhất và nhanh nhất, nhưng cách khác nó (Edit- thêm loại bỏ các tế bào trống):

public static DataSet ReadWorkbook(string excelFileName, bool useFirstRowAsColumnName = false) 
    { 
     var excel = new Microsoft.Office.Interop.Excel.Application(); 
     var workBook = excel.Workbooks.Open(excelFileName, 0, true, 5, "", "", true, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);//MLHIDE 
     try 
     { 
      System.Data.DataSet ds = new DataSet(excelFileName); 
      foreach (var sheet0 in workBook.Worksheets) 
      { 
       var sheet = (Microsoft.Office.Interop.Excel.Worksheet)sheet0; 
       try 
       { 
        var dt = readSheet(sheet, useFirstRowAsColumnName); 
        if (dt != null) 
         ds.Tables.Add(dt); 
       } 
       finally 
       { 
        releaseObject(sheet); 
       } 
      } 
      return ds; 
     } 
     finally 
     { 
      workBook.Close(true, null, null); 
      excel.Quit(); 

      releaseObject(workBook); 
      releaseObject(excel); 
     } 
    } 

    /// <summary> 
    /// Returns null for empty sheets or if sheet is not found. 
    /// </summary> 
    public static DataTable ReadSheet(string excelFileName, string sheetName, bool useFirstRowAsColumnName = false) 
    { 
     var excel = new Microsoft.Office.Interop.Excel.Application(); 
     var workBook = excel.Workbooks.Open(excelFileName, 0, true, 5, "", "", true, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);//MLHIDE 
     try 
     { 
      foreach (var sheet0 in workBook.Worksheets) 
      { 
       var sheet = (Microsoft.Office.Interop.Excel.Worksheet)sheet0; 
       try 
       { 
        if (sheet.Name.Equals_Wildcard(sheetName)) 
        { 
         var dt = readSheet(sheet, useFirstRowAsColumnName); 
         if (dt != null) 
          return dt; 
        } 
       } 
       finally 
       { 
        releaseObject(sheet); 
       } 
      } 
      return null; 
     } 
     finally 
     { 
      workBook.Close(true, null, null); 
      excel.Quit(); 

      releaseObject(workBook); 
      releaseObject(excel); 
     } 
    } 

    /// <summary> 
    /// Returns null for empty sheets 
    /// </summary> 
private static DataTable readSheet(Microsoft.Office.Interop.Excel.Worksheet sheet, bool useFirstRowAsColumnName = false) 
     { 
      using (Dece.Common.BeginChangeCurrentCultureBlock_EN_us()) 
      { 
       var range = sheet.UsedRange; 
       try 
       { 
        object[,] values = (object[,])range.Value2; 
        int rowCount = values.GetLength(0); 
        int colCount = values.GetLength(1); 
        int rowCount0 = rowCount; 
        int colCount0 = colCount; 
        #region find row-col count 
        { 
         bool ok = false; 
         for (int row = rowCount; row > 0; row--) 
          if (!ok) 
           for (int col = colCount; col > 0; col--) 
           { 
            var val = values[row, col]; 
            if ((val != null) && (!System.Convert.ToString(val).IsNullOrEmpty())) 
            { 
             rowCount = row; 
             ok = true; 
             break; 
            } 
           } 
          else 
           break; 
        } 
        { 
         bool ok = false; 
         for (int col = colCount; col > 0; col--) 
          if (!ok) 
           for (int row = rowCount; row > 0; row--) 
           { 
            var val = values[row, col]; 
            if ((val != null) && (!System.Convert.ToString(val).IsNullOrEmpty())) 
            { 
             colCount = col; 
             ok = true; 
             break; 
            } 
           } 
          else 
           break; 
        } 
        #endregion 
        if ((rowCount > 0) && (colCount > 0)) 
        { 
         var dt = new DataTable(sheet.Name); 
         dt.BeginLoadData(); 
         try 
         { 
          for (int col = 1; col <= colCount; col++) 
           dt.Columns.Add_RenameIfRequired(useFirstRowAsColumnName ? values[1, col].ToString_NullProof() : col.ToString()); 
          var arr = new object[colCount]; 
          for (int row = useFirstRowAsColumnName ? 1 : 0; row < rowCount; row++) 
          { 
           for (int col = 1; col <= colCount; col++) 
            arr[col - 1] = values[row + 1, col]; 
           dt.Rows.Add(arr); 
          } 
         } 
         finally 
         { 
          dt.EndLoadData(); 
         } 
         return dt;       
        } 
        else 
         return null; 
       } 
       finally 
       { 
        releaseObject(range); 
       } 
      } 
     } 

    private static void releaseObject(object obj) 
    { 
     try 
     { 
      System.Runtime.InteropServices.Marshal.ReleaseComObject(obj); 
      obj = null; 
     } 
     catch (Exception ex) 
     { 
      obj = null; 
      throw new Exception("Unable to release the Object " + ex.ToString(), ex);//MLHIDE 
     } 
     finally 
     { 
      GC.Collect(); 
     } 
    }