用C++ MFC实现list控件对Excel的读取和写入

微软为VS与Excel的通信编程提供了专门的接口,在进行对Excel的操作前,应当先导入相应的操作库。

在解决方案资源管理器中右击工程名,选择类向导,选中 类型库中的MFC类,弹出的对话框可以看到里面提供了很多接口,写入和读取的话只需要从中添加六个接口,生成对应的六个类就可以了。六个接口分别为Worksheets,Workbooks,_Worksheet,_Workbook,_Application,Range。自动生成的类如下图所示:

用C++ MFC实现list控件对Excel的读取和写入_第1张图片

 

在生成的六个类的头文件中,都会有下面这句:

#import "C:\\Program Files\\Microsoft Office\\Office14\\EXCEL.EXE" no_namespace

将每一个头文件中的这一句都注释掉,再添加头文件,在需要用到的程序中添加,我直接新建了一个专门用于文件存取的类,直接在类的头文件中添加下面语句:

#include"CApplication.h"
#include"CRange.h"
#include"CWorkbook.h"
#include"CWorkbooks.h"
#include"CWorksheets.h"
#include"CWorksheet.h"
#include "afxcmn.h"
#include

此外还要修改一个地方,此时编译的话会有一个错误,双击错误列表中的错误提示,在DialogBox()前面加一个下划线,此时,编译就能通过了。

再为这几个类创建对象,我是直接放在的创建类的头文件中,也可以在使用功能的源文件中做此操作

CApplication app;
CRange range;
CRange usedrange;
CWorkbook book;
CWorkbooks books;
CWorksheets sheets;
CWorksheet sheet;

下面就是列表控件写入和读取Excel文件的具体实现了,我把实现都封装成了专门的函数,可用于以后的调用,先讲将list控件的数据写入Excel:

list控件写入Excel

void ListToExcel(CListCtrl *datalist, CString filepath, CString str[], int rowcount, int colcount);

这是我定义的函数原型,五个参数含义分别为

控件变量,存储路径,表头数组,控件行数,控件列数

任何地方只要往里传这五个参数就可以实现list控件写入Excel,具体代码如下:

void CFileRW::ListToExcel(CListCtrl *datalist, CString filepath, CString str[], int rowcount, int colcount)   //列表控件变量,存储文件路径,列表头的字符串数组,控件行数,控件列数
{
	//list控件数据写入Excel
	COleVariant
		covTrue((short)TRUE),
		covFalse((short)FALSE),
		covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
	//创建Excel 服务器(启动Excel)
	if (!app.CreateDispatch(_T("Excel.Application"), NULL))
	{
		AfxMessageBox(_T("启动Excel服务器失败!"));
		return;
	}

/*得到工作簿容器*/
	books.AttachDispatch(app.get_Workbooks());	
/*增加一个新的工作簿*/
	lpdisp = books.Add(covOptional);
	book.AttachDispatch(lpdisp);
	/*得到工作簿中的Sheet的容器*/
	sheets.AttachDispatch(book.get_Sheets());
	sheet = sheets.get_Item(COleVariant((short)1));   //得到第一个工作表
	CHeaderCtrl   *pmyHeaderCtrl = datalist->GetHeaderCtrl(); //获取表头
	usedrange.AttachDispatch(sheet.get_UsedRange());
try
	{
		//获取当前读取的EXCEL中活动的sheet
		usedrange.AttachDispatch(sheet.get_Cells());
		//清空Excel中的内容
		usedrange.ClearContents();
		//填入列名
		for (int i = 1; i <= colcount; i++)
		{
			range.AttachDispatch(usedrange.get_Item((_variant_t((long)1)),
				(_variant_t)(long)i).pdispVal);
			range.put_Value2((_variant_t (str[i-1])));
		}
//填充新内容
		CString	 str1;
		for (int row = 0; row < rowcount; row++)
		{
			for (int col = 0; col < colcount; col++)
			{
				str1 = datalist->GetItemText(row, col);
				range.AttachDispatch(usedrange.get_Item(_variant_t((long)row + 2),
					_variant_t((long)col + 1)).pdispVal);
				range.put_Value2(_variant_t(str1));
			}
		}
book.SaveAs(COleVariant(filepath), covOptional, covOptional, covOptional,
			covOptional, covOptional, 1, covOptional, covOptional, covOptional,
			covOptional, covOptional);
		release();
		AfxMessageBox(L"保存成功");
		//m_used_range.AttachDispatch(m_used_range.get_Item(COleVariant((long)1), (COleVariant)(long)1).pdispVal);
	}
	catch (CException *e)
	{
		release();
		AfxMessageBox(L"保存失败");
	}

不要忘了资源用完以后需要释放资源,我自己定义了一个资源释放函数release(),具体代码如下:

usedrange.ReleaseDispatch();
	range.ReleaseDispatch();
	sheet.ReleaseDispatch();
	sheets.ReleaseDispatch();
	book.ReleaseDispatch();
	books.ReleaseDispatch();
	app.Quit();
	app.ReleaseDispatch();

以上就是list控件写入Excel函数的源代码,具体函数调用方式如下:

CString strlisthead[3];           //输入列表头
	strlisthead[0] = L"姓名";
    strlisthead[1] = L"学号";
	strlisthead[2] = L"性别";
CString strBookPath = _T("D:\\123.xlsx");      //存储文件路径
int colcount = m_datalist.GetHeaderCtrl()->GetItemCount();   //求控件列数
int rowcount = m_datalist.GetItemCount();           //求控件行数
//函数调用
filerw.ListToExcel(&m_datalist, strBookPath, strlisthead, rowcount, colcount);

 

以上就是list控件写入Excel的功能实现代码,我自己试验过是可以的,如果有什么问题的话欢迎一起讨论。list控件读取显示Excel内容将会在下一篇中写到。

第一次发帖子,说的可能不是特别详细清晰,有什么问题可以在评论里一起讨论,我看到的话会及时回复,希望对大家能够有帮助,谢谢。

你可能感兴趣的:(C++,C,MFC,Excel,C,文件操作)