分享

两种VC操纵EXCEL的方法

 苏梅家家 2009-09-17
第一种方法,简单的,用CDatabase实现. 程序是一个基于对话框的,步骤:    A,为了避免代码重复,设置下面几个全局变量(类范围的),要引入头文件<afxdb.h>
              CDatabase m_db;                     //数据库
             CString m_dbdriver;                 //要生成的EXCEL文件的目录
             char m_path[MAX_PATH];       //获取路径用的数组
               CString m_strdir;                      //包括EXCEL文件名在内的路径名.
               CString m_strsql;                    //SQL命令语句,用m_db可直接执行.
B,在OnInitDialog方法中,生成一个xls文件,并插入两条记录,可在TRY语句中进行,因为这里面要创建一张表,当再次启动程序时,会有异常发生,说表已经存在了,这时就避免了重复创建和插入.代码如下:
m_dbdriver="MICROSOFT EXCEL DRIVER (*.XLS)";
GetCurrentDirectory(MAX_PATH,m_path);
m_strdir=m_path;
m_strdir+="//test.xls";             //上面初始化各个变量.
m_strsql.Format("DRIVER={%s};DSN='''';FIRSTROWHASNAMES=1;READONLY=FALSE;CREATE_DB=\"%s\";DBQ=%s",m_dbdriver,m_strdir,m_strdir);
TRY
{
  if (m_db.OpenEx(m_strsql,CDatabase::noOdbcDialog))
  {
   m_strsql="Create Table OdbcExl(Name Text,Age Number,Gener Text)";
   m_db.ExecuteSQL(m_strsql);
   m_strsql="Insert Into OdbcExl(Name,Age,Gener) Values('Bob',34,'Male')";
   m_db.ExecuteSQL(m_strsql);
   m_strsql="Insert Into OdbcExl(Name,Age,Gener) Values('Jane',23,'Female')";
   m_db.ExecuteSQL(m_strsql);
   m_db.Close();
  }

}
CATCH_ALL(e)
{
// e->ReportError();
  m_db.Close();
  return FALSE;
}
END_CATCH_ALL;
C,其实上面已经达到了答题人的要求,但作为一个程序,这也太不像话了,于是我又稍微加了点不值一提的东西,在对话框上输入信息,再插入到EXCEL表中去,这一切都在按下"插入"按钮后发生:
UpdateData();
m_strsql.Format("DRIVER={%s};DSN='''';FIRSTROWHASNAMES=1;READONLY=FALSE;CREATE_DB=\"%s\";DBQ=%s", m_dbdriver,m_strdir,m_strdir);
TRY
{
  if (m_db.OpenEx(m_strsql,CDatabase::noOdbcDialog))
  {
   m_strsql.Format("Insert into OdbcExl(Name,Age,Gener)Values('%s',%d,'%s')",m_name,m_age,m_gener);
   m_db.ExecuteSQL(m_strsql);
  }
}
CATCH_ALL(e)
{
  e->ReportError();
// db.Close();
}
END_CATCH_ALL;
m_db.Close();
可以说,只要对CDatabase稍有了解,对SQL语句稍有了解,这个问题就很容易解决,如果要说这是一个针对Excel文件操作的方法,那是因为在OpenEx初始化数据库对象(不是"打开"哦)时用的文件后缀名为.xls而已,我们可以像在普通的数据库中一样进行其他操作,如用SELECT语句来读取EXCEL文件的内容等, 第一种方法完.
下面是第二种方法,这里涉及的原理要复杂一些了,传说中的OLE(对象链接与嵌入)技术在这里用上了,EXCEL.EXE作为一个组件服务器,应用程序作为客户端......,还是直接写过程吧,头晕晕的,只能平铺直述了.
A,从classwizard中add class处from type library,去office的安装目录下引入excel.exe(这是office 2003的选择,其他版本都是用olb文件),服务器就算引入了,这时会弹出对话框,要求加入一些类,这些类都是一些接口,里面有大量的方法,类的对象表征着excel文件的一个个部分,常用的有这几个_application,workbooks,_workbook,worksheets,_worksheet,Range,它们分别代表不同的意义._application代表了EXCEL服务器,workbooks表示整个Excel服务器(表现为一个.xls文件)里所有的表,(可以通过"新建"得到多个表,即MDI程序里的一个视窗一样,所有的视窗就是workbooks), _workbook就是一个表,相当于MDI中的一个视窗, worksheets表示所有的表单,每个表都可能有很多表单(建立一个Excel文件之后,打开,可以看到有sheet1,sheet2等,所有这些sheetn就组成了worksheets), _worksheet就表示一个表单, range表示元素的集合. 搞清楚上面这几个名词的意思非常重要.
B,在dlg.h中声明下面几个变量:
_Application exlapp;   //组件服务器的各个classes
_Workbook wbk;
Workbooks wbks;
_Worksheet wht;
Worksheets whts;
LPDISPATCH lpDisp;
并在app.cpp的InitInstance方法中加入下面两句AfxInitOle(); AfxEnableControlContainer();
C,这里我没有像上面一样完全用程序来生成一个Excel文件,而是在开始时就在当前目录下生成了一个Excel文件,在对话框上我设置了两个按钮,下面是"显示"按钮的代码:
//创建Excel服务器
if(!exlapp.CreateDispatch("Excel.Application"))
{
  AfxMessageBox("无法启动Excel服务器!");
  return;
}
COleVariant  avar((long)DISP_E_PARAMNOTFOUND,VT_ERROR);
exlapp.SetVisible(TRUE);//使Excel可见
exlapp.SetUserControl(TRUE);//允许其它用户控制Excel,否则Excel将一闪即逝.

//Open an excel file
char path[MAX_PATH];
GetCurrentDirectory(MAX_PATH,path);
CString strPath = path;
strPath += "[url=file://vcopexcel/]\\VCOpExcel[/url]";
wbks.AttachDispatch(exlapp.GetWorkbooks());

lpDisp=wbks.Open(strPath,
  avar,avar,avar,avar,avar,avar,avar,avar,avar,avar,avar,avar,avar,avar);

wbks.ReleaseDispatch();
exlapp.ReleaseDispatch();
D,与上面第一种方法一样,可以插入记录:
UpdateData();     //读入数据
if (""==m_name)     //判断名字输入有效
{
  MessageBox("Please input a right name");
  return;
}
if (0>=m_age||100<=m_age)  //判断年龄输入有效
{
  MessageBox("Please input a right age");
  return;
}
char *p=strupr(_strdup(m_gener));
if (strcmp(p,"FEMALE")&&strcmp(p,"MALE")) //判断性别输入有效
{
  MessageBox("Please input a right gener");
  return;
}

Range range;
Range usedRange;
COleVariant  avar((long)DISP_E_PARAMNOTFOUND,VT_ERROR);

if(!exlapp.CreateDispatch("Excel.Application")) //启动服务器
{
  AfxMessageBox("无法启动Excel服务器!");
  return;
}
char path[MAX_PATH];
GetCurrentDirectory(MAX_PATH,path);
CString strPath = path;
strPath += "[url=file://vcopexcel/]\\VCOpExcel[/url]";
wbks.AttachDispatch(exlapp.GetWorkbooks());
lpDisp=wbks.Open(strPath,            //初始化.
  avar,avar,avar,avar,avar,avar,avar,avar,avar,avar,avar,avar,avar,avar);
wbk.AttachDispatch(lpDisp);
whts.AttachDispatch(wbk.GetWorksheets());
lpDisp=wbk.GetActiveSheet();
wht.AttachDispatch(lpDisp);



usedRange.AttachDispatch(wht.GetUsedRange());
range.AttachDispatch(usedRange.GetRows());
long iRowNum=range.GetCount();//已经使用的行数
range.AttachDispatch(wht.GetCells());

range.SetItem(COleVariant(long(iRowNum+1)),COleVariant(long(1)),COleVariant(m_name));
range.SetItem(COleVariant(long(iRowNum+1)),COleVariant(long(2)),COleVariant(m_age));
range.SetItem(COleVariant(long(iRowNum+1)),COleVariant(long(3)),COleVariant(m_gener));

wbk.Save();
wbk.Close(avar,COleVariant(strPath),avar);
wbks.Close();
exlapp.Quit();
第二种方法完.


来自:http://blog.csdn.net/biblereader/archive/2006/06/26/834663.aspx

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多