C#通過OleDb讀寫excel表格幾個要點,
1,OleDbConnection 的連接字串:
0ffice 97-2003 :
strConnection = string.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties=\"Excel 8.0;HDR={1};IMEX={2:D}\";", ExcelFilePath, HDR, IMEX);
//HDR=No 表示ADO將不把你Excel檔案的第一行作為欄位名(此時使用預設欄位名:F1,F2。。)
//IMEX= 0寫入模式,1讀模數式,2串連讀寫入模式(效率不高),"IMEX=1;" 則始終將“互混”資料列作為文本讀取
office2007:
strConnection = string.Format("Provider==Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=\"Excel 12.0 Xml;HDR={1};IMEX={2:D}\";", ExcelFilePath, HDR, IMEX);
2,建立串連並開啟:
try
{
Connection = new OleDbConnection(strConnection);
/* 特別說明: 在C++中建立串連後,串連就可以直接使用。 在C#中,串連可以使用 datatable 等操作,但是串連此時處於關閉狀態。//*/
Connection.Open();
/* 特別說明,如果沒有這一句,串連處於關閉狀態,執行sql語句會提示錯誤:串連關閉不可用。我用一天的時間才研究出來
這個貌似 MSDN 和 網上都沒有相關資料和說明,我一直奇怪,建立串連都沒任何錯誤,datatable.fill()都沒問題,為何執行sql語句串連處於關閉不可用呢?
大部分情況大量資料回寫匯出到EXCEL表格,都會是SQL資料庫,可以用 SqlBulkCopy ,只是我的資料庫卻是 SqlCe,不支援SqlBulkCopy
所以,只能自己做線程執行插入語句。
貌似在 C++ 中,建立串連後,從來沒有自己手動去Open,,,,,,,,,,,,,
//*/
}
catch (OleDbException ex )
{
}
3,執行sql語句:
try
{
OleDbCommand comm = new OleDbCommand(sqlstr, Connection);
result = comm.ExecuteNonQuery(); //返回受影響的資料行數量。
}
catch (OleDbException e)
{
}
4,excel表格sql語句書寫
string sqlstr="select F1,F2 from [Sheet1$] ";//注意表名稱[] 和 $ 都不能少了。
5,讀取的時候,部分資料丟失,或者錯誤。
excel預設掃描前8行資料,以便自動識別欄位資料類型,故,後面如果欄位類型不符合,或者欄位超長度,就會出現丟失。
1,IMEX=1 串連的時候設為讀模數式,將數字和字元始終做字元處理。
2,修改註冊表,將行數改更大 0 - 16;0代表整個表格。
TypeGuessRows 設定為 0,,注意表格如果較大,10000行,改成0,則需要考慮效能和效率問題。
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\4.0\Engines\Excel]
Windows 7 的登錄機碼目
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Jet\4.0\Engines\Excel
3,修改註冊表指令碼
@echo off reg add HKLM\SOFTWARE\Microsoft\Jet\4.0\Engines\Excel /v TypeGuessRows /t REG_DWORD /d 0 /f
@echo off reg add "HKLM\SOFTWARE\Microsoft\Office\12.0\Access Connectivity Engine\Engines\Excel" /v TypeGuessRows /t REG_DWORD /d 0 /f
@echo off reg add "HKLM\SOFTWARE\Microsoft\Office\14.0\Access Connectivity Engine\Engines\Excel" /v TypeGuessRows /t REG_DWORD /d 0 /f