向EXCEL模板文件中写入数据和插入新行

在很多情况下,我们需要将程序产生的一些数据按照一些用户要求的EXCEL文件模板格式进行填写,将指定的数据项写入指定的单元格。在某些特定的情况下,可能还需要进行动态的行插入,比如数量不确定的点坐标信息,要求每行记录一个点坐标信息时。另外,用模板生成的文件,需要进行文件另存,以免将模板文件覆盖。

基于以上目的,笔者采用通用的网络搜魂大法,几经周折,几多测试,终于完成了以上功能,在此与大家共享。

之前曾经使用过CSpreadSheet类进行EXCEL读写,不过貌似这个类不能用于模板EXCEL的填写,只能对新建EXCEL文件进行操作。

闲话少说,下面就介绍如何完成以上工作的吧。

1。需要在工程中初始化OLE

if(!AfxOleInit())///初始化COM库

{

AfxMessageBox("初始化COM失败");

return FALSE;

}

这段代码我一般会放在应用程序类的InitInstance函数的开头部分。

2。插入EXCEL模块

使用Classwizard中,点击右侧第一个按钮“AddClass...”,在弹出的下拉菜单中选择“From a type library...”

在弹出的目录选择对话框中,选择Office安装目录下的EXCEL.EXE文件

将弹出需要导入的模块选择窗口,如果嫌麻烦,那就将列表中的模块全部选中。选中的办法是直接拖拉选中,或者按住SHIFT键后,选择第一个和最后一个即可。(该死,怎么不支持CTRL+A呢)

点击“OK”即可将所有模块插入工程。此时看一下工程文件,会发现多了EXCEL.h和EXCEL.CPP两个文件。

3。编写代码

环境已经准备好了,假设现在的测试工程是点击一个按钮,在按钮事件中完成模板文件单元格数据的填写、动态行的插入以及文件的存储。

首先注意要将EXCEL.h文件包含进来:

#include "comdef.h" //这个也需要哦,不然_variant_t不认识
#include "excel.h"

这里假设将EXCEL对象作为成员变量:(这个主要看工程中具体的应用了)

Range m_ExlRge;
_Worksheet m_ExlSheet;
Worksheets m_ExlSheets;
_Workbook m_ExlBook;
Workbooks m_ExlBooks;
_Application m_ExlApp;

然后在按钮的点击事件中增加处理代码,具体代码的含义就看注释吧。

void CTTTDlg::OnButton1() { //用m_ExlApp对象创建Excel2003进程 if(!m_ExlApp.CreateDispatch("Excel.Application",NULL)) { AfxMessageBox("创建Excel服务失败!"); return; } //设置为不可见,这样就不会弹出EXCEL窗口了 m_ExlApp.SetVisible(FALSE); ///下面得到应用程序所在的路径/// CString theAppPath; // //此段省略获得应用程序根目录的代码 // CString TempPath = theAppPath+"ShipInfoTemp.xls";//EXCEL模板的路径 m_ExlBooks.AttachDispatch(m_ExlApp.GetWorkbooks(),TRUE); m_ExlBook.AttachDispatch(m_ExlBooks.Add((_variant_t)TempPath),TRUE);//加载EXCEL模板 m_ExlSheets.AttachDispatch(m_ExlBook.GetSheets(),TRUE);//加载Sheet页面 //修改Sheet页面的名称,第一页从1开始,不是0哦!后面涉及到编号的地方都是如此,要注意阿 m_ExlSheet.AttachDispatch(m_ExlSheets.GetItem(_variant_t((long)1)),TRUE); m_ExlSheet.SetName("1106号台风"); //根据实际受台风影响的船舶的数量,动态改变船舶信息的行数,这里假设只增加一行,插入在第12行之前 Range rangeSelect; rangeSelect.AttachDispatch(m_ExlSheet.GetRange(_variant_t("A12"),_variant_t("D12")),TRUE); Range rangeInsert = rangeSelect.GetEntireRow();//选择第12行 //这里特别说明一下-4121,在ASP.NET和VB等工具下,表示xlShiftDown,指将行向下挤,VC下没找到,所以只能用直接的数值了 rangeInsert.Insert(COleVariant((long)-4121),vtMissing); //在12行之前插入 rangeSelect.ReleaseDispatch(); rangeInsert.ReleaseDispatch(); //开始向各个单元格填入数据 m_ExlRge.AttachDispatch(m_ExlSheet.GetCells(),TRUE);//加载所有单元格 //此段可以循环插入船舶信息,这里以插入一条船来举例 m_ExlRge.SetItem(_variant_t((long)8),_variant_t((long)1),_variant_t("1")); m_ExlRge.SetItem(_variant_t((long)8),_variant_t((long)2),_variant_t("雪龙号")); m_ExlRge.SetItem(_variant_t((long)8),_variant_t((long)3),_variant_t("201106270800")); m_ExlRge.SetItem(_variant_t((long)8),_variant_t((long)4),_variant_t("京唐/南沙")); m_ExlRge.SetItem(_variant_t((long)8),_variant_t((long)5),_variant_t("3901N")); m_ExlRge.SetItem(_variant_t((long)8),_variant_t((long)6),_variant_t("12138E")); //将编辑完成的内容保存为新文件,这里的文件名可以根据需要动态产生。 m_ExlSheet.SaveAs(theAppPath + "newdata.xls",vtMissing,vtMissing,vtMissing,vtMissing,vtMissing,vtMissing,vtMissing,vtMissing,vtMissing); //释放对象 m_ExlRge.ReleaseDispatch(); m_ExlSheet.ReleaseDispatch(); m_ExlSheets.ReleaseDispatch(); m_ExlBook.ReleaseDispatch(); m_ExlBooks.ReleaseDispatch(); //m_ExlApp一定要退出程序,否则程序结束后还会有一个Excel进程驻留在内存中,而且程序重复运行的时候会出错 m_ExlApp.Quit(); m_ExlApp.ReleaseDispatch(); } 本段代码在XP系统,EXCEL 2003,VC6环境下测试成功。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值