关于VC++操作Excel表格,内存不释放问题,还请各位帮忙找问题!

时间:2022-09-04 18:42:01
// 打开excel文件函数
bool ExcelEx::OpenExcel(CString sSheetName)
{
COleVariant covTrue((short)TRUE),covFalse((short)FALSE),covOptional((long)DISP_E_PARAMNOTFOUND,   VT_ERROR); 
if (!app.CreateDispatch(_T("Excel.Application")))
{
return false;
}
bCreate=false;   //打开文件则置为false
m_filename=sSheetName;
//获取book容器
books = app.get_Workbooks();
//添加一个book实例
book = books.Open(m_filename, vtMissing, vtMissing, vtMissing, vtMissing, vtMissing, vtMissing, vtMissing, vtMissing, vtMissing, vtMissing, vtMissing, vtMissing, vtMissing, vtMissing);
//获取sheet容器
sheets=book.get_Sheets();
//获取sheet1表格页
sheet = sheets.get_Item(COleVariant((short)1));
//获取当前表格所有区域
range=sheet.get_Cells();
return true;
}


// 根据指定项写入文本
void ExcelEx::WriteData(unsigned long iRow, unsigned long iCol, LPCTSTR pszTex)
{
range.put_Item(_variant_t((unsigned long)(iRow)),_variant_t((unsigned long)(iCol)),
_variant_t(pszTex));
}


// 保存并关闭excel表格
void ExcelEx::Close(void)
{
//释放对象 
//app.put_UserControl(true);
COleVariant covTrue((short)TRUE),covFalse((short)FALSE),covOptional((long)DISP_E_PARAMNOTFOUND,   VT_ERROR); 
range.ReleaseDispatch(); 
sheet.ReleaseDispatch(); 
sheets.ReleaseDispatch(); 
book.Close(covTrue,COleVariant(m_filename),covTrue);
book.ReleaseDispatch(); 
books.Close(); 
books.ReleaseDispatch();
app.Quit();
app.ReleaseDispatch(); 

}


// 创建excel文件
bool ExcelEx::CreateExcel(CString sExcelFile)
{
covOptional = COleVariant((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
if (!app.CreateDispatch(_T("Excel.Application")))
{
return false;
}
m_filename=sExcelFile;
bCreate=true;
//获取book容器
books = app.get_Workbooks();
//添加一个book实例
book = books.Add(covOptional);
//获取sheet容器
sheets=book.get_Sheets();
//获取sheet1表格页
sheet = sheets.get_Item(COleVariant((short)1));
//获取当前表格所有区域
range=sheet.get_Cells();
return true;
}

实际上只使用了打开OpenExcel操作和关闭ExcelEx::Close(void)操作,整个程序内存使用一次就增加几K,这样下去内存很快就没有了,找半天没有解决办法,值知道是这段代码问题?郁闷

8 个解决方案

#1


关于VC++操作Excel表格,内存不释放问题,还请各位帮忙找问题!
帮顶吧,excel操作没接触过.....

#2


有时系统没有及时释放内存,多用一下试试,是不是就少了。

#3


没看出来什么问题。确定把这两个函数调用注释掉,内存就不出现增长了么?

#4


仅供参考
//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


没有看出什么问题来,帮顶    关注 

#6


把打开和保存关闭写到一起函数中试试看

一般对表格操作,数据增加和减少应该在表格中的。

#7


引用 3 楼 happyparrot 的回复:
没看出来什么问题。确定把这两个函数调用注释掉,内存就不出现增长了么?

通过屏蔽代码发现只要app.CreateDispatch(_T("Excel.Application")) 就会使能存增加,Excel对象我是在对话框类中定义的,奇怪了

#8


已经找到问题?app.CreateDispatch(_T("Excel.Application")) 没创建一次,就会在COM服务程序中申请一次内存,这个方法只能放在程序初始化方法中使用一次即可,在退出程序时才释放他即可!

#1


关于VC++操作Excel表格,内存不释放问题,还请各位帮忙找问题!
帮顶吧,excel操作没接触过.....

#2


有时系统没有及时释放内存,多用一下试试,是不是就少了。

#3


没看出来什么问题。确定把这两个函数调用注释掉,内存就不出现增长了么?

#4


仅供参考
//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


没有看出什么问题来,帮顶    关注 

#6


把打开和保存关闭写到一起函数中试试看

一般对表格操作,数据增加和减少应该在表格中的。

#7


引用 3 楼 happyparrot 的回复:
没看出来什么问题。确定把这两个函数调用注释掉,内存就不出现增长了么?

通过屏蔽代码发现只要app.CreateDispatch(_T("Excel.Application")) 就会使能存增加,Excel对象我是在对话框类中定义的,奇怪了

#8


已经找到问题?app.CreateDispatch(_T("Excel.Application")) 没创建一次,就会在COM服务程序中申请一次内存,这个方法只能放在程序初始化方法中使用一次即可,在退出程序时才释放他即可!