C++使用ODBC驱动读取EXCEL表格(只读)

<h-begin>和<h-end>之间是clsExcel.h的完整内容;<cpp-begin>和<cpp-end>之间是clsExcel.cpp的完整内容;

注意:ODBC驱动,可以通过安装微软官方提供的ADE驱动来安装(Mircrosoft Access Database Engine),区分32位和64版本。该驱动与已经安装的Office位数有冲突性,比如安装的Office是32位,那么驱动就无法安装64位,同样如果Office安装的是64位,则ADE也无法安装32位,必须不冲突,但不要求系统必须安装Office。32位的程序只能调用32位的驱动,64位的程序只能调用64位的驱动。

clsODBCExcelRead类的使用方法相对灵活,整体步骤是:初始化ODBC驱动->打开EXCEL表格文件->读单元数据(重复读操作,直到读完所有需要的单元格)->关闭EXCEL表格文件;在类卸载以前,不必反复初始化驱动;在关闭EXCEL表格文件之前,表格一直保持打开状态(其他程序无法修改EXCEL文件)。

传入文件名的函数提供ANSI版本和UNICODE版本;读写TEXT类型的数据时,也提供ANSI和UNICODE两个版本。

//<h-begin>clsExcel,v1.0.001
//Excel文件常用操作
//updated:2024-02-26
//
//#include "clsExcel.h"
/*
*Driver name:Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)
*Runtime:Mircrosoft Access Database Eengine
*max count of column:255
*max count of item:1048576
*/
#pragma once
#include <Windows.h>
#include <sqlext.h>
#include <sql.h>

#ifndef EXCEL_TEXTA
#define EXCEL_TEXTA 1
#endif
#ifndef EXCEL_TEXTW
#define EXCEL_TEXTW (-8)
#endif

//拆分
//将ABC123拆分成ABC为column,123为item.字母是26进制表示的数值.
bool Excel_SplitNameA (char    * pstrName, unsigned long * pulColumn, unsigned long * pulItem);
bool Excel_SplitNameW (wchar_t * pstrName, unsigned long * pulColumn, unsigned long * pulItem);

//--------------------------------------------------clsODBCExcelRead-begin
class clsODBCExcelRead
{
public:
    clsODBCExcelRead();
    ~clsODBCExcelRead();
    //class
    bool Init   (void);
    void UnInit (void);
    //file
    bool OpenA (char    * pstrFilename);
    bool OpenW (wchar_t * pstrFilename);
    bool Close (void);
    //Column
    bool CountOfColumnA (char    * pstrSheetname, unsigned long * pulCountOfColumn);
    bool CountOfColumnW (wchar_t * pstrSheetname, unsigned long * pulCountOfColumn);
    //data
    unsigned long ReadA (char    * pstrSheetname, unsigned long ulColumn, unsigned long ulItem, void * pvAddress, unsigned long ulSize);
    unsigned long ReadW (wchar_t * pstrSheetname, unsigned long ulColumn, unsigned long ulItem, void * pvAddress, unsigned long ulSize);
    unsigned long ReadTextA(char    * pstrSheetname, unsigned long ulColumn, unsigned long ulItem, char    * pstrString, unsigned long ulSize);
    unsigned long ReadTextW(wchar_t * pstrSheetname, unsigned long ulColumn, unsigned long ulItem, wchar_t * pstrString, unsigned long ulSize);
private:
    SQLHANDLE chandle_Environment; //数据库环境句柄
    SQLHANDLE chandle_Connect;//数据库连接句柄
};
//step 1:Init().
//step 2:OpenA()/OpenW().
//step 3: ReadA()/ReadW(),ReadTextA(),ReadTextW().
//step 4:Close();
//recall OpenA(),OpenW()...Read...
//step 5:UnInit().
//--------------------------------------------------clsODBCExcelRead-end
//<h-end>

//<cpp-begin>clsExcel,v1.0.001
//Excel文件常用操作
//updated:2024-02-26
//
#pragma warning (disable:4996)
#include "clsExcel.h"
#include <odbcinst.h>
#pragma comment(lib,"odbccp32.lib")
//#include "\..\module\String.h"
//#include "Debug.h"

#ifndef VALNUM0
#define VALNUM0 0x30
#endif
#ifndef VALNUM9
#define VALNUM9 0x39
#endif
#ifndef VALLETTERLA
#define VALLETTERLA 0x61
#endif
#ifndef VALLETTERLZ
#define VALLETTERLZ 0x7A
#endif
#ifndef VALLETTERUA
#define VALLETTERUA 0x41
#endif
#ifndef VALLETTERUZ
#define VALLETTERUZ 0x5A
#endif

static const wchar_t mconststrW_Text_NameOfODBCExcelDriver[]  = L"Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)";
static const char    mconststrA_Text_NameOfODBCExcelDriver[]  =  "Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)";

bool Excel_SplitNameA (char    * pstrName, unsigned long * pulColumn, unsigned long * pulItem)
{//将ABC123翻译成ABC为column,123为item.ABC对应的是26进制值
    if (NULL == pstrName)    return false;
    unsigned long i = 0;
    unsigned long ulColumn = 0, ulItem = 0;
    while (0 != pstrName[i])
    {
        if (VALLETTERLA <= pstrName[i] && VALLETTERLZ >= pstrName[i])//a-z
        {
            ulColumn = ulColumn * 26 + (pstrName[i] - VALLETTERLA + 1);
        }
        else if (VALLETTERUA <= pstrName[i] && VALLETTERUZ >= pstrName[i])//A-Z
        {
            ulColumn = ulColumn * 26 + (pstrName[i] - VALLETTERUA + 1);
        }
        else if (VALNUM0 <= pstrName[i] && VALNUM9 >= pstrName[i])//0~9
        {//not run next while,and variable(i)stop at the digital bit.
            break;
        }
        else
        {
            return false;//invalid char.
        }
        i++;
    }
    if (!(VALNUM0 <= pstrName[i] && VALNUM9 >= pstrName[i]))    return false;//string not have digit(0~9).
    while (0 != pstrName[i])
    {
        if (VALNUM0 <= pstrName[i] && VALNUM9 >= pstrName[i])//0~9
        {
            ulItem = ulItem * 10 + (pstrName[i] - VALNUM0);
        }
        else
        {
            return false;//invalid char.
        }
        i++;
    }
    if (0 == ulColumn || 0 == ulItem)    return false;
    if (NULL != pulColumn)    *pulColumn = ulColumn;
    if (NULL != pulItem)    *pulItem = ulItem;
    return true;
}
bool Excel_SplitNameW (wchar_t * pstrName, unsigned long * pulColumn, unsigned long * pulItem)
{
    if (NULL == pstrName)    return false;
    unsigned long i = 0;
    unsigned long ulColumn = 0, ulItem = 0;
    while (0 != pstrName[i])
    {
        if (VALLETTERLA <= pstrName[i] && VALLETTERLZ >= pstrName[i])//a-z
        {
            ulColumn = ulColumn * 26 + (pstrName[i] - VALLETTERLA + 1);
        }
        else if (VALLETTERUA <= pstrName[i] && VALLETTERUZ >= pstrName[i])//A-Z
        {
            ulColumn = ulColumn * 26 + (pstrName[i] - VALLETTERUA + 1);
        }
        else if (VALNUM0 <= pstrName[i] && VALNUM9 >= pstrName[i])//0~9
        {//not run next while,and variable(i)stop at the digital bit.
            break;
        }
        else
        {
            return false;//invalid char.
        }
        i++;
    }
    if (!(VALNUM0 <= pstrName[i] && VALNUM9 >= pstrName[i]))    return false;//string not have digit(0~9).
    while (0 != pstrName[i])
    {
        if (VALNUM0 <= pstrName[i] && VALNUM9 >= pstrName[i])//0~9
        {
            ulItem = ulItem * 10 + (pstrName[i] - VALNUM0);
        }
        else
        {
            return false;//invalid char.
        }
        i++;
    }
    if (0 == ulColumn || 0 == ulItem)    return false;
    if (NULL != pulColumn)    *pulColumn = ulColumn;
    if (NULL != pulItem)    *pulItem = ulItem;
    return true;
}
//----------------------------------------------------------------------------------------------------clsODBCExcelRead-begin
clsODBCExcelRead::clsODBCExcelRead()
{
    chandle_Environment = NULL;
    chandle_Connect = NULL;
}
clsODBCExcelRead::~clsODBCExcelRead()
{
    UnInit();
}
bool clsODBCExcelRead::Init   (void)
{
    SQLRETURN   ret = 0;
    //判断是否已经初始化完成过
    if (NULL != chandle_Environment)    return true;
    //分配环境句柄
    ret = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &chandle_Environment);
    if (!SQL_SUCCEEDED(ret))
    {
        chandle_Environment = NULL;
        return false;
    }
    //设置ODBC版本
    ret = SQLSetEnvAttr(chandle_Environment, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0);
    if (!SQL_SUCCEEDED(ret))
    {
        SQLFreeHandle(SQL_HANDLE_ENV, chandle_Environment);
        chandle_Environment = NULL;
    }
    return true;
}
void clsODBCExcelRead::UnInit (void)
{
    if (NULL != chandle_Connect)
    {
        SQLFreeHandle(SQL_HANDLE_DBC, chandle_Connect);
        chandle_Connect = NULL;
    }
    if (NULL != chandle_Environment)
    {
        SQLFreeHandle(SQL_HANDLE_ENV, chandle_Environment);
        chandle_Environment = NULL;
    }
}
bool clsODBCExcelRead::OpenA (char    * pstrFilename)
{
    SQLCHAR    strConnect[2048] = { 0 };
    SQLCHAR    outstr[1024];
    SQLSMALLINT outstrlen = 1024;
    SQLRETURN   ret = 0;
    if (NULL == chandle_Environment)
    {
        SetLastError(6);//6=句柄无效
        return false;
    }
    if (NULL != chandle_Connect)
    {
        SetLastError(80);//80:文件存在
        return false;
    }
    //分配连接句柄
    ret = SQLAllocHandle(SQL_HANDLE_DBC, chandle_Environment, &chandle_Connect);
    if (!SQL_SUCCEEDED(ret))
    {
        chandle_Connect = NULL;
        return false;
    }
    strcpy((char*)strConnect, "DRIVER={");
    strcat((char*)strConnect, mconststrA_Text_NameOfODBCExcelDriver);
    strcat((char*)strConnect, "};DBQ=");
    strcat((char*)strConnect, pstrFilename);
    strcat((char*)strConnect, ";");

    ret = SQLDriverConnectA(chandle_Connect, NULL, (SQLCHAR*)strConnect, SQL_NTS, outstr, 1024, &outstrlen, SQL_DRIVER_COMPLETE);
    if (SQL_SUCCEEDED(ret))    return true;
    return false;
}
bool clsODBCExcelRead::OpenW (wchar_t * pstrFilename)
{
    SQLWCHAR    strConnect[2048] = { 0 };
    SQLWCHAR    outstr[1024];
    SQLSMALLINT outstrlen = 1024;
    SQLRETURN   ret = 0;
    if (NULL == chandle_Environment)
    {
        SetLastError(6);//6=句柄无效
        return false;
    }
    if (NULL != chandle_Connect)
    {
        SetLastError(80);//80:文件存在
        return false;
    }
    //分配连接句柄
    ret = SQLAllocHandle(SQL_HANDLE_DBC, chandle_Environment, &chandle_Connect);
    if (!SQL_SUCCEEDED(ret))
    {
        chandle_Connect = NULL;
        return false;
    }
    //语句确定
    wcscpy((wchar_t*)strConnect, L"DRIVER={");
    wcscat((wchar_t*)strConnect, mconststrW_Text_NameOfODBCExcelDriver);
    wcscat((wchar_t*)strConnect, L"};DBQ=");
    wcscat((wchar_t*)strConnect, pstrFilename);
    wcscat((wchar_t*)strConnect, L";");
    //执行连接
    ret = SQLDriverConnectW(chandle_Connect, NULL, strConnect, SQL_NTS, outstr, 1024, &outstrlen, SQL_DRIVER_COMPLETE);
    if (SQL_SUCCEEDED(ret))    return true;
    return false;
}
bool clsODBCExcelRead::Close (void)
{
    SQLRETURN ret = 0;
    if (NULL == chandle_Connect)    return false;
    ret = SQLDisconnect(chandle_Connect);
    if (!SQL_SUCCEEDED(ret))    return false;
    ret = SQLFreeHandle(SQL_HANDLE_DBC, chandle_Connect);
    switch (ret)
    {
    case SQL_SUCCESS://成功释放
        chandle_Connect = NULL;
        return true;
    case SQL_SUCCESS_WITH_INFO://成功释放
        chandle_Connect = NULL;
        return true;
    case SQL_ERROR:
        return false;//句柄依然有效
    case SQL_INVALID_HANDLE:
        chandle_Connect = NULL;
        return true;//传入的句柄是无效的
    default:
        return false;
    }
}
bool clsODBCExcelRead::CountOfColumnA (char    * pstrSheetname, unsigned long * pulCountOfColumn)
{
    SQLHANDLE   hSTMT = NULL;
    SQLCHAR    query[1024] = { 0 };
    SQLSMALLINT colCount = 0;
    SQLRETURN   ret = 0;
    //分配语句句柄
    ret = SQLAllocHandle(SQL_HANDLE_STMT, chandle_Connect, &hSTMT);
    if (!SQL_SUCCEEDED(ret))    return false;
    //查询语句确定
    strcpy((char*)query, "SELECT * FROM [");
    strcat((char*)query, pstrSheetname);
    strcat((char*)query, "]");
    ret = SQLExecDirectA(hSTMT, query, SQL_NTS);
    if (!SQL_SUCCEEDED(ret))
    {
        SQLFreeHandle(SQL_HANDLE_STMT, hSTMT);
        return false;
    }
    ret = SQLNumResultCols(hSTMT, &colCount);
    SQLFreeHandle(SQL_HANDLE_STMT, hSTMT);
    if (!SQL_SUCCEEDED(ret))    return false;
    if (NULL != pulCountOfColumn)    *pulCountOfColumn = (unsigned long)colCount;
    return true;
}
bool clsODBCExcelRead::CountOfColumnW (wchar_t * pstrSheetname, unsigned long * pulCountOfColumn)
{
    SQLHANDLE   hSTMT = NULL;
    SQLWCHAR    query[1024] = { 0 };
    SQLSMALLINT colCount = 0;
    SQLRETURN   ret = 0;
    //分配语句句柄
    ret = SQLAllocHandle(SQL_HANDLE_STMT, chandle_Connect, &hSTMT);
    if (!SQL_SUCCEEDED(ret))    return false;
    //查询语句确定
    wcscpy((wchar_t*)query, L"SELECT * FROM [");
    wcscat((wchar_t*)query, pstrSheetname);
    wcscat((wchar_t*)query, L"]");
    //提交查询
    ret = SQLExecDirectW(hSTMT, query, SQL_NTS);
    if (!SQL_SUCCEEDED(ret))
    {
        SQLFreeHandle(SQL_HANDLE_STMT, hSTMT);
        return false;
    }
    //获取查询结果
    ret = SQLNumResultCols(hSTMT, &colCount);
    SQLFreeHandle(SQL_HANDLE_STMT, hSTMT);
    if (SQL_SUCCEEDED(ret))
    {
        if (NULL != pulCountOfColumn)    *pulCountOfColumn = (unsigned long)colCount;
        return true;
    }
    return false;
}
unsigned long clsODBCExcelRead::ReadA (char    * pstrSheetname, unsigned long ulColumn, unsigned long ulItem, void * pvAddress, unsigned long ulSize)
{
    SQLHANDLE  hSTMT = NULL;
    SQLCHAR   query[1024] = { 0 };
    SQLINTEGER dataLen = 0;
    SQLRETURN  ret = 0;
    //分配语句句柄
    ret = SQLAllocHandle(SQL_HANDLE_STMT, chandle_Connect, &hSTMT);
    if (!SQL_SUCCEEDED(ret))    return 0;
    //查询语句确定
    strcpy((char*)query, "SELECT * FROM [");
    strcat((char*)query, pstrSheetname);
    strcat((char*)query, "]");
    //提交查询
    ret = SQLExecDirectA(hSTMT, query, SQL_NTS);
    if (!SQL_SUCCEEDED(ret))
    {
        SQLFreeHandle(SQL_HANDLE_STMT, hSTMT);
        return 0;
    }
    SQLSMALLINT colType = 0;
    SQLSMALLINT datType = 0;
    //获取指定目标的数据类型
    ret = SQLDescribeColA(hSTMT, (SQLUSMALLINT)ulColumn, NULL, 0, NULL, &colType, NULL, NULL, NULL);
    if (!SQL_SUCCEEDED(ret))
    {
        SQLFreeHandle(SQL_HANDLE_STMT, hSTMT);
        return 0;
    }
    switch (colType) {
    case SQL_CHAR:
    case SQL_VARCHAR:
    case SQL_LONGVARCHAR:
        datType = SQL_C_CHAR;
        break;
    case SQL_INTEGER:
    case SQL_SMALLINT:
    case SQL_TINYINT:
    case SQL_BIGINT:
        datType = SQL_C_LONG;
        break;
    case SQL_FLOAT:
    case SQL_DOUBLE:
    case SQL_REAL:
        datType = SQL_C_DOUBLE;
        break;
        // 其他数据类型...  
    default:
        // 不支持的数据类型,处理错误  
        return SQL_ERROR;
    }
    //跳转到指定行
    for (unsigned long i = 1; i < ulItem; i++)//行计数是从1开始的,所以读写第N行是执行(N-1)次跳转.
    {
        ret = SQLFetch(hSTMT);
        if (!SQL_SUCCEEDED(ret))    break;
    }
    //确认跳转是成功的
    if (!SQL_SUCCEEDED(ret))
    {
        SQLFreeHandle(SQL_HANDLE_STMT, hSTMT);
        return 0;
    }
    //尝试读取数据
    ret = SQLGetData(hSTMT, (SQLUSMALLINT)ulColumn, datType, (SQLPOINTER)pvAddress, (SQLINTEGER)ulSize, (SQLINTEGER*)&dataLen);
    SQLFreeHandle(SQL_HANDLE_STMT, hSTMT);
    if (!SQL_SUCCEEDED(ret))    return 0;
    return (unsigned short)dataLen;
}
unsigned long clsODBCExcelRead::ReadW (wchar_t * pstrSheetname, unsigned long ulColumn, unsigned long ulItem, void * pvAddress, unsigned long ulSize)
{
    SQLHANDLE  hSTMT = NULL;
    SQLWCHAR   query[1024] = { 0 };
    SQLINTEGER dataLen = 0;
    SQLRETURN  ret = 0;
    //分配语句句柄
    ret = SQLAllocHandle(SQL_HANDLE_STMT, chandle_Connect, &hSTMT);
    if (!SQL_SUCCEEDED(ret))    return 0;
    //查询语句确定
    wcscpy((wchar_t*)query, L"SELECT * FROM [");
    wcscat((wchar_t*)query, pstrSheetname);
    wcscat((wchar_t*)query, L"]");
    //提交查询
    ret = SQLExecDirectW(hSTMT, query, SQL_NTS);
    if (!SQL_SUCCEEDED(ret))
    {
        SQLFreeHandle(SQL_HANDLE_STMT, hSTMT);
        return 0;
    }
    SQLSMALLINT colType = 0;
    SQLSMALLINT datType = 0;
    //获取指定目标的数据类型
    ret = SQLDescribeColW(hSTMT, (SQLUSMALLINT)ulColumn, NULL, 0, NULL, &colType, NULL, NULL, NULL);
    if (!SQL_SUCCEEDED(ret))
    {
        SQLFreeHandle(SQL_HANDLE_STMT, hSTMT);
        return 0;
    }
    switch (colType) {
    case SQL_CHAR:
    case SQL_VARCHAR:
    case SQL_LONGVARCHAR:
        datType = SQL_C_CHAR;
        break;
    case SQL_INTEGER:
    case SQL_SMALLINT:
    case SQL_TINYINT:
    case SQL_BIGINT:
        datType = SQL_C_LONG;
        break;
    case SQL_FLOAT:
    case SQL_DOUBLE:
    case SQL_REAL:
        datType = SQL_C_DOUBLE;
        break;
        // 其他数据类型...  
    default:
        // 不支持的数据类型,处理错误  
        return SQL_ERROR;
    }
    //跳转到指定行
    for (unsigned long i = 1; i < ulItem; i++)//行计数是从1开始的,所以读写第N行是执行(N-1)次跳转.
    {
        ret = SQLFetch(hSTMT);
        if (!SQL_SUCCEEDED(ret))    break;
    }
    //确认跳转是成功的
    if (!SQL_SUCCEEDED(ret))
    {
        SQLFreeHandle(SQL_HANDLE_STMT, hSTMT);
        return 0;
    }
    //尝试读取数据
    ret = SQLGetData(hSTMT, (SQLUSMALLINT)ulColumn, datType, (SQLPOINTER)pvAddress, (SQLINTEGER)ulSize, (SQLINTEGER*)&dataLen);
    SQLFreeHandle(SQL_HANDLE_STMT, hSTMT);
    if (!SQL_SUCCEEDED(ret))    return 0;
    return (unsigned short)dataLen;
}
unsigned long clsODBCExcelRead::ReadTextA (char    * pstrSheetname, unsigned long ulColumn, unsigned long ulItem, char    * pstrString, unsigned long ulSize)
{
    SQLHANDLE  hSTMT = NULL;
    SQLCHAR   query[1024] = { 0 };
    SQLINTEGER dataLen = 0;
    SQLRETURN  ret = 0;
    //分配语句句柄
    ret = SQLAllocHandle(SQL_HANDLE_STMT, chandle_Connect, &hSTMT);
    if (!SQL_SUCCEEDED(ret))    return 0;
    //查询语句确定
    strcpy((char*)query, "SELECT * FROM [");
    strcat((char*)query, pstrSheetname);
    strcat((char*)query, "]");
    //提交查询
    ret = SQLExecDirectA(hSTMT, query, SQL_NTS);
    if (!SQL_SUCCEEDED(ret))
    {
        SQLFreeHandle(SQL_HANDLE_STMT, hSTMT);
        return 0;
    }
    //跳转到指定行
    for (unsigned long i = 1; i < ulItem; i++)//行计数是从1开始的,所以读写第N行是执行(N-1)次跳转.
    {
        ret = SQLFetch(hSTMT);
        if (!SQL_SUCCEEDED(ret))    break;
    }
    //确认跳转是成功的
    if (!SQL_SUCCEEDED(ret))
    {
        SQLFreeHandle(SQL_HANDLE_STMT, hSTMT);
        return 0;
    }
    //尝试读取数据
    ret = SQLGetData(hSTMT, (SQLUSMALLINT)ulColumn, EXCEL_TEXTA, (SQLPOINTER)pstrString, (SQLINTEGER)ulSize, (SQLINTEGER*)&dataLen);
    if (!SQL_SUCCEEDED(ret))
    {
        SQLFreeHandle(SQL_HANDLE_STMT, hSTMT);
        return 0;
    }
    SQLFreeHandle(SQL_HANDLE_STMT, hSTMT);
    return (unsigned short)dataLen;
}
unsigned long clsODBCExcelRead::ReadTextW (wchar_t * pstrSheetname, unsigned long ulColumn, unsigned long ulItem, wchar_t * pstrString, unsigned long ulSize)
{
    SQLHANDLE  hSTMT = NULL;
    SQLWCHAR   query[1024] = { 0 };
    SQLINTEGER dataLen = 0;
    SQLRETURN  ret = 0;
    //分配语句句柄
    ret = SQLAllocHandle(SQL_HANDLE_STMT, chandle_Connect, &hSTMT);
    if (!SQL_SUCCEEDED(ret))    return 0;
    //查询语句确定
    wcscpy((wchar_t*)query, L"SELECT * FROM [");
    wcscat((wchar_t*)query, pstrSheetname);
    wcscat((wchar_t*)query, L"]");
    //提交查询
    ret = SQLExecDirectW(hSTMT, query, SQL_NTS);
    if (!SQL_SUCCEEDED(ret))
    {
        SQLFreeHandle(SQL_HANDLE_STMT, hSTMT);
        return 0;
    }
    //跳转到指定行
    for (unsigned long i = 1; i < ulItem; i++)//行计数是从1开始的,所以读写第N行是执行(N-1)次跳转.
    {
        ret = SQLFetch(hSTMT);
        if (!SQL_SUCCEEDED(ret))    break;
    }
    //确认跳转是成功的
    if (!SQL_SUCCEEDED(ret))
    {
        SQLFreeHandle(SQL_HANDLE_STMT, hSTMT);
        return 0;
    }
    //尝试读取数据
    ret = SQLGetData(hSTMT, (SQLUSMALLINT)ulColumn, EXCEL_TEXTW, (SQLPOINTER)pstrString, (SQLINTEGER)ulSize, (SQLINTEGER*)&dataLen);
    if (!SQL_SUCCEEDED(ret))
    {
        SQLFreeHandle(SQL_HANDLE_STMT, hSTMT);
        return 0;
    }
    SQLFreeHandle(SQL_HANDLE_STMT, hSTMT);
    return (unsigned short)dataLen;
}
//----------------------------------------------------------------------------------------------------clsODBCExcelRead-end
//<cppp-end>

用法大致如下:

clsODBCExcelRead cExcel;

if(false == cExcel.Init() )

{

//驱动加载失败(未安装)

}

if(false == cExcel.OpenA("D:\\123.xlsx"))

{

//打开EXCEL文件失败;

}

unsigned long ulColumn = 0;//列

unsigned long ulItem = 0;//行

unsigned wchar_t strText[1024] = {0};

Excel_SplitNameA("C13",&ulColumn,&ulItem);//合并的单元格编号拆分成列和行

if(false == cExcel.ReadTextW(L"$Sheet1",ulColumn,ulItem,strText, 1024))

{

//读取失败;

}else

{

cout<<"C13"单元格上的内容是:"<<strText<<endl;

}

Excel_SplitNameA("F16",&ulColumn,&ulItem);

if(false == cExcel.ReadTextW(L"$Sheet1",ulColumn,ulItem,strText, 1024))

{

//读取失败;

}else

{

cout<<"F16"单元格上的内容是:"<<strText<<endl;

}

cExcel.Close();//关闭对EXCEL表格文件的访问

//目前,列只能访问到255,行没有限制(除了第1行不能访问)。

//Exel表格不是标准的关系数据库,第一行的内容无法读取,这是硬性限制,无法突破。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值