Visual Studio 2013开发MFC程序对Excel 2010进行写操作(下)

版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/Fish_55_66/article/details/49160083

上文的记录中,只是提到了如何在MFC程序添加Excel类库而已,并没有记录到如何调用Excel类库去实际操作Excel文件。在MFC程序,除了上文中记录的方法之外,其实还有很多方法也都可以实现对Excel文件的操作,在《C++读写EXCEL文件方式比较》这篇文章中总结得不错,感兴趣的推荐看看,同时该文的作者还分享了一个他自己封装好OLE操作类,详见《C++使用OLE高速读写EXCEL的源码》,该操作类中通过预加载的方式优化了读取Excel数据的速度,而我编写的读取TXT日志转换为Excel文件的小程序中,只需要对Excel进行写操作,所以我并没有参考该代码,不过还是感谢原作者的分享。


在学习调用Excel类库去操作Excel文件的过程中,让我印象最深刻的文章是《VC++6.0操作excel2007文件封装类CExcelServer 》,看完了该文章,再去学习别人的OLE 操作Excel文件的代码,基本就没有什么难度了。该文中对OLE操作Excel时常用的枚举变量进行说明,还给出了MSDN帮助连接,这让当时的我受益匪浅啊,因为我之前看到了太多的示例代码中直接就是把一个数字传入函数中,比如-4143、-4108、-4142等等,望着这些数字,谁知道是个什么意思o(╯□╰)o!鉴于此,当时瞬间就觉得文中的示例代码,那才是真正的良心代码啊!为防止原文丢失,在此摘录文中部分内容如下:

===================================================我是分割线========================================================

要利用OLE Automation实现对Excel进行操作,必须与Excel对象模型提供的对象进行交互。Excel提供了数百个可能需要与之交互的对象,下面先了解一下编程中常用到的几个对象。


1) Application 对象:代表整个 Microsoft Excel 应用程序。
2) Workbook 对象:代表一个 Microsoft Excel 工作簿,即Excel文件。
3) Workbooks 对象:包含 Microsoft Excel 中当前打开的所有 Workbook 对象。
4) Worksheet 对象:代表一个工作表。一个工作簿中可以包括多个工作表。
5) Worksheets 对象:代表指定或活动工作簿中所有 Worksheet 对象的集合。
6) Range 对象:代表某一单元格、某一行、某一列、某一选定区域(该区域可包含一个或若干连续单元格区域)。Range对象是Excel操作的重点,对于数据插入、修改、删除都要通过它来实现,Range所表示等同于我们在实际编辑Excel文件时,用鼠标在表单中选择中的区域,选中之后再对其进行单元格修改、删除、合并、设置宽、高、颜色等操作。
7) Chart对象:代表工作簿中的图表。此图表既可以是嵌入的图表(包含在ChartObject对象中),也可以是单独的图表工作表。
8) Charts对象:代表指定或活动工作簿中所有图表工作表的集合。
9) Sheets 对象:代表指定或活动工作簿中所有工作表(可以是Chart对象或者WorkSheet对象)的集合。
10) Font对象:用于设置Range选中的单元格字体格式和颜色。
11) Interior对象:用于设置Range选中的单元格背景格式和颜色。
12) Borders对象:用于设置Range选中的单元格的边框。

其他对象可到msdn去了解:http://msdn.microsoft.com/zh-cn/library/office/ff194068.aspx

调用excel对象方法时,常常会用到一些枚举变量,可以到msdn中查找相关值:http://msdn.microsoft.com/zh-cn/library/office/ff838815.aspx

===================================================我是分割线========================================================


虽然Excel提供的对象很多,不过我们只需要在自己程序中添加自己需要的对象即可,添加对象到程序中之后,可以去头文件中查看对象提供的接口,基本上看了接口名称就能知道接口的功能了。下面列举几个我在开发过程中一开始没有注意到的地方:


1、必须初始化COM库。在MFC程序中,推荐使用函数AfxOleInit()进行初始化,不过也可以使用函数CoInitialize(),但是CoInitialize()和CoUninitialize()在程序中必须成对调用。如果忘记初始化COM库,则无法创建Excel应用。


2、如果调用了CWorkbook的接口SaveAs另存文件,如果另存为的Excel文件已经存在并且被打开,则接口SaveAs会出错并导致程序崩溃,所以必须保证另存为的文件不能被打开,据说这是OLE特点决定的,没深究o(╯□╰)o


3、程序中有一个按钮对象CButton m_btnExportLogFile,调用CApplication的接口CreateDispatch创建Excel应用之后再去调用m_btnExportLogFile.EnableWindow(FALSE),发现按钮不会变成禁用的灰色状态;如果先调用m_btnExportLogFile.EnableWindow(FALSE),再去调用CApplication的接口CreateDispatch创建Excel应用,发现按钮状态就正常了,即可变成禁用的灰色状态。原因目前不明,可能跟创建了Excel应用之后会打开EXCEL.EXE程序有关。


4、程序退出时,CApplication对象必须调用接口Quit,否则程序退出后,任务管理器会存在一个EXCEL.EXE进程,这时重复运行程序会发现操作Excel的功能已不能正常应用。


5、如果调用AfxOleInit()函数初始化COM库,那么在程序退出时,所有的Excel类库对象都必须调用ReleaseDispatch释放对象,否则,即使CApplication对象调用了接口Quit,任务管理器也会存在一个EXCEL.EXE进程,直至程序完全退出这个EXCEL.EXE进程才跟着消失。


6、如果调用CoInitialize()和CoUninitialize()来完成COM库的初始化和反初始化,那么在程序退出时,所有的Excel类库对象都必须调用ReleaseDispatch释放对象,否则在调用CoUninitialize()时会导致程序崩溃。


7、在某些对象中有两个接口都可以指定所选功能(如边框、字体或填充)的颜色,就是put_Color()和put_ColorIndex(),最初没搞清楚这两个接口传入参数的区别,直到后来发现如果给put_ColorIndex()传入一个大于56的值,那么就会引起程序错误。既然出错了不能再装糊涂了,果断查阅MSDN,终于弄明白了,具体请看《Adding Color to Excel 2007 Worksheets by Using the ColorIndex Property》


以上几点内容,是我在开发时碰到过的,仅仅针对Visual Studio 2013和Office 2010,并且是基于MFC对话框的应用程序。在参考了《VC++6.0操作excel2007文件封装类CExcelServer》一文的代码后,我根据自己的理解,结合实际的开发需求,精简和完善了其中的部分代码,依样画葫芦整理出一个适合自己程序使用的操作类,其中没有什么技术含量,就不贴出来占用篇幅了。下面是本例中的Demo程序及其功能的一个演示:



奋斗总算记录完了,虽然顺着大神的道路走,然而还是得花一点时间来学习,并应用到实际的开发中加以尝试。文章最后再次感谢各位大神的无私奉献,为了继承前辈的传统,下面的链接给出了本例中Demo程序的实现源码。


猛戳这里,下载源码!


说明:以上代码在Visual Studio 2013通过测试,并且必须安装Office 2010。


没有更多推荐了,返回首页