2010-06-02 103 views
2

我讀Csharp的使用OLEDB Excel文件,我已經展示了樣品的Excel數據我有什麼閱讀Excel中通過OLEDB讀取字符串作爲DBNull的

F1 F2 F3 F4 
India 23 44 4 
China 4  8  Month 6 
USA 45 Neg 4 

,當我讀到這些數據併爲您在我的DataTable我得到空值爲「第6個月」和「負」 其中,因爲我可以正確獲取F1列...我的連接字符串如圖所示

Provider = Microsoft.ACE.OLEDB.12.0; Data Source = [XLSource ];擴展屬性= Excel 12.0;

OleDbDataReader dr; 
OleDbConnection conExcel = new OleDbConnection(); 
conExcel.ConnectionString = ConnectionString 
conExcel.Open(); 
OleDbCommand cmdExcel = new OleDbCommand(); 
cmdExcel.Connection = conExcel; 
cmdExcel.CommandText = "SELECT * FROM Sheet1$"; 
dr = cmdExcel.ExecuteReader(); 
DataTable dtExcel = new DataTable(); 
dtExcel.Load(dr); 
+1

你可以顯示代碼如何讀入你的DataTable嗎? – chiccodoro 2010-06-02 06:51:25

+1

沒有足夠的信息來回答 – 2010-06-02 06:51:55

回答

4

嘗試在連接字符串中使用IMEX = 1參數(google瞭解更多信息)。

我認爲發生的事情是,Excel從前幾行推斷出每列的數據類型。當它遇到一個與推斷的數據類型不匹配的值時,它將其視爲null。

+0

但它需要在系統中註冊一些DLL時,我使用它顯示「無法找到可安裝的ISAM」。 – Sathish 2010-06-02 06:59:38

+1

連接字符串的語法可能不正確。谷歌搜索「Excel Oledb無法找到可安裝的ISAM」將提供一些幫助,包括以下線程:http://www.devnewsgroups.net/adonet/t16014-could-not-find-installable-isam.aspx – Joe 2010-06-02 07:12:27

+0

擴展屬性必須放在引號Extended Properties =「」Excel 8.0; HDR = NO「」「 – rsapru 2012-06-29 08:51:22

2

我有這個問題,而不是設置IMEX = 1我設置註冊表設置TypeGuessRows爲0而不是默認的8,我讀IMEX將需要的地方,但它似乎拿起這種註冊表變化的方式。
但是,我使用Jet提供程序而不是Ace,因此可能會有所作爲。

對我來說,我發現在設置:Hkey_Local_Machine/Software/Microsoft/Jet/4.0/Engines/Excel/TypeGuessRows

+0

當我將此值更改爲零它太長,以閱讀表:( – Sathish 2010-06-02 10:03:50

+0

嗯,據我所知,有效值是0-16,其中0意味着讀取所有行(最多65000或我認爲的東西,因此它不適合大單)來決定數據類型,而其他值意味着讀取多行,所以我想你可以嘗試與16,看看是否有幫助。 – 2010-06-02 10:20:42

0

我回答了類似的問題here。在這裏,我已經複製並粘貼了相同的答案,以方便您:

我有這個相同的問題,但能夠解決它而不訴諸於Excel COM接口或第三方軟件。它涉及一點處理開銷,但似乎爲我工作。

  1. 數據首先閱讀得到的列名
  2. 然後創建與這些列的新的數據集,他們的每一個數據類型設置爲字符串。
  3. 將數據再次讀入新的 數據集。瞧 - 科學 符號現在已經消失,所有內容都以字符串形式讀入。

下面是一些代碼,說明了這一點,作爲一個額外的好處,它甚至StyleCopped!

public void ImportSpreadsheet(string path) 
{ 
    string extendedProperties = "Excel 12.0;HDR=YES;IMEX=1"; 
    string connectionString = string.Format(
     CultureInfo.CurrentCulture, 
     "Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=\"{1}\"", 
     path, 
     extendedProperties); 

    using (OleDbConnection connection = new OleDbConnection(connectionString)) 
    { 
     using (OleDbCommand command = connection.CreateCommand()) 
     { 
      command.CommandText = "SELECT * FROM [Worksheet1$]"; 
      connection.Open(); 

      using (OleDbDataAdapter adapter = new OleDbDataAdapter(command)) 
      using (DataSet columnDataSet = new DataSet()) 
      using (DataSet dataSet = new DataSet()) 
      { 
       columnDataSet.Locale = CultureInfo.CurrentCulture; 
       adapter.Fill(columnDataSet); 

       if (columnDataSet.Tables.Count == 1) 
       { 
        var worksheet = columnDataSet.Tables[0]; 

        // Now that we have a valid worksheet read in, with column names, we can create a 
        // new DataSet with a table that has preset columns that are all of type string. 
        // This fixes a problem where the OLEDB provider is trying to guess the data types 
        // of the cells and strange data appears, such as scientific notation on some cells. 
        dataSet.Tables.Add("WorksheetData"); 
        DataTable tempTable = dataSet.Tables[0]; 

        foreach (DataColumn column in worksheet.Columns) 
        { 
         tempTable.Columns.Add(column.ColumnName, typeof(string)); 
        } 

        adapter.Fill(dataSet, "WorksheetData"); 

        if (dataSet.Tables.Count == 1) 
        { 
         worksheet = dataSet.Tables[0]; 

         foreach (var row in worksheet.Rows) 
         { 
          // TODO: Consume some data. 
         } 
        } 
       } 
      } 
     } 
    } 
} 
0

我回答了another question很像這個。

簡言之,控制ACE駕駛員行爲的設置是在位於註冊表:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\14.0\Access Connectivity Engine\Engines\Excel 

設置ImportMixedTypesText並設置TypeGuessRows0(或一些適當一大批像1000),你應該得到你期待的行爲。