在VC中彻底玩转Excel
- 格式:doc
- 大小:40.20 KB
- 文档页数:39
C++读取Excel的XLS文件的方法有很多,但是也许就是因为方法太多,大家在选择的时候会很疑惑。
由于前两天要做导表工具,比较了常用的方法,总结一下写个短文,1.OLE的方式这个大约是最常用的方式,这个方式其实启动了一个EXCEL的进程在背后读写EXCEL 文件,这个方式的最大好处是什么事情都能做。
包括设置EXCEL的格式,增加删除Sheet,读写单元格,等等。
功能几乎是最全的,而且使用起来也不是特别的难。
其基本方法都是使用导出的.h文件进行OLE操作,但是由于OLE的接口说明文档不多,想非常完美的使用她们也不是太容易,好在例子也很多。
网上普遍认为OLE速度慢,EXCEL的OLE读写方式也基本一样。
但是读取速度可以改进,如果在读取的加载整个Sheet的Range的全部数据,而不是一个个单元格读取,那么速度还是相对不错。
想想原理也很简单,整体读取减少了OLE的交互次数。
OLE的写入方式一般只能几个进行比较方便,所以速度可能要快很多。
我自己的亲身体会是,一个EXCEL文件,100多列的字段,如果采用一个个单元格的读取方式,1s大约3条左右的记录,如果整体读取,速度可以提高几十倍。
OLE读写EXCEL方式功能很强大,读取速度还可以,但写入速度不高,当然这个方式不可能移植的,而且你必须安装了EXCEL。
2.Basic EXCEL 方式这是CodeProject上的一个推荐开源工程了,/KB/office/BasicExcel.aspx作者是基于EXCEL的文件格式进行的处理。
但是为什么叫Basic EXCEL呢。
他不支持很多东西,公式,文件格式,表格合并等(有人说中文支持也不好),所以可以认为他只支持最基本的EXCEL表格,我自己的尝试是如果这个EXCEL文件有其他元素(公式,格式等),使用Basic EXCEL读取会失败。
OLE读写EXCEL方式功能比较弱,由于是直接根据文件格式操作,读写速度都不错,你也不需要按照EXCEL,另外这个方式是可以移植的,但是有一些成本,其代码比较晦涩难懂,而且没有注释,另外即使在Windows平台上,告警也很多。
VC操作Excel之基本操作/sp_daiyq/article/details/61912331、Excel的对象模型(有人称其为层次结构)打开一个Excel工作表,点击“工具”->“宏”->“Visual Basic 编辑器”选项打开VB的编辑器,打开帮助文档,里面“Microsoft Excel Visual Basic 参考”下的“Microsoft Excel 对象模型”展示了完整的Excel的层次结构,是不是有点类似于MFC的继承图表啊?利用帮助文档我们可以找到一些需要的知识,下面介绍一些类:_Application:表示整个的Excel应用程序,包含一个工作簿集合Workbooks:工作簿集合,包含N个工作簿(Workbook)_Workbook:工作簿,包含一个工作表(sheets)集合Worksheets:工作表集合,包含N个工作表_Worksheet:工作表,也就是我们在Excel中看到的Sheet1、Sheet2、Sheet3,它是我们操作Excel的基本单位Range:这是单元格的集合,我们知道Excel是由一个个的单元格组成的,通过Range 来操作单元格Font:用于设置单元格的字体、颜色、字号、粗体设置Interior:设置底色Boards:设置区域内所有单元格的边框,如果要设置一组区域的外边框的话用Rang->BorderAround设置下面用一个具体的例子来说明怎么通过MFC来操作Excel2、Excel库的插入在我们MFC的工程中,按Ctrl+W打开MFC类向导对话框,点击“Add Class...”->“From a type Library...”,找到你所使用的excel类型库,我使用的在目录C:/ProgramFiles/Microsoft Office/OFFICE11下的“EXCEL.EXE”文件,查找时文件类型选“All Files”,然后添加我们所需要的类,通常以上列举的前6类是必须的,其它的需要时再添加。
如何用VC读取Excel表格中的数据详细介绍如何用VC读取Excel表格中的数据详细介绍2007-03-29 17:44首先,我们要明白的是,VC是通过ODBC来访问Excel表格的,也就是说,VC将Excel表格,当作数据库来处理。
当然了,也可以通过读以tab键隔开的文件来处理这样的文件,但是,我还是更加愿意用读取数据库的方式来访问Excel表格。
第二,既然是数据库,那么,就需要建立一个与该库对应的dsn,这个,而且,在建立dsn之前,首先要确定,已经安装了Excel的驱动。
第三,要访问数据库中的表格,就要先打开该表格,如此,就需要一个与之对应的RecordSet。
如此,有如下代码:void CRWExcel::ReadFromExcel(){CDatabase database;CString sSql;CString sItem1, sItem2;CString sDriver;CString sDsn;CString sFile = "Demo.xls";// 将被读取的Excel文件名// 检索是否安装有Excel驱动 "Microsoft Excel Driver (*.xls)"sDriver = GetExcelDriver();if (sDriver.IsEmpty()){// 没有发现Excel驱动AfxMessageBox("没有安装Excel驱动!");return;}// 创建进行存取的字符串sDsn.Format("ODBC;DRIVER={%s};DSN='''';DBQ=%s", sDriver, sFile);TRY{// 打开数据库,建立与这个Excel对应的Databasedatabase.Open(NULL, false, false, sDsn);CRecordset recset(&database);// 设置读取的查询语句.demo.xls并非文件名,需要在excel中进行//设置,具体文章最后有讲sSql = "SELECT Age, Name FROM DEMO.XLS";// 执行查询语句,打开表格recset.Open(CRecordset::forwardOnly, sSql, CRecordset::readOnly);// 获取查询结果while (!recset.IsEOF()){//读取Excel内部数值recset.GetFieldValue("Name ", sItem1);recset.GetFieldValue("Age", sItem2);// 移到下一行recset.MoveNext();}// 关闭数据库database.Close();}CATCH(CDBException, e){// 数据库操作产生异常时...AfxMessageBox("数据库错误: " + e->m_strError);}END_CATCH;}需要注意的是,我们对我们的Excel表格需要进行一些处理,需要先选定我们要读取的数据,之后,选择插入>>名字>>之后,在输入框中输入我们在select语句中用到的表名。
[原创]在VC中彻底玩转Excel如今Excel是越来越重要了,在我们自己开发的程序中不免要和Excel打交道了。
利用 Automation 技术,我们可以在不去了解数据库的情况下玩转Exce,l而且你会发现一切竟如此轻松!好了,咱们开始吧,我不喜欢用长篇累牍的代码来故弄玄虚,所以下面的代码都是切中要害的片段,总体上是个连贯的过程,包括启动 Exce,l 读取数据,写入数据,以及最后的关闭Exce,l 其中还包括了很多人感兴趣的合并单元格的处理。
特别说明以下代码需要 MFC的支持,而且工程中还要包含 EXCEL2OO0勺定义文件:EXCEL9.,H EXCEL9.CPPVC6.0操作 Excel( 2008-1-22 11:26 )1.建立一个空的单文档程序;2.加入Excel的库文件:在vc+ +的view菜单里面选classwizard 然后选 Automation tab,再选Add Class 选"From a type library.",然后再选你需要的 object library。
(for this example, if you are automating Excel 97, choose the Microsoft Excel 8.0 Object Library; the defaultlocation is C:\Program Files\MicrosoftOffice\Office\Excel8.olb).If you are automating Microsoft Excel 2000, choose Microsoft Excel 9.0 Object Library for which the defaultlocation is the C:\Program Files\MicrosoftOffice\Office\Excel9.olb.If you are automating Microsoft Excel 2002 and Microsoft Office Excel 2003, the object library is embedded inthe file Excel.exe. The default location for Excel.exe in Office 2002 is C:\program Files\MicrosoftOffice\Office10\Excel.exe. The default location for Excel.exe in Office 2003 is C:\programFiles\MicrosoftOffice\Office11\Excel.exe.在 ListCtrl 框中选中 _Application, _Workbook, _Worksheet, Range, Sheets, Workbooks,单击 OK,自动生成 EXCEL8.f和 EXCEL8.CP文件(或者 EXCEL9.I和 EXCEL9.CP或者 EXCELS EXCEL.CPP。
我不会飞经验始于总结,进步源于积累(短地址: )<< 解决无法直接打开EXCEL文件的问题 | 首页 | 2008北京奥运会开幕式高清图片(46P) >>搜索最新日志最新评论打开MFC ClassWizard窗口(查看—>建立类向导),选择Automation,单击Add Class按钮,选择From a type library...,弹出文件选择对话框,之后定位到Microsoft Office的安装目录(通常访客/logs/24923682.html[2010/8/20 9:34:10]访问统计: 96302什么是返回编辑器,查看工程文件,可发现多了EXCEL9.H及EXCEL9.CPP两个文件。
打开stdafx.h头文件确保包含如下头文件:#include <afxdisp.h>#include "excel9.h"打开TestExcel.cpp文件,修改CTestExcelApp::InitInstance(),加入如下代码:BOOL CTestExcelApp::InitInstance()/logs/24923682.html[2010/8/20 9:34:10]到此,即完成了我们的示例程序,下面将对程序进行详细的说明,如果大家有过使用VisualBasic操作Excel程序的经验,则应该能看懂下面程序:void CTestExcelDlg::OnButton1()/logs/24923682.html[2010/8/20 9:34:10]/logs/24923682.html[2010/8/20 9:34:10]/logs/24923682.html[2010/8/20 9:34:10]/logs/24923682.html[2010/8/20 9:34:10]/logs/24923682.html[2010/8/20 9:34:10]博客大巴博客大巴模板设计:柠檬星球 | 作者:小明/logs/24923682.html[2010/8/20 9:34:10]。
VC操纵EXCEL的两种方法第一种方法,简单的,用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;READO NLY=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;REA DONLY=FALSE;CREATE_DB=\"%s\";DBQ=%s", m_dbdriver,m_strdir,m_strdi r);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文件),服务器就算引入了,这时会弹出对话框,要求加入一些类,这些类都是一些接口,里面有大量的方法,类的对象表征着exc el文件的一个个部分,常用的有这几个_application,workbooks,_workbook,workshee ts,_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(); AfxEnableControl Container();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 filechar path[MAX_PATH];GetCurrentDirectory(MAX_PATH,path);CString strPath = path;strPath += "\\VCOpExcel";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 += "\\VCOpExcel";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)),COleVa riant(m_name));range.SetItem(COleVariant(long(iRowNum+1)),COleVariant(long(2)),COleVa riant(m_age));range.SetItem(COleVariant(long(iRowNum+1)),COleVariant(long(3)),COleVa riant(m_gener));wbk.Save();wbk.Close(avar,COleVariant(strPath),avar);wbks.Close();exlapp.Quit();第二种方法完.。
最近刚完成一个例子,受益不菲,和大家分享一下。
VC的Excel编程操作,总结:(结合网络资源)利用VC操作Excel的方法至少有两种1 .利用ODBC把Excel文件当成数据库文件,来进行读、写、修改等操作,网上有人编写了CSpreadSheet类,提供支持。
(不太能理解CSpreadSheet)2. 利用Automation(OLD Automation)方法。
将Excel当成组件服务器,利用VBA。
又分为基于MFC的和SDK两种。
(制作报表适用)主要研究了一下第二种基于MFC的OLE编程方法。
一、Excel的对象模型Application:代表应用程序本身。
即Excel应用程序Workbooks:是Workbook 的集合,代表了工作薄。
Worksheets:是Worksheet的集合,是Workbook的子对象。
Range:是Worksheet的子对象,可以理解为Sheet中一定范围的单元格。
Shapes:是Worksheet的子对象,用于存储图片等信息的单元格。
二、VC操作Excel的初始化过程1、导入Excel库文件。
使用VC6.0的同志们可进行一下操作获取Excel库文件:1.启动VC 6.0,打开新建对话框,新建一个MFC AppWizard(exe)工程,这里工程明设置为TestExcel。
2.进入MFC 应用程序向导,选择基本对话框,直接点击完成,工程文件结构如下图:3.打开MFC ClassWizard窗口(查看—>建立类向导),选择Automation,单击Add Class按钮,选择From a type library...,弹出文件选择对话框,之后定位到Microsoft Office 的安装目录(通常为C:\Program Files\Microsoft Office\Office),选择(excel.exe适用于Excel2003;EXCEL9.OLB适用于Excel2000),确定后,弹出Confirm Classes 窗口,(在不知道会使用到哪些类的情况下,)选择列表中的所有类,单击OK按钮。
轻轻松松搞定VC操作Excel之⼀时常在论坛上看到有⼈问这个VC操作Word或者Excel有没有书系统地介绍如何去做,有这个必要吗?其实捅破这层窗户纸,你就会恍然⼤悟,原来是这么回事啊!在此我觉得有必要把我⼯作中操纵Excel的⼀点⼩体会拿出来和⼤家共享,也许对初学者能有所帮助,⾼⼿就不要看了。
操作Word请看⽜⼈yingkou的BLOG() .基本步骤如下:⼀、Excel的层次结构ApplicationWorkbooksWorkbook......WorksheetsWorksheet......RangeFontBorders.............⼆、插⼊类型库1、在⼀个已有的MFC⼯程按Ctrl + W 弹出ClassWizard对话框。
2、Add Class...\From a type Library... 在 Office ⽬录中,找到你想使⽤的Excel类型库(Offce2000下,此⽬录在C:\ProgramFiles\Microsoft Office\Office\EXCEL9.OLB)。
选择EXCEL9.OLB此类型⽂件。
3、在弹出的对话框中选择要添加的类,具体选那些类要根据实际情况⽽定。
当然你也可以全选。
三、基本操作当你要选⽤Excel⽣成报表时,表的结构可能有固定的部分,这时做⼀个模板,这样可以减少编码的负担。
加载Excel模板的代码如下。
_Application ExcelApp; // 定义Excel应⽤程序Workbooks wbsBooks;_Workbook wbBook;Worksheets wssSheets;_Worksheet wsSheet;Range rngXls;FontXls font; // 字体BordersXls border; // 边框// 初始化Comif (::CoInitialize( NULL ) == E_INVALIDARG){AfxMessageBox(_T("初始化Com失败!"));}// 创建Excel2000服务器(启动Excel)if ( !ExcelApp.CreateDispatch(_T("Excel.Application"), NULL)){AfxMessageBox(_T("创建Excel2000服务失败!"));::CoUninitialize();}ExcelApp.SetVisible(FALSE); // 隐藏CString strPath;strPath += "C:\\template.xlt"; // 模板的路径CFileFind filefind;if( !filefind.FindFile( strPath ) ){AfxMessageBox( "没有找到模版⽂档,请其查找" );CFileDialog dlg (TRUE,NULL,NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,"模版||*.xlt||",NULL );if (IDOK == dlg.DoModal()){strPath = dlg.GetPathName();}}COleVariant vOptional( (long)DISP_E_PARAMNOTFOUND, VT_ERROR );try{wbsBooks.AttachDispatch(ExcelApp.GetWorkbooks(), TRUE);wbBook.AttachDispatch(wbsBooks.Add(COleVariant(strPath)), TRUE );wssSheets = wbBook.GetWorksheets();wsSheet = wssSheets.GetItem(_variant_t("Sheet1")); // Get Sheet1wsSheet.SetName( "Your Sheet" ); // 改名// 得到全部Cells,此时,rngXls 是cells的集合rngXls = wsSheetAcc.GetCells();}catch (CException e){AfxMessageBox( "" )}我们知道在Excel中每个单元格可以⽤A1,A2,C3的形式来表⽰。
我以前写了个VC操作Excel 2003的例子,是一个Console的程序,你可以修改一下文件保存的路径,然后运行一下看看。
/dukejoe/archive/2007/04/16/1156319.aspx以下是一部分的VC代码,全部的看链接吧。
我就不都粘了VC操作Excel文件保存问题用VC对Excel文件进行写操作后,在程序结束前需要对一些对象进行收尾工作,如调用_Workbook::Save()方法(该方法是Microsoft提供的供VC调用的对Excel文件操作的标准方法,在文件excel9.cpp或excel.cpp中定义)保存文件。
问题就出现在这里,若选取要保存的Excel文件以前不存在则程序创建一个同名的空Excel文件,对Excel 表的操作实际是对其同名副本的操作,Save()方法会触发一个"另存为"的对话框,需要覆盖原来同名的空Excel文件,否则写入Excel的数据会丢失。
若选取的Excel文件已经存在,则调用Save()方法不会触发"另存为"对话框,系统会自动保存写到Excel中的数据。
需要说明的是,在调用Save()前,已经调用过SetAlertBeforeOverwriting(FALSE)和SetDisplayAlerts(FALSE)关掉一些警告窗口了。
若调用SaveAs()方法,虽不会触发"另存为"对话框,但会出抛出“找不到成员”的错误,这时保存写好的Excel文件后并重新打开发现数据还是丢失。
想尽所有办法,可总无法去掉那个讨厌的"另存为"对话框,请各位大虾帮忙。
多谢了!SaveAs()是excelapp的方法吗。
xlApp.ActiveWorkbook.SaveAs "C:\excel.xls"xlApp.Quit我的没有问题。
如今Excel是越来越重要了,在我们自己开发的程序中不免要和Excel打交道了。
-----------------------------------精品考试资料---------------------学资学习网-----------------------------------[原创]在VC中彻底玩转Excel如今Excel是越来越重要了,在我们自己开发的程序中不免要和Excel打交道了。
利用Automation技术,我们可以在不去了解数据库的情况下玩转Excel,而且你会发现一切竟如此轻松!好了,咱们开始吧,我不喜欢用长篇累牍的代码来故弄玄虚,所以下面的代码都是切中要害的片段,总体上是个连贯的过程,包括启动Excel,读取数据,写入数据,以及最后的关闭Excel,其中还包括了很多人感兴趣的合并单元格的处理。
特别说明以下代码需要MFC的支持,而且工程中还要包含EXCEL2000的定义文件:EXCEL9.H,EXCEL9.CPPVC6.0操作Excel( 2008-1-22 11:26 )1.建立一个空的单文档程序;2.加入Excel的库文件:在vc++的view菜单里面选classwizard,然后选Automation tab,再选Add Class,选?潲??祴数氠扩慲祲尮,然后再选你需要的object library。
(for this example, if you are automating Excel 97, choose the Microsoft Excel 8.0Object Library; the defaultlocation is C:\ProgramFiles\MicrosoftOffice\Office\Excel8.olb).If you are automating Microsoft Excel 2000, choose Microsoft Excel 9.0 ObjectLibrary for which the defaultlocation is the C:\ProgramFiles\MicrosoftOffice\Office\Excel9.olb.If you are automating Microsoft Excel 2002 and Microsoft Office Excel 2003, theobject library is embedded inthe file Excel.exe. The default location for Excel.exe inOffice 2002 is C:\programFiles\MicrosoftOffice\Office10\Excel.exe. The defaultlocation for Excel.exe in Office 2003 is C:\programFiles\MicrosoftOffice\Office11\Excel.exe.1 / 31在ListCtrl框中选中_Application, _Workbook, _Worksheet, Range, Sheets,Workbooks,单击OK,自动生成EXCEL8.H和EXCEL8.CPP文件(或者EXCEL9.H和EXCEL9.CPP或者EXCEL.H和EXCEL.CPP)。
3.初始化COM库:在App类的InitInstance中一定要先加上AfxOleInit();因为操作Excel是属于COM自动化,需初始化COM库。
4.加入Excel的头文件:文档类的CPP文件中包含头文件椣据畬敤尠硥散?栮,是关于Excel中各类的接口定义信息。
如果excel9.h, excel9.cpp文件已经生成创建project,将示例文档中的excel9.h, excel9.cpp复制到工程目录,选Project-->Add to project-->File-->excel9.h;Project-->Add to project-->File-->excel9.cpp;在App的Initinstance中加入AfxOleInit();在Dlg的头文件中加入#include excel9.h代码中加入调用COM接口代码,编译即可,**************************************************** **************************************************** *********//*****//变量定义_Application app;Workbooks books;2 / 31_Workbook book;Worksheets sheets;_Worksheet sheet;Range range;Range iCell;LPDISPATCH lpDisp;COleVariant vResult;COleVariantcovTrue((short)TRUE),covFalse((short)FALSE),covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR); //*****//初始化COM的动态连接库if(!AfxOleInit()){晁?獥慳敧潂?无法初始化COM的动态连接库!);return ;}//*****//创建Excel 2000服务器(启动Excel)if(!app.CreateDispatch(Excel.Application))3 / 31{晁?獥慳敧潂?无法启动Excel服务器!);return;}app.SetVisible(TRUE);//使Excel可见app.SetUserControl(TRUE);//允许其它用户控制Excel //*****//打开c:\\1.xlsbooks.AttachDispatch(app.GetWorkbooks());lpDisp = books.Open(C:\\\\1.xls,covOptional, covOptional, covOptional, covOptional, covOptional,covOptional, covOptional, covOptional, covOptional, covOptional,covOptional, covOptional );//*****//得到Workbookbook.AttachDispatch(lpDisp);//*****//得到Worksheetssheets.AttachDispatch(book.GetWorksheets());//*****//得到当前活跃sheet4 / 31//如果有单元格正处于编辑状态中,此操作不能返回,会一直等待lpDisp=book.GetActiveSheet();sheet.AttachDispatch(lpDisp);//*****//读取已经使用区域的信息,包括已经使用的行数、列数、起始行、起始列Range usedRange;usedRange.AttachDispatch(sheet.GetUsedRange());range.AttachDispatch(usedRange.GetRows());long iRowNum=range.GetCount();//已经使用的行数range.AttachDispatch(usedRange.GetColumns());long iColNum=range.GetCount();//已经使用的列数long iStartRow=usedRange.GetRow();//已使用区域的起始行,从1开始longiStartCol=usedRange.GetColumn();//已使用区域的起始列,从1开始//*****//读取第一个单元格的值range.AttachDispatch(sheet.GetCells());range.AttachDispatch(range.GetItem(COleVariant((long)1),COleVariant((long)1)).pdispVal );COleVaria nt vResult=range.GetValue();CString str;if(vResult.vt == VT_BSTR)//字符串{str=vResult.bstrVal;5 / 31}else if (vResult.vt==VT_R8)//8字节的数字{str.Format(%f,vResult.dblVal);}else if(vResult.vt==VT_DATE)//时间格式{SYSTEMTIME st;VariantTimeToSystemTime(&vResult.date, &st);}else if(vResult.vt==VT_EMPTY)//单元格空的{str=\;}//*****//读取第一个单元格的对齐方式,数据类型:VT_I4//读取水平对齐方式range.AttachDispatch(sheet.GetCells());iCell.AttachDispatch((range.GetItem (COleVariant(long(1)), COleVariant(long(1)))).pdispVal);vResult.lVal=0;vResult=iCell.GetHorizontalAlignment();if(vResult.lVal!=0)6 / 31{switch (vResult.lVal){case 1://默认break;case -4108://居中break;case -4131 : //靠左break;case -4152 : //靠右break;}}//垂直对齐方式iCell.AttachDispatch((range.GetItem (COleVariant(long(1)), COleVariant(long(1)))).pdispVal);vResult.lVal=0;vResult=iCell.GetVerticalAlignment();if(vResult.lVal!=0){switch (vResult.lVal){case -4160 ://靠上7 / 31break;case -4108 ://居中break;case -4107 ://靠下break;}}//*****//设置第一个单元格的值HI,EXCEL!range.SetItem(COleVariant(1),COleVariant(1),COleVariant(HI,EX CEL!));//*****//设置第一个单元格字体颜色:红色Font font;range.AttachDispatch(sheet.GetCells());range.AttachDispatch((range.GetItem (COleVariant(long(1)), COleVariant(long(1)))).pdispVal);font.SetColor(COleVariant((lon g)0xFF0000));//*****//合并单元格的处理//包括判断第一个单元格是否为合并单元格,以及将第一个单元格进行合并Range unionRange;range.AttachDispatch(sheet.GetCells());unionRange.AttachDispatch(range.GetItem8 / 31(COleVariant((long)1),COleVariant((long)1)).pdispVal );vResult=unionRange.GetMergeCells();if(vResult.boolVal==-1)//是合并的单元格{//合并单元格的行数range.AttachDispatch (unionRange.GetRows ());long iUnionRowNum=range.GetCount ();//合并单元格的列数range.AttachDispatch (unionRange.GetColumns ());long iUnionColumnNum=range.GetCount ();//合并区域的起始行,列long iUnionStartRow=unionRange.GetRow();//起始行,从1开始long iUnionStartCol=unionRange.GetColumn();//起始列,从1开始}else if(vResult.boolVal==0){//不是合并的单元格}//将第一个单元格合并成2行,3列range.AttachDispatch(sheet.GetCells());unionRange.AttachDispatch(range.GetItem(COleVariant((long)1),COleVariant((long)1)).pdispVal );9 / 31unionRange.AttachDispatch(unionRange.GetResize(COleVariant ((long)2),COleVariant((long)3)));unionRange.Merge(COleVariant((long)0));//合并单元格//*****//将文件保存为2.xlsbook.SaveAs(COleVariant(C:\\\\2.xls),covOptional,covOptional, \\covOptional,covOptional,covOptional,0,\\covOptional,covOptional,covOptional,covOptional);//*****//关闭所有的book,退出Excelbook.Close(covOptional,COleVariant(OutFilename),covOptional); books.Close();app.Quit();关于excel.h和excel.cpp,要注意版本问题.比如对excel xp,类库是直接包含在excel.exe中.因此你只要用加入类(addclass)的方法,直接选中excel.exe,并选择对话框中的常用的几个类(如Rang)就可以编程了.千万不要选所有的类,否则太大了.作者:unionsoft 2003-11-29 11:00:34)修改字体颜色的那段漏了一句,应为://*****//设置第一个单元格字体颜色:红色Font font;10 / 31range.AttachDispatch(sheet.GetCells());range.AttachDispatch((range.GetItem (COleVariant(long(1)), COleVariant(long(1)))).pdispVal);font.AttachDispatch (range.GetFont ());font.SetColor(COleVariant((long)0xFF0000));作者:zhengkuo 2003-12-2 10:50:00)如果,程序既要安装在2000的计算机上,也可能安装在XP 的机子上,有的用户还用97,(指的都是office),可能会出现版本问题------其中比较麻烦的是--在app.quit()后,仍旧存在excel进程,如果这样?怎么解决?作者:zhengkuo 2003-12-2 10:51:50)请教高手,能否用vb控制excel做成dll,在arx中进行调用,因为毕竟vb与excel亲切作者:unionsoft 2004-1-30 11:06:58) 以下是引用zhengkuo在2003-12-2 10:50:00的发言:如果,程序既要安装在2000的计算机上,也可能安装在XP的机子上,有的用户还用97,(指的都是office),可能会出现版本问题------其中比较麻烦的是--在app.quit()后,仍旧存在excel进程,如果这样?怎么解决?兼容性问题:office2002-office97是向下兼容的,只要你不使用office2002中的新特性,程序在这些office版本中都好用Excel程序不能退出的问题:1 .不要使用#import导入类型库,如:#importc:\\excel\\excel.olb2 .程序结束时,确保所有IDispatch都释放了,如:app.ReleaseDispatch ();作者:easypower 2004-5-14 10:00:39) 還是不明白如何得到excel.cpp和excel.h這兩個文件,請指教作者:jack1975 2004-6-24 16:43:03)11 / 31有版本问题时,可以加一个判断:1、首先通过exlApp得到版本,比如9.0,10.0,11.0,10.0以后的版本注意open函数的参数为15个,即最后在增加两个covOptional,即可,另外,补充一下,判断当前是否有excel应用程序在运行,使之更舒服一些:::CLSIDFromProgID(LExcel.Application,&clsid); // from registry if(::GetActiveObject(clsid, NULL,&pUnk) == S_OK){VERIFY(pUnk->QueryInterface(IID_IDispatch,(void**) &pDisp) == S_OK);ExcelApp.AttachDispatch(pDisp);pUnk->Release();}else{if(!ExcelApp.CreateDispatch(Excel.Application)) { AfxMessageBox(Excel program not found);return 0;}}作者:unionsoft 2004-12-13 12:36:09)以下是引用zhmary在2004-12-10 11:30:10的发言:请问各位高手,从哪里得onclick=Cswf()height=22alt=Flash图片src=skins/default/ubb/swf.gif width=23 border=0>到Excel.cp...12 / 31Excel.cpp和Excel.h是从Excel的类型库中获取的,类型库类似C++中的头文件,包括接口,方法,属性的定义;类型库在Excel的安装目录可以找到,Excel的版本不同,这个类型库也不一样,如下所示:Excel 95 and prior:xl5en32.olbExcel 97:excel8.olbExcel 2000:excel9.olbExcel 2002:excel.exe具体的获取方法:1 .使用VC++新建立一个基于MFC的EXE工程2 .点击菜单查看??建立类向导,此时会弹全???慬獳楗慺摲对话框3 .点击?摤?慬獳???潲??祴数氠扩慲屹,指定Excel的type libray,在Excel的安装目录下可以找到,如:D:\\Microsoft Office\\Office\\EXCEL9.OLB4 .在弹出的对话框中选择所需的类,按确定,Excel.cpp和Excel.h就产生了。