微软为VS与Excel的通信编程提供了专门的接口,在进行对Excel的操作前,应当先导入相应的操作库。
在解决方案资源管理器中右击工程名,选择类向导,选中 类型库中的MFC类,弹出的对话框可以看到里面提供了很多接口,写入和读取的话只需要从中添加六个接口,生成对应的六个类就可以了。六个接口分别为Worksheets,Workbooks,_Worksheet,_Workbook,_Application,Range。自动生成的类如下图所示:
在生成的六个类的头文件中,都会有下面这句:
#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:
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内容将会在下一篇中写到。
第一次发帖子,说的可能不是特别详细清晰,有什么问题可以在评论里一起讨论,我看到的话会及时回复,希望对大家能够有帮助,谢谢。