求共享------C++读写Excel表格

时间:2022-05-19 11:39:16
excel c++ ado

18 个解决方案

#1


先安装MDAC28

#2


不过个人建议在Excel另存为.csv(半角逗号间隔列,回车换行间隔行的纯文本格式),然后用C++读取该.csv文件。

#3


引用 2 楼 zhao4zhong1 的回复:
不过个人建议在Excel另存为.csv(半角逗号间隔列,回车换行间隔行的纯文本格式),然后用C++读取该.csv文件。


赵老师,c++读取Excel已经很成熟了吧,应该有人将其封成可用的类了吧,能不能直接给个封装好的类用呀?

#4


引用 3 楼 huoqingna2332 的回复:
Quote: 引用 2 楼 zhao4zhong1 的回复:

不过个人建议在Excel另存为.csv(半角逗号间隔列,回车换行间隔行的纯文本格式),然后用C++读取该.csv文件。


赵老师,c++读取Excel已经很成熟了吧,应该有人将其封成可用的类了吧,能不能直接给个封装好的类用呀?

至少我没用过。
在Excel 2003中开始记录宏,手动完成所需功能,结束记录宏,按Alt+F11键,查看刚才记录的宏对应的VBA代码。
参考下面:
//1.在VC中新建一控制台程序,选支持MFC(当然,你也可以不选择支持MFC的,不过会很麻烦)
//2.按CTRL+W调出MFC ClassWizard,Add Class->From a type library,选择你的word的类型库
//  (例如我的是word2003,安装在e盘,我的路径是"e:\edittools\microsoft office\office11\msword.olb"),
//  选择完毕后,在弹出的窗口中选择要让classwizard生成的包装类,在本例中要用到
//  _Application,
//  Documents,
//  _Document,
//  Range
//  这四个类,选中他们后按OK
//3.进入你的main函数所在的cpp文件,加入头文件引用
//  #include  "msword.h"    //引用刚才classwizard生成的idispatch包装类
//4.加入代码
// console_word.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "console_word.h"
#include "msword.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// The one and only application object

CWinApp theApp;

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
    int nRetCode = 0;

    // initialize MFC and print and error on failure
    if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
    {
        // TODO: change error code to suit your needs
        printf(_T("Fatal Error: MFC initialization failed!\n"));
        nRetCode = 1;
    }
    else
    {
        // TODO: code your application's behavior here.
        if  (CoInitialize(NULL)  !=  S_OK)
        {
            AfxMessageBox("初始化COM支持库失败!");
            return  -1;
        }

        _Application  wordApp;
        Documents     docs;
        _Document     doc;
        Range         aRange;
        COleVariant   vTrue((short)TRUE), vFalse((short)FALSE), vOpt((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
        CString       txt;

        wordApp.CreateDispatch("Word.Application",NULL);
        wordApp.SetVisible(FALSE);
            docs=wordApp.GetDocuments();
                doc=docs.Open(COleVariant("c:\\new\\测试.doc"),vFalse,vTrue,vFalse,vOpt,vOpt,vOpt,vOpt,vOpt,vOpt,vOpt,vOpt,vOpt,vOpt,vOpt,vOpt);
                    aRange=doc.Range(vOpt,vOpt);
                        txt=aRange.GetText();
                        AfxMessageBox(txt);//这里GetText得到的就是word文件的纯文本了,你可以将其写到txt文件中
                        printf("[%s]\n",txt.GetBuffer(txt.GetLength()));//里面的换行不是\r\n而是\r,所以需要输出重定向到文本文件看结果。
                    aRange.ReleaseDispatch();
                doc.Close(vOpt,vOpt,vOpt);
                doc.ReleaseDispatch();
            docs.ReleaseDispatch();
        wordApp.Quit(vOpt,vOpt,vOpt);
        wordApp.ReleaseDispatch();

        CoUninitialize();
    }

    return nRetCode;
}



#5


引用 4 楼 zhao4zhong1 的回复:
Quote: 引用 3 楼 huoqingna2332 的回复:

Quote: 引用 2 楼 zhao4zhong1 的回复:

不过个人建议在Excel另存为.csv(半角逗号间隔列,回车换行间隔行的纯文本格式),然后用C++读取该.csv文件。


赵老师,c++读取Excel已经很成熟了吧,应该有人将其封成可用的类了吧,能不能直接给个封装好的类用呀?

至少我没用过。
在Excel 2003中开始记录宏,手动完成所需功能,结束记录宏,按Alt+F11键,查看刚才记录的宏对应的VBA代码。
参考下面:
//1.在VC中新建一控制台程序,选支持MFC(当然,你也可以不选择支持MFC的,不过会很麻烦)





谢谢 赵老师!
我自己再研究一下。

#6


获取表中的数据保存到question数组
CString Clogin::GetExcelDriver()
{
char szBuf[2001];
    WORD cbBufMax = 2000;
    WORD cbBufOut;
    char *pszBuf = szBuf;
    CString sDriver;
    // 获取已安装驱动的名称(涵数在odbcinst.h里)
if (!SQLGetInstalledDrivers(szBuf, cbBufMax, &cbBufOut))
return "";
    
    // 检索已安装的驱动是否有Excel...
    do
    {
        if (strstr(pszBuf, "Excel") != 0)
        {
            //发现 !
            sDriver = CString(pszBuf);
            break;
        }
        pszBuf = strchr(pszBuf, '\0') + 1;
    }
    while (pszBuf[1] != '\0');
    return sDriver;
}
void Clogin::GetUseinf(CString question[100][11])
{
   CDatabase database;
    CString sSql;
    CString sItem1, sItem2,sItem3,sItem4,sItem5,sItem6,sItem7,sItem8;
    CString sDriver;
    CString sDsn;
    CString sFile,sPath;

GetModuleFileName(NULL,sPath.GetBufferSetLength (MAX_PATH+1),MAX_PATH);
sPath.ReleaseBuffer ();
int nPos;
nPos=sPath.ReverseFind ('\\');
sPath=sPath.Left (nPos);
sFile = sPath+"\\user.xls";
//CExcel *ep=new CExcel;
sDriver = GetExcelDriver();

if (sDriver.IsEmpty())
    {
        // 没有发现Excel驱动
        AfxMessageBox("没有安装Excel驱动!");
return;
}
    
    // 创建进行存取的字符串
    sDsn.Format("ODBC;DRIVER={%s};DSN='' '';DBQ=%s", sDriver, sFile);

        // 打开数据库(既Excel文件)
        database.Open(NULL, false, false, sDsn);
        
        CRecordset recset(&database);
        // 设置读取的查询语句.



sSql= "select 用户名,密码" //设置索引顺序     
" from [sheet1$]" ; 


int i=0;
        // 执行查询语句
        recset.Open(CRecordset::forwardOnly, sSql, CRecordset::readOnly);
        // 获取查询结果
        while (!recset.IsEOF())
        {  
recset.GetFieldValue("用户名", question[i][0]);
recset.GetFieldValue("密码", question[i][1]);
i++;
recset.MoveNext();
        // 关闭数据库
}
}

实现部分调用GetUseinf(question);即可

#7


忘记加头文件
#include <afxdb.h>//定义CDatabase需要用到
#include "odbcinst.h"//定义getexceldriver需用到

#8


好像不支持新格式 前段时间我们用qt写的时候试了好几个库,最后才有一个好用的 odbc以及原生的都试过,都有各种各样的问题

#9


引用 7 楼 u010101009 的回复:
忘记加头文件
#include <afxdb.h>//定义CDatabase需要用到
#include "odbcinst.h"//定义getexceldriver需用到


谢谢。
我自己再研究一下。

#10


引用 8 楼 sniffer12345 的回复:
好像不支持新格式 前段时间我们用qt写的时候试了好几个库,最后才有一个好用的 odbc以及原生的都试过,都有各种各样的问题


确实,用什么方法都有各种问题。
而且编译环境不一样,导致的问题也很多,真让人头疼。
我现在在用ADO的方式调试,先满足功能吧,性能方面等测试根据具体情况而定吧。

#11


正因为“用什么方法都有各种问题”
所以要参考2楼的方法。
2楼的方法虽然也会有问题,但至少问题在哪里容易看出来。

#12


百度,谷歌关键字  BasicExcel.cpp

#13


引用 11 楼 zhao4zhong1 的回复:
正因为“用什么方法都有各种问题”
所以要参考2楼的方法。
2楼的方法虽然也会有问题,但至少问题在哪里容易看出来。


赵老师,关键是Excel中你不知道本身内容是否含有 半角逗号或者回车 ,这个转文件明显不行,呵呵,至少在我这个项目中不可取。

#14


引用 12 楼 henry3695 的回复:
百度,谷歌关键字  BasicExcel.cpp


BasicExcel这个方式我基本不准备采用,谢谢!

#15


引用 13 楼 huoqingna2332 的回复:
Quote: 引用 11 楼 zhao4zhong1 的回复:

正因为“用什么方法都有各种问题”
所以要参考2楼的方法。
2楼的方法虽然也会有问题,但至少问题在哪里容易看出来。


赵老师,关键是Excel中你不知道本身内容是否含有 半角逗号或者回车 ,这个转文件明显不行,呵呵,至少在我这个项目中不可取。

你不会先在Excel中将所有半角逗号先替换为全角逗号,所有回车先替换为↙吗?

#16


office安装目录下就有com接口
你在vs下Add Class--MFC--导入类型库,选择com接口文件,生成接口类。
具体com文件请自行百度;


#17


引用 15 楼 zhao4zhong1 的回复:
Quote: 引用 13 楼 huoqingna2332 的回复:

Quote: 引用 11 楼 zhao4zhong1 的回复:

正因为“用什么方法都有各种问题”
所以要参考2楼的方法。
2楼的方法虽然也会有问题,但至少问题在哪里容易看出来。


赵老师,关键是Excel中你不知道本身内容是否含有 半角逗号或者回车 ,这个转文件明显不行,呵呵,至少在我这个项目中不可取。

你不会先在Excel中将所有半角逗号先替换为全角逗号,所有回车先替换为↙吗?

那如果原来excel中就有全角的逗号呢?!
你无论如何替换,都不能保证 起到 分割元素 的符号 在原来的excel内容中就没有!

#18


引用 16 楼 jianwen0529 的回复:
office安装目录下就有com接口
你在vs下Add Class--MFC--导入类型库,选择com接口文件,生成接口类。
具体com文件请自行百度;


谢谢 ,我已经可以使用ADO的方式读写Excel了。

#1


先安装MDAC28

#2


不过个人建议在Excel另存为.csv(半角逗号间隔列,回车换行间隔行的纯文本格式),然后用C++读取该.csv文件。

#3


引用 2 楼 zhao4zhong1 的回复:
不过个人建议在Excel另存为.csv(半角逗号间隔列,回车换行间隔行的纯文本格式),然后用C++读取该.csv文件。


赵老师,c++读取Excel已经很成熟了吧,应该有人将其封成可用的类了吧,能不能直接给个封装好的类用呀?

#4


引用 3 楼 huoqingna2332 的回复:
Quote: 引用 2 楼 zhao4zhong1 的回复:

不过个人建议在Excel另存为.csv(半角逗号间隔列,回车换行间隔行的纯文本格式),然后用C++读取该.csv文件。


赵老师,c++读取Excel已经很成熟了吧,应该有人将其封成可用的类了吧,能不能直接给个封装好的类用呀?

至少我没用过。
在Excel 2003中开始记录宏,手动完成所需功能,结束记录宏,按Alt+F11键,查看刚才记录的宏对应的VBA代码。
参考下面:
//1.在VC中新建一控制台程序,选支持MFC(当然,你也可以不选择支持MFC的,不过会很麻烦)
//2.按CTRL+W调出MFC ClassWizard,Add Class->From a type library,选择你的word的类型库
//  (例如我的是word2003,安装在e盘,我的路径是"e:\edittools\microsoft office\office11\msword.olb"),
//  选择完毕后,在弹出的窗口中选择要让classwizard生成的包装类,在本例中要用到
//  _Application,
//  Documents,
//  _Document,
//  Range
//  这四个类,选中他们后按OK
//3.进入你的main函数所在的cpp文件,加入头文件引用
//  #include  "msword.h"    //引用刚才classwizard生成的idispatch包装类
//4.加入代码
// console_word.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "console_word.h"
#include "msword.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// The one and only application object

CWinApp theApp;

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
    int nRetCode = 0;

    // initialize MFC and print and error on failure
    if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
    {
        // TODO: change error code to suit your needs
        printf(_T("Fatal Error: MFC initialization failed!\n"));
        nRetCode = 1;
    }
    else
    {
        // TODO: code your application's behavior here.
        if  (CoInitialize(NULL)  !=  S_OK)
        {
            AfxMessageBox("初始化COM支持库失败!");
            return  -1;
        }

        _Application  wordApp;
        Documents     docs;
        _Document     doc;
        Range         aRange;
        COleVariant   vTrue((short)TRUE), vFalse((short)FALSE), vOpt((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
        CString       txt;

        wordApp.CreateDispatch("Word.Application",NULL);
        wordApp.SetVisible(FALSE);
            docs=wordApp.GetDocuments();
                doc=docs.Open(COleVariant("c:\\new\\测试.doc"),vFalse,vTrue,vFalse,vOpt,vOpt,vOpt,vOpt,vOpt,vOpt,vOpt,vOpt,vOpt,vOpt,vOpt,vOpt);
                    aRange=doc.Range(vOpt,vOpt);
                        txt=aRange.GetText();
                        AfxMessageBox(txt);//这里GetText得到的就是word文件的纯文本了,你可以将其写到txt文件中
                        printf("[%s]\n",txt.GetBuffer(txt.GetLength()));//里面的换行不是\r\n而是\r,所以需要输出重定向到文本文件看结果。
                    aRange.ReleaseDispatch();
                doc.Close(vOpt,vOpt,vOpt);
                doc.ReleaseDispatch();
            docs.ReleaseDispatch();
        wordApp.Quit(vOpt,vOpt,vOpt);
        wordApp.ReleaseDispatch();

        CoUninitialize();
    }

    return nRetCode;
}



#5


引用 4 楼 zhao4zhong1 的回复:
Quote: 引用 3 楼 huoqingna2332 的回复:

Quote: 引用 2 楼 zhao4zhong1 的回复:

不过个人建议在Excel另存为.csv(半角逗号间隔列,回车换行间隔行的纯文本格式),然后用C++读取该.csv文件。


赵老师,c++读取Excel已经很成熟了吧,应该有人将其封成可用的类了吧,能不能直接给个封装好的类用呀?

至少我没用过。
在Excel 2003中开始记录宏,手动完成所需功能,结束记录宏,按Alt+F11键,查看刚才记录的宏对应的VBA代码。
参考下面:
//1.在VC中新建一控制台程序,选支持MFC(当然,你也可以不选择支持MFC的,不过会很麻烦)





谢谢 赵老师!
我自己再研究一下。

#6


获取表中的数据保存到question数组
CString Clogin::GetExcelDriver()
{
char szBuf[2001];
    WORD cbBufMax = 2000;
    WORD cbBufOut;
    char *pszBuf = szBuf;
    CString sDriver;
    // 获取已安装驱动的名称(涵数在odbcinst.h里)
if (!SQLGetInstalledDrivers(szBuf, cbBufMax, &cbBufOut))
return "";
    
    // 检索已安装的驱动是否有Excel...
    do
    {
        if (strstr(pszBuf, "Excel") != 0)
        {
            //发现 !
            sDriver = CString(pszBuf);
            break;
        }
        pszBuf = strchr(pszBuf, '\0') + 1;
    }
    while (pszBuf[1] != '\0');
    return sDriver;
}
void Clogin::GetUseinf(CString question[100][11])
{
   CDatabase database;
    CString sSql;
    CString sItem1, sItem2,sItem3,sItem4,sItem5,sItem6,sItem7,sItem8;
    CString sDriver;
    CString sDsn;
    CString sFile,sPath;

GetModuleFileName(NULL,sPath.GetBufferSetLength (MAX_PATH+1),MAX_PATH);
sPath.ReleaseBuffer ();
int nPos;
nPos=sPath.ReverseFind ('\\');
sPath=sPath.Left (nPos);
sFile = sPath+"\\user.xls";
//CExcel *ep=new CExcel;
sDriver = GetExcelDriver();

if (sDriver.IsEmpty())
    {
        // 没有发现Excel驱动
        AfxMessageBox("没有安装Excel驱动!");
return;
}
    
    // 创建进行存取的字符串
    sDsn.Format("ODBC;DRIVER={%s};DSN='' '';DBQ=%s", sDriver, sFile);

        // 打开数据库(既Excel文件)
        database.Open(NULL, false, false, sDsn);
        
        CRecordset recset(&database);
        // 设置读取的查询语句.



sSql= "select 用户名,密码" //设置索引顺序     
" from [sheet1$]" ; 


int i=0;
        // 执行查询语句
        recset.Open(CRecordset::forwardOnly, sSql, CRecordset::readOnly);
        // 获取查询结果
        while (!recset.IsEOF())
        {  
recset.GetFieldValue("用户名", question[i][0]);
recset.GetFieldValue("密码", question[i][1]);
i++;
recset.MoveNext();
        // 关闭数据库
}
}

实现部分调用GetUseinf(question);即可

#7


忘记加头文件
#include <afxdb.h>//定义CDatabase需要用到
#include "odbcinst.h"//定义getexceldriver需用到

#8


好像不支持新格式 前段时间我们用qt写的时候试了好几个库,最后才有一个好用的 odbc以及原生的都试过,都有各种各样的问题

#9


引用 7 楼 u010101009 的回复:
忘记加头文件
#include <afxdb.h>//定义CDatabase需要用到
#include "odbcinst.h"//定义getexceldriver需用到


谢谢。
我自己再研究一下。

#10


引用 8 楼 sniffer12345 的回复:
好像不支持新格式 前段时间我们用qt写的时候试了好几个库,最后才有一个好用的 odbc以及原生的都试过,都有各种各样的问题


确实,用什么方法都有各种问题。
而且编译环境不一样,导致的问题也很多,真让人头疼。
我现在在用ADO的方式调试,先满足功能吧,性能方面等测试根据具体情况而定吧。

#11


正因为“用什么方法都有各种问题”
所以要参考2楼的方法。
2楼的方法虽然也会有问题,但至少问题在哪里容易看出来。

#12


百度,谷歌关键字  BasicExcel.cpp

#13


引用 11 楼 zhao4zhong1 的回复:
正因为“用什么方法都有各种问题”
所以要参考2楼的方法。
2楼的方法虽然也会有问题,但至少问题在哪里容易看出来。


赵老师,关键是Excel中你不知道本身内容是否含有 半角逗号或者回车 ,这个转文件明显不行,呵呵,至少在我这个项目中不可取。

#14


引用 12 楼 henry3695 的回复:
百度,谷歌关键字  BasicExcel.cpp


BasicExcel这个方式我基本不准备采用,谢谢!

#15


引用 13 楼 huoqingna2332 的回复:
Quote: 引用 11 楼 zhao4zhong1 的回复:

正因为“用什么方法都有各种问题”
所以要参考2楼的方法。
2楼的方法虽然也会有问题,但至少问题在哪里容易看出来。


赵老师,关键是Excel中你不知道本身内容是否含有 半角逗号或者回车 ,这个转文件明显不行,呵呵,至少在我这个项目中不可取。

你不会先在Excel中将所有半角逗号先替换为全角逗号,所有回车先替换为↙吗?

#16


office安装目录下就有com接口
你在vs下Add Class--MFC--导入类型库,选择com接口文件,生成接口类。
具体com文件请自行百度;


#17


引用 15 楼 zhao4zhong1 的回复:
Quote: 引用 13 楼 huoqingna2332 的回复:

Quote: 引用 11 楼 zhao4zhong1 的回复:

正因为“用什么方法都有各种问题”
所以要参考2楼的方法。
2楼的方法虽然也会有问题,但至少问题在哪里容易看出来。


赵老师,关键是Excel中你不知道本身内容是否含有 半角逗号或者回车 ,这个转文件明显不行,呵呵,至少在我这个项目中不可取。

你不会先在Excel中将所有半角逗号先替换为全角逗号,所有回车先替换为↙吗?

那如果原来excel中就有全角的逗号呢?!
你无论如何替换,都不能保证 起到 分割元素 的符号 在原来的excel内容中就没有!

#18


引用 16 楼 jianwen0529 的回复:
office安装目录下就有com接口
你在vs下Add Class--MFC--导入类型库,选择com接口文件,生成接口类。
具体com文件请自行百度;


谢谢 ,我已经可以使用ADO的方式读写Excel了。