woaidongmao

文章均收录自他人博客,但不喜标题前加-[转贴],因其丑陋,见谅!~
随笔 - 1469, 文章 - 0, 评论 - 661, 引用 - 0
数据加载中……

VC中操作excel表格

http://blog.csdn.net/callmeback/archive/2009/02/18/3906310.aspx

 

操作系统是Microsoft XP,办公套装是Microsoft Office 2003,编程环境是Microsoft Visual Studio 6.0,一切都是Microsoft

 

我最近要将数据库中的内容查询出来放到excel表格以便打印,所以上网找了这方面的内容,这里主要是抛砖引玉。

 

从思路上来看,操作excel表格就是将其打开,然后写入/读出数据,然后关闭。

 

首先创建一个程序(我的例子是一个MFC的单文档程序),在程序的入口处和出口处先作这样两个步骤来支持COM库:

 

在程序入口处CXXXApp:: InitInstance()函数AfxEnableControlContainer();语句之后加入下面几行:

 

if (CoInitialize(NULL) != 0)

 

{

 

       AfxMessageBox(“初始化COM支持库失败!);

 

       exit(1);

 

}

 

假如这个条件不通过就不能运行起程序。

 

在程序的出口处CXXXApp:: ExitInstance()函数return语句之前加入下面这句话:CoUninitialize();来释放COM支持库。

 

这样对COM支持库的代码已经完成。

 

下面要从Office的安装目录中找到对VC操作excel文件的动态库,在某些版本下这个文件是Excel8.olb或者Excel9.olb,在我的版本中是excel.exe这个exe也是动态库的形式,是微软公司主要的文件结果之一。选择vcView菜单里面的ClassWizad命令,会弹出一个对话框;然后点击Add Class…按钮选择From a type library,会弹出一个打开对话框,从这里打开Office安装目录下…\Office11\EXCEL.EXE文件,从里面选择几个要用到的类:_Application, Workbooks, _Wrokbook, Worksheets, _WorkSheet, Range,点击OK按钮。会在程序中生成一个excel.hexcel.cpp文件,这些文件中包含了刚才我们选择的几个类的代码。下面介绍一下这几个类:

 

vc操纵excelexe动态库里面有好多个对象模型,就是刚才在创建过程中看到的那个列表,但是经常用到的有这么几个:_Application, Workbooks, _Wrokbook, Worksheets, _WorkSheet, RangeCharts_Chart,最后面的两个是用来操作图表的,我没有用到所以这里也就不记录了。

 

_Application:这里的Application就是Excel本身,众所周知,一个Excel可以包含多个工作簿,每个工作簿又可以包含多个工作表,而每个工作表又可以包含多个区域或者图表,所以这里他们是树型的结构关系,而application最基本的一个功能就是找到它的子项工作簿。果然,我们在引入我们程序的Application类中看到了这样的成员函数:GetWorkbooks()。既然application就是excel,那么打开程序,退出程序,显示/隐藏程序这些基本的操作都可以在这个类的成员函数中找到,果不其然。

 

Workbooks:这个对象是一个容器对象,它里面存放着所有打开的工作簿。因此,我们可以猜测它一定有添加,查找,打开/关闭工作簿的功能。(本程序中使用excel的一个xlt模板来生成一个xls文件就是使用了这个容器对象的添加功能。)

 

_Workbook:这是一个工作簿,也就相当于一个xls文件。Excel可以同时打开多个工作簿,所以工作簿之间必定能够互相切换,每个工作簿可以关联工作表容器并获得工作表的索引。

 

Worksheets:也是一个容器对象,和Workbooks类似。

 

_Worksheet:这个就是我们看到的工作表,比如Sheet1sheet2等等。

 

Rang:就是我们看到的能选中的方框的大小。而我们所要作的操作基本上是以区域为单位进行的。

 

 

 

介绍完这些,就添加一个菜单,来响应操作excel的命令。

 

然后下面附带这个函数的内容,注释还算可以吧,并且附上网上不知道谁写的但是转载极多的一个封装类。

 

view plaincopy to clipboardprint?

_Application _app;  

_Workbook _workBook;  

_Worksheet _workSheet;  

Worksheets workSheets;  

Workbooks workBooks;  

Range range;  

Range copyFrom;  

Range copyTo;  

 

if(!_app.CreateDispatch("Excel.Application", NULL))  

{  

    MessageBox("创建Excel服务失败!", "信息提示", MB_OK);  

    return;  

}  

//利用模板建立新文档  

workBooks.AttachDispatch(_app.GetWorkbooks());  

_workBook.AttachDispatch(workBooks.Add(_variant_t("\"C:\\Documents and Settings\\模板.xlt\"")));//你可以自己创建一个模板,并自由设定目录  

//得到worksheets  

workSheets.AttachDispatch(_workBook.GetWorksheets());  

//得到workSheet  

_workSheet.AttachDispatch(workSheets.GetItem(_variant_t("sheet1")));  

//得到拷贝的母板  

copyFrom.AttachDispatch(_workSheet.GetRange(_variant_t("A3"), _variant_t("Q6")));  

copyTo.AttachDispatch(_workSheet.GetRange(_variant_t("A61"), _variant_t("A61")));  

//得到全部的cells  

range.AttachDispatch(_workSheet.GetCells());  

 

///////////////////////////////////////////////////////////////////////////////////////////////////  

// 上边是头  

 

/* 

中间要做的工作有这两项:设置数据和拷贝格式 

设置数据就是将数据库中查询出来的数据写入表格,拷贝格式就是将表格拷贝到别的地方。 

*/ 

//写入数据  

range.SetItem(_variant_t((long)3), _variant_t((long)1), _variant_t("写入数据了"));  

range.SetItem(_variant_t((long)5), _variant_t((long)1), _variant_t("重新写入数据了"));  

//拷贝一段区域到另外的一段区域  

copyFrom.Copy(_variant_t(copyTo));  

range.SetItem(_variant_t((long)61), _variant_t((long)1), _variant_t("123"));  

 

//显示excel表格  

    _app.SetVisible(TRUE);  

//保存为文件  

_app.SetDisplayAlerts(FALSE);   //隐藏弹出的对话框  

_workSheet.SaveAs("d:\\Test.xls",vtMissing,vtMissing,vtMissing,vtMissing,  

    vtMissing,vtMissing,vtMissing,vtMissing,vtMissing);  

_app.Quit();  

//下边是尾  

///////////////////////////////////////////////////////////////////////////////////////////////////  

copyFrom.ReleaseDispatch();  

copyTo.ReleaseDispatch();  

range.ReleaseDispatch();  

_workSheet.ReleaseDispatch();  

workSheets.ReleaseDispatch();  

_workBook.ReleaseDispatch();  

workSheets.ReleaseDispatch();  

_app.ReleaseDispatch(); 

    _Application _app;

    _Workbook _workBook;

    _Worksheet _workSheet;

    Worksheets workSheets;

    Workbooks workBooks;

    Range range;

    Range copyFrom;

    Range copyTo;

   

    if(!_app.CreateDispatch("Excel.Application", NULL))

    {

       MessageBox("创建Excel服务失败!", "信息提示", MB_OK);

       return;

    }

    //利用模板建立新文档

    workBooks.AttachDispatch(_app.GetWorkbooks());

    _workBook.AttachDispatch(workBooks.Add(_variant_t("\"C:\\Documents and Settings\\模板.xlt\"")));//你可以自己创建一个模板,并自由设定目录

    //得到worksheets

    workSheets.AttachDispatch(_workBook.GetWorksheets());

    //得到workSheet

    _workSheet.AttachDispatch(workSheets.GetItem(_variant_t("sheet1")));

    //得到拷贝的母板

    copyFrom.AttachDispatch(_workSheet.GetRange(_variant_t("A3"), _variant_t("Q6")));

    copyTo.AttachDispatch(_workSheet.GetRange(_variant_t("A61"), _variant_t("A61")));

    //得到全部的cells

    range.AttachDispatch(_workSheet.GetCells());

   

    ///////////////////////////////////////////////////////////////////////////////////////////////////

    // 上边是头

   

    /*

    中间要做的工作有这两项:设置数据和拷贝格式

    设置数据就是将数据库中查询出来的数据写入表格,拷贝格式就是将表格拷贝到别的地方。

    */

    //写入数据

    range.SetItem(_variant_t((long)3), _variant_t((long)1), _variant_t("写入数据了"));

    range.SetItem(_variant_t((long)5), _variant_t((long)1), _variant_t("重新写入数据了"));

    //拷贝一段区域到另外的一段区域

    copyFrom.Copy(_variant_t(copyTo));

    range.SetItem(_variant_t((long)61), _variant_t((long)1), _variant_t("123"));

   

    //显示excel表格

       _app.SetVisible(TRUE);

    //保存为文件

    _app.SetDisplayAlerts(FALSE);   //隐藏弹出的对话框

    _workSheet.SaveAs("d:\\Test.xls",vtMissing,vtMissing,vtMissing,vtMissing,

       vtMissing,vtMissing,vtMissing,vtMissing,vtMissing);

    _app.Quit();

    //下边是尾

    ///////////////////////////////////////////////////////////////////////////////////////////////////

    copyFrom.ReleaseDispatch();

    copyTo.ReleaseDispatch();

    range.ReleaseDispatch();

    _workSheet.ReleaseDispatch();

    workSheets.ReleaseDispatch();

    _workBook.ReleaseDispatch();

    workSheets.ReleaseDispatch();

    _app.ReleaseDispatch();

 

 

 

别人的代码:

 

 

view plaincopy to clipboardprint?

.h文件: 

#include "comdef.h"  

#include "excel.h"  

class ExcelFile   

{  

public:  

void ShowInExcel(bool bShow);  

CString GetCell(int iRow, int iColumn);  

int     GetCellInt(int iRow, int iColumn);  

int GetRowCount();  

int GetColumnCount();  

bool LoadSheet(int iIndex);  

CString GetSheetName(int iIndex);  

static void InitExcel();  

static void ReleaseExcel();  

int GetSheetCount();  

bool Open(CString FileName);  

ExcelFile();  

virtual ~ExcelFile();  

protected:  

private:  

static _Application m_ExcelApp;  

 

Workbooks    m_Books;   

_Workbook    m_Book;   

Worksheets   m_sheets;   

_Worksheet   m_sheet;   

Range        m_Rge;   

};  

.cpp文件:  

ExcelFile::ExcelFile()  

{  

}  

ExcelFile::~ExcelFile()  

{  

m_Rge.ReleaseDispatch();   

m_sheet.ReleaseDispatch();   

m_sheets.ReleaseDispatch();   

m_Book.ReleaseDispatch();   

m_Books.ReleaseDispatch();   

}  

void ExcelFile::InitExcel()  

{  

//创建Excel 2000服务器(启动Excel)   

if (!m_ExcelApp.CreateDispatch("Excel.Application",NULL))   

{   

AfxMessageBox("创建Excel服务失败!");   

exit(1);   

}   

}  

void ExcelFile::ReleaseExcel()  

{  

m_ExcelApp.ReleaseDispatch();  

}  

bool ExcelFile::Open(CString FileName)  

{  

//打开excel文件  

//利用模板文件建立新文档   

m_Books.AttachDispatch(m_ExcelApp.GetWorkbooks(),true);   

LPDISPATCH lpDis = NULL;  

lpDis = m_Books.Add(_variant_t(FileName)); // 如何判断文件是否打开?  

if (lpDis)  

{  

m_Book.AttachDispatch(lpDis);   

//得到Worksheets   

m_sheets.AttachDispatch(m_Book.GetWorksheets(),true);   

return true;  

}  

return false;  

}  

int ExcelFile::GetSheetCount()  

{  

return m_sheets.GetCount();  

}  

CString ExcelFile::GetSheetName(int iIndex)  

{  

_Worksheet sheet;  

sheet.AttachDispatch(m_sheets.GetItem(_variant_t((long)iIndex)),true);  

CString name = sheet.GetName();  

sheet.ReleaseDispatch();  

return name;  

}  

bool ExcelFile::LoadSheet(int iIndex)  

{  

LPDISPATCH lpDis = NULL;  

m_Rge.ReleaseDispatch();  

m_sheet.ReleaseDispatch();  

lpDis = m_sheets.GetItem(_variant_t((long)iIndex));  

if (lpDis)  

{  

        m_sheet.AttachDispatch(lpDis,true);  

        m_Rge.AttachDispatch(m_sheet.GetCells(), true);  

        return true;  

}  

return false;  

}  

int ExcelFile::GetColumnCount()  

{  

Range range;  

Range usedRange;  

usedRange.AttachDispatch(m_sheet.GetUsedRange(), true);  

range.AttachDispatch(usedRange.GetColumns(), true);  

int count = range.GetCount();  

usedRange.ReleaseDispatch();  

range.ReleaseDispatch();  

return count;  

}  

int ExcelFile::GetRowCount()  

{  

Range range;  

Range usedRange;  

usedRange.AttachDispatch(m_sheet.GetUsedRange(), true);  

range.AttachDispatch(usedRange.GetRows(), true);  

int count = range.GetCount();  

usedRange.ReleaseDispatch();  

range.ReleaseDispatch();  

return count;  

}  

CString ExcelFile::GetCell(int iRow, int iColumn)  

{  

Range range;  

range.AttachDispatch(m_Rge.GetItem (COleVariant((long)iRow),COleVariant((long)iColumn)).pdispVal, true);  

    COleVariant vResult =range.GetValue2();  

CString str;  

if(vResult.vt == VT_BSTR)       //字符串  

{  

str=vResult.bstrVal;  

}  

else if (vResult.vt==VT_INT)  

{  

        str.Format("%d",vResult.pintVal);  

}  

else if (vResult.vt==VT_R8)     //8字节的数字   

{  

str.Format("%f",vResult.dblVal);  

//str.Format("%.0f",vResult.dblVal);  

//str.Format("%1f",vResult.fltVal);  

}  

else if(vResult.vt==VT_DATE)    //时间格式  

{  

SYSTEMTIME st;  

VariantTimeToSystemTime(vResult.date, &st);  

}  

else if(vResult.vt==VT_EMPTY)   //单元格空的  

{  

    str="(NULL)";  

}   

range.ReleaseDispatch();  

return str;  

}  

int ExcelFile::GetCellInt(int iRow, int iColumn)  

{  

Range range;  

range.AttachDispatch(m_Rge.GetItem(COleVariant((long)iRow),COleVariant((long)iColumn)).pdispVal, true);  

COleVariant vResult =range.GetValue2();  

int num;  

num = (int)vResult.date;  

range.ReleaseDispatch();  

return num;  

}  

void ExcelFile::ShowInExcel(bool bShow)  

{  

m_ExcelApp.SetVisible(bShow);  

} 

 

 

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/callmeback/archive/2009/02/18/3906310.aspx

posted on 2011-02-28 15:06 肥仔 阅读(3813) 评论(0)  编辑 收藏 引用 所属分类: Windows开发


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理