問題:
OleDB讀取Excel、csv時,某些有資料的欄位卻是空值!?
這是...OleDB的硬傷,先說明一下他的淺規則~
讀取的資料都有行列,每一行的前8格(預設),Excel會解析這8格裡面最多格的型態,並將此行預設為此符合此型態才給讀取,否則為空值。
來看看我們的例子:
Input:
10 |
11 |
546 |
2154489 |
545 |
巴拉巴拉巴 |
454 |
55 |
Output:
"10" |
"11" |
"546" |
"2154489" |
"545" |
"" |
"454" |
"55" |
解決方法1:
設定系統機碼!
事實上會有這樣的淺規則,就是因為微軟Excel的設定,OleDB是微軟以統一方式來訪問不同儲存格式的應用程式介面,所以OleDB會以Excel的設定來制定這樣的淺規則也是合理的吧。
所以我們只能乖乖的開啟機碼設定來進行修改:
Win xp
開始→搜尋→regedit→HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\3.5\Engines\Excel
Win 7
開始→搜尋→regedit→HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Jet\4.0\Engines\Excel
Excel機碼中,ImportMixedTypes的預設值為Text,也就是我們讀取的Excel、csv檔案,若每1行的資料格式不一致,則Jet Engine將其欄位格式自動轉為文字格式。
Excel機碼中,TypeGuessRows 的預設值為8,也就是我們讀取的Excel、csv檔案,若每1行的前8格的資料格式不一致,Jet Engine將會以前8格裡面最多的型態來當作此行的預設型態,若此行某格非此行的預設型態,則讀取時會有null值。
所以,我們將ImportMixedTypes的值仍為Text、TypeGuessRows的值改為0,此時完成收工。
需注意的是將TypeGuessRows的值改為0,這樣一來Jet Engine會將所有資料讀取完再判斷每格欄位的資料型態!也就是說我們讀取的資料量越大,將會影響資料讀取的效能...
最後再提醒一件事,若是此功能需上架(當然會上架啦QQ),代表需修改server上的機碼...所以...上架的話還是放棄吧!以免接下來的開發、維護會哭哭。
解決方法1.1:
再利用OleDB讀取檔案時,設定檔案路徑設定的地方之中,在Extended Properties=''裡,加入ImportMixedTypes=Text與TypeGuessRows=0,有看過不少人討論這樣做是能解決的,但我沒試出來就是了...
string FileLocation = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\DataExcel.xls;Extended Properties='Excel 8.0;HDR=NO;IMEX=1;ImportMixedTypes=Text;TypeGuessRows=0'";
解決方法2:
改用 NPOI 來讀取 Excel 吧!如此一來即能一格一格的判斷欄位格式。
使用NPOI.SS.UserModel.ICell.CellType就可以知道是什麼資料型態,接著用對應的資料型態的XXXCellValue屬性去取得資料。
這部分仍須再研究NPOI才是...若都做好要改很麻煩啊。囧rz
解決方法3:
設計讀取的excel、csv資料填寫格式,每一行都要填寫相同欄位格式,並且唬弄告知使用者相關的使用規定,開發者設定程式沒按照此設定走而導致讀取時出現null,將出現Error Message,告知使用者需修改相關資料。
騙吃騙吃啦!
結論:
大致上能想的到的解決方法就這幾種,以後有想到會再補上。
有參考到這篇唷!“透過 OleDb 精準讀入 Excel 檔的方法”。
http://blog.miniasp.com/post/2011/04/07/Open-a-ReadOnly-file-will-cause-UnauthorizedAccessException-in-TFS-project.aspx
留言列表