2009-01-09 54 views
6

我有一個從Excel導入數據並處理它的C#/ .Net作業。我們的客戶將文件刪除並處理它們(重要的是因爲我沒有對原始文件的任何控制權)。從.Net導入Excel時的科學記數法

我使用OleDb庫來填充一個數據集(我討厭寫這個代碼,嚴重的是,有沒有.NET開發人員所寫的更多的代碼?)。該文件包含一些數字,如30829300,30071500等...這些列的數據類型是「文本」。

當我導入數據時,這些數字轉換爲科學記數法。無論如何要防止這種情況發生?

克里斯

+0

什麼數據類型,你導入一串數字進入? – scottm 2009-01-09 22:13:21

回答

3

OleDb庫,通常會在Excel電子表格中混淆您的數據。這很大程度上是因爲它將所有內容強制爲固定類型的列布局,猜測在每列的前8個單元格中的每列的類型。如果猜測錯誤,最終會將數字字符串轉換爲科學記數法。布萊什!

爲了避免這種情況,您最好跳過OleDb並直接自己閱讀工作表。您可以使用Excel的COM接口(也是blech!)或第三方.NET Excel兼容閱讀器來完成此操作。 SpreadsheetGear就是這樣一個工作得很好的庫,它的接口與Excel的COM接口非常相似。

0

我發現,最簡單的方法就是選擇Zip格式,而不是文本格式爲大「數字」列。

+0

就像我上面說的,我無法控制這個文件。客戶創建。 – ChrisDiRulli 2009-01-09 21:43:51

0

您是否嘗試將字段的值轉換爲(int)或可能(Int64),因爲您正在閱讀它?

+0

我不會「讀取」文件,OleDb API會這樣做。我只需調用OleDbDataAdapter上的「fill」方法並傳入一個DataSet。然後數據集就會充滿多汁美味的數據。 – ChrisDiRulli 2009-01-09 21:54:12

+0

數據集是否強類型以便字段需要一個數字? – palehorse 2009-01-09 21:55:37

+0

不,它不是強類型。 – ChrisDiRulli 2009-01-09 22:04:26

0

在google上查找IMEX = 1連接字符串選項和TypeGuessRows註冊表設置。 事實上,由於讀者通過查看前幾行(默認爲8)來推斷列數據類型,所以沒有簡單的方法。如果行包含所有數字,那麼你運氣不好。

我過去使用的一個不幸的解決方法是使用HDR = NO連接字符串選項並將TypeGuessRows註冊表設置值設置爲1,這會強制它將第一行讀取爲有效數據以使其數據類型決心,而不是頭。 這是一個黑客,但它的工作。代碼將第一行(包含標題)作爲文本讀取,然後相應地設置數據類型。

更改註冊表是一個痛苦(並不總是可能的),但我建議之後恢復原始值。

如果您的導入數據沒有標題行,那麼另一種選擇是預處理該文件並在違規列中的每個數字前面插入一個'字符。這導致列數據被視爲文本。

所以總而言之,有一堆黑客來解決這個問題,但沒有什麼真正的萬無一失。

0

我有這個相同的問題,但能夠解決它而不訴諸於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

我用Google搜索解決這個狀態.. 這裏是我的solulition步驟

  • 模板excel文件

1格式的Excel coloumn爲文本 2 - 寫宏禁用數字錯誤警告 - >文本轉換

Private Sub Workbook_BeforeClose(Cancel As Boolean) 
Application.ErrorCheckingOptions.BackgroundChecking = Ture 
End Sub 
Private Sub Workbook_Open() 
Application.ErrorCheckingOptions.BackgroundChecking = False 
End Sub 
  • 在代碼隱藏

3-讀取數據時導入 嘗試解析輸入的數據的Int64或的Int32 ....

0

我想知道如果任何人有一個答案。我一直在所有的網站上下來,嘗試IMEX和HDR的所有組合。 IMEX = 1是我設法提取日期,貨幣和一般數字值的唯一一個。但大數據仍然顯示爲科學。我只需要閱讀文件和更改電子表格,註冊表,第三方不是一個選項。

5

一種解決方法這個問題是要改變你的SELECT語句,而不是SELECT *做到這一點:

"SELECT Format([F1], 'General Number') From [Sheet1$]" 
-or- 
"SELECT Format([F1], \"#####\") From [Sheet1$]" 

但是,這樣做將炸燬,如果你的細胞,包含超過255個字符以下錯誤: 「多步OLE DB操作生成錯誤。檢查每個OLE DB狀態值(如果可用),沒有工作完成。」

幸運的是,我的客戶並不關心在這種情況下出錯。

這個頁面有一堆好東西來嘗試,以及: http://www.dicks-blog.com/archives/2004/06/03/external-data-mixed-data-types/

1

如果您使用的Open XML SDK 2.0生產力工具(或簡單地看看實際.XSLX文件解壓縮文件,並查看XML中記事本),您將看到Excel 2007實際上以科學格式存儲原始數據。

例如0.00001存儲爲1.0000000000000001E -5-

<x:c r="C18" s="11" xmlns:x="http://schemas.openxmlformats.org/spreadsheetml/2006/main"> 
    <x:v>1.0000000000000001E-5</x:v> 
</x:c> 

在Excel中的細胞尋找其顯示爲在所述單元和所述式酒吧兩者0.00001。因此,OleDB並不總是造成這個問題。

2

使用此連接字符串:

Provider=Microsoft.ACE.OLEDB.12.0; data source={0}; Extended Properties=\"Excel 12.0;HDR=NO;IMEX=1\" 

與Excel 2010中我注意到以下幾點。如果在運行OLEDB SELECT時打開Excel文件,則會得到當前版本的單元格,而不是保存的文件值。此外,該字符串值返回一個長的數字,十進制值和日期是這樣的:

5.0130370071e+012 
4.08 
36808 

如果文件沒有再打開返回的值是:

5013037007084 
£4.08 
Monday, October 09, 2000