使用ODBC操作Excel中的一些坑

ODBC可以操作Excel,給程序猿們帶來了方便 ,但是其中的坑真多啊,說起來真是淚,記錄下來,也幫助有需要的人不掉坑里。

1.首先,驅動有兩個,

?{Microsoft Excel Driver (*.xls)}和

?{Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)}

第一個是ODBCJT32.DLL,支持低版本的office;第二個是ACEODBC.DLL(The ODBC Excel driver (ACE)),支持高版本的Office。

建議使用高版本的驅動,如果windows沒有帶高版本的驅動,可以在這里下載:

http://www.microsoft.com/en-us/download/details.aspx?id=13255(Microsoft Access Database Engine 2010 Redistributable)這是2010版,也可以在上面找2016版下載。

2.ODBC DSN,一般格式如下:

DRIVER={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};READONLY=FALSE;DBQ=xx.xls

好多文檔里說還有MaxScanRows?,IMIX,HDR等選項,這方面?的資料比較少,但是好像都不起作用,

3.文件名

這就是一個大坑了,使用英文名,完全沒有問題,但是有一天你突然要打開一個中文文件,可能就會發現出問題了。why?這個可能與操作系統有關,我win 10 64位,系統默認字符集是utf-8,所以DSN要轉換成utf8才能正確打開文件。

4.表

表有三種:

1)自建表,Select * from MyNamedRange

2)sheet,Select * from [MyWorksheet$]

3)range ,?Select * from [MyWorksheet$C3:M8]

操作表的時候要注意了

5.獲取文件里面的所有表

由于excel不是專門的數據庫,里面沒有存放一些常規數據庫的信息,所以沒有方法能直接獲取到所有的表,只有調用ODBC?API才能實現,大概是下面這樣實現:

std::vector<string> TableList;

//excel get tables -->

#define? TABLE_NAME_LENGTH? 100?

SQLHDBC hdbc;

HSTMT hStmt;

int ret = -1;

UCHAR? ? ? szName[256] = { 0 };

SDWORD? ? cbName;

ret = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hStmt);

//? 獲取表信息(返回一個數據表)?

ret = SQLTables(hStmt,

NULL, SQL_NTS, //(SQLCHAR*)SQL_ALL_CATALOGS

NULL, SQL_NTS,

NULL, SQL_NTS,

NULL, SQL_NTS);//(SQLCHAR*)"SYSTEM TABLE"

if (ret == SQL_ERROR)

{

SQLFreeStmt(hStmt, SQL_CLOSE);

//database.Close();

if (ret == SQL_INVALID_HANDLE)

{

//return? false;

}

//return? false;

}

while (1)

{

//取數據到緩沖區

ret = SQLFetch(hStmt);

if (ret == SQL_NO_DATA_FOUND)

break;

//取某一列數據(第3列為表名,其他還有表屬性、數據庫名等)?

ret = SQLGetData(hStmt, 3, SQL_C_CHAR, szName, TABLE_NAME_LENGTH, &cbName);

OutputDebugStringA((char*)szName);

OutputDebugStringA("\t");

TableList.push_back( std::string((char*)szName) );

ret = SQLGetData(hStmt, 4, SQL_C_CHAR, szName, TABLE_NAME_LENGTH, &cbName);

OutputDebugStringA((char*)szName);

OutputDebugStringA("\n");

}

//? 釋放句柄?

SQLFreeStmt(hStmt, SQL_CLOSE);

6.混合字段,這個是最大的坑

對于excel有些列是混合字段,如既有文本又有數字,這個時間odbc就會凌亂了,順便也會把你帶崩潰

由于excel沒有專門存儲列類型的結構,所以odbc驅動是不知道你這個列是什么類型的,MaxScanRows就出廠的,這個值默認是8,意思就是驅動要掃描8行,確定這個列是什么類型。這就比較麻煩了,1.混合字段只掃8行根本看不出哪個占多,就是確定了一個類型,比如文本,你讀純數字的時候,讀出來的都是空值。。。。

這個只有強制在excel中把這一列設成文本,可以解決這個問題。。。


當然,實際情況中坑可能還要多,希望能有所幫助。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容