理论性的东西就是不讲了,简单的就是用微软提供的组件来操作excel。我们先看看如何添加相关组件。
1.进入类导向对话框:
2.点击下拉菜单“添加类”,选择“类型库中的MFC类‘
3.相关的类行库可以从注册表中找,你选择一个”可用类行库“,向导会自动显示它的接口。还有另外一种方式,通过添加文件也能获取接口,这个可以百度得到,就不多说了。
4.选择接口,生成相应的类。
5.如何选择接口
有些接口是必须的,_Application,_Workbook,_Worksheet,Workbooks,Worksheets,Range等,如果要改变边框,底色和字体,还要选择Borders,Interior和Font。接口名字都是统一的,但还不同的工程生成的类不一定是一样的。为了避免与MFC里面的类相冲突,VS编译器会把Font接口的类生成为CFont0,说不定CFont1也不一定,就看编译器那天心情好不好。
6.修改代码:
相关的类生成完毕后,还是不能用的。
#import "C:\\Program Files (x86)\\Microsoft Office\\Office12\\EXCEL.EXE" no_namespace,每个生成的类里面都有这么一行代码,导入相关的组件。该库只要导入一次就行了,所以其他文件的该行代码可以注释掉或者删掉了。一般是保留_Application生成的那个类里面的代码,当然了,要保证该头文件是最早被引用的,要不然肯定会出现一大堆未定义。那么做完这些事情结束了吗?当然没有。
7.继续修改代码
把上面那行import代码改成如下:
#import "C:\\Program Files (x86)\\Common Files\\Microsoft Shared\\OFFICE12\\MSO.DLL" \
rename("RGB", "MSORGB") \
rename("DocumentProperties", "MSODocumentProperties")
using namespace Office;
#import "C:\\Program Files (x86)\\Common Files\\Microsoft Shared\\VBA\\VBA6\\VBE6EXT.OLB"
using namespace VBIDE;
#import "C:\\Program Files (x86)\\Microsoft Office\\Office12\\EXCEL.EXE" \
rename("DialogBox", "ExcelDialogBox") \
rename("RGB", "ExcelRGB") \
rename("CopyFile", "ExcelCopyFile") \
rename("ReplaceText", "ExcelReplaceText") \
no_auto_exclude
using namespace Excel;
不要问我为什么,我是新手,不懂。总之,网络上的大佬是这么做的就对了。
8.你们认为没问题吗?我不觉得。我这里出现了一个重复定义的错误,CRange类的,然后我给头文件加了一行代码,”#progma once“,就可以了。总之,你们自己随机应变吧。我的这个问题应该是非主流的。
9.添加创建文档或打开文档的实现代码:
void CcontrolExcelView::OnBnClickedButtonOpenFile()
{
// TODO: 在此添加控件通知处理程序代码
LPDISPATCH lpDisp = NULL;
//创建Excel 服务器(启动Excel)
if(!ExcelApp.CreateDispatch(_T("Excel.Application"),NULL))
{
AfxMessageBox(_T("启动Excel服务器失败!"));
return;
}
/*判断当前Excel的版本*/
CString strExcelVersion = ExcelApp.get_Version();
int iStart = 0;
strExcelVersion = strExcelVersion.Tokenize(_T("."), iStart);
if (_T("11") == strExcelVersion)
{
//AfxMessageBox(_T("当前Excel的版本是2003。"));
GetDlgItem(IDC_EDIT_VERSIONS)->SetWindowText(_T("Excel2003"));
}
else if (_T("12") == strExcelVersion)
{
//AfxMessageBox(_T("当前Excel的版本是2007。"));
GetDlgItem(IDC_EDIT_VERSIONS)->SetWindowText(_T("Excel2007"));
}
else
{
//AfxMessageBox(_T("当前Excel的版本是其他版本。"));
GetDlgItem(IDC_EDIT_VERSIONS)->SetWindowText(_T("Excel"));
}
ExcelApp.put_Visible(TRUE);
ExcelApp.put_UserControl(TRUE);
/*得到工作簿容器*/
books.AttachDispatch(ExcelApp.get_Workbooks());
/*打开一个工作簿,如不存在,则新增一个工作簿*/
CString strBookPath = m_strPathName;
try
{
/*打开一个工作簿*/
lpDisp = books.Open(strBookPath,
vtMissing, vtMissing, vtMissing, vtMissing, vtMissing,
vtMissing, vtMissing, vtMissing, vtMissing, vtMissing,
vtMissing, vtMissing, vtMissing, vtMissing);
book.AttachDispatch(lpDisp);
}
catch(...)
{
/*增加一个新的工作簿*/
lpDisp = books.Add(vtMissing);
book.AttachDispatch(lpDisp);
}
/*得到工作簿中的Sheet的容器*/
sheets.AttachDispatch(book.get_Sheets());
/*打开一个Sheet,如不存在,就新增一个Sheet*/
CString strSheetName = _T("NewSheet");
try
{
/*打开一个已有的Sheet*/
lpDisp = sheets.get_Item(_variant_t(strSheetName));
sheet.AttachDispatch(lpDisp);
}
catch(...)
{
/*创建一个新的Sheet*/
lpDisp = sheets.Add(vtMissing, vtMissing, _variant_t((long)1), vtMissing);
sheet.AttachDispatch(lpDisp);
sheet.put_Name(strSheetName);
}
}
这里面注释已经够多了,我也不像废话了。
10.写入单元格的代码
void CcontrolExcelView::OnBnClickedButtonWrite()
{
// TODO: 在此添加控件通知处理程序代码
//获取单元格
UpdateData(TRUE);
CString strRange;
strRange.Format(_T("%d"), m_lRow);
strRange = m_strColumn + strRange;
//获取range
LPDISPATCH lpDisp = NULL;
lpDisp = sheet.get_Range(COleVariant(strRange), COleVariant(strRange));
range.AttachDispatch(lpDisp);
range.put_Value(vtMissing, COleVariant(m_strRange));
}
11.读取单元格的代码
void CcontrolExcelView::OnBnClickedButtonRead()
{
// TODO: 在此添加控件通知处理程序代码
//获取单元格
UpdateData(TRUE);
CString strRange;
strRange.Format(_T("%d"), m_lRow);
strRange = m_strColumn + strRange;
//获取range
LPDISPATCH lpDisp = NULL;
lpDisp = sheet.get_Range(COleVariant(strRange), COleVariant(strRange));
range.AttachDispatch(lpDisp);
VARIANT ret = range.get_Value(vtMissing);
switch (ret.vt)
{
case VT_R8:
{
m_strRange.Format(_T("%d"), (int)ret.dblVal);
}
break;
case VT_BSTR:
{
m_strRange = ret.bstrVal;
}
break;
case VT_I4:
{
m_strRange.Format(_T("%ld"), (int)ret.lVal);
}
break;
default:
{
}
break;
}
UpdateData(FALSE);
}
12.改变单元格边框的实现代码
void CcontrolExcelView::OnBnClickedButtonStyle()
{
// TODO: 在此添加控件通知处理程序代码
//获取单元格
UpdateData(TRUE);
CString strRange;
strRange.Format(_T("%d"), m_lRow);
strRange = m_strColumn + strRange;
//获取range
LPDISPATCH lpDisp = NULL;
lpDisp = sheet.get_Range(COleVariant(strRange), COleVariant(strRange));
range.AttachDispatch(lpDisp);
// 然后设置外边框
// LineStyle=线型(1~13) Weight=线宽 ColorIndex=线的颜色(-4105为自动, 1为黑色)
long lColor = RGB(255, 0, 0);
COleVariant varColor(lColor);
range.BorderAround(_variant_t(long(3)), 3, 3, vtMissing);//设置边框
}
13.改变单元格字体的实现代码
void CcontrolExcelView::OnBnClickedButtonFont()
{
// TODO: 在此添加控件通知处理程序代码
UpdateData(TRUE);
CString strRange;
strRange.Format(_T("%d"), m_lRow);
strRange = m_strColumn + strRange;
//获取range
LPDISPATCH lpDisp = NULL;
lpDisp = sheet.get_Range(COleVariant(strRange), COleVariant(strRange));
range.AttachDispatch(lpDisp);
CFont0 ft;
ft.AttachDispatch(range.get_Font());
ft.put_Name(_variant_t(_T("华文行楷")));
ft.put_Size(_variant_t(8));
ft.put_Color(_variant_t(RGB(255, 0, 0)));
}
14.改变单元格底色的实现代码
void CcontrolExcelView::OnBnClickedButtonDise()
{
// TODO: 在此添加控件通知处理程序代码
UpdateData(TRUE);
CString strRange;
strRange.Format(_T("%d"), m_lRow);
strRange = m_strColumn + strRange;
//获取range
LPDISPATCH lpDisp = NULL;
lpDisp = sheet.get_Range(COleVariant(strRange), COleVariant(strRange));
range.AttachDispatch(lpDisp);
//改变底色
Cnterior interior;
interior.AttachDispatch(range.get_Interior());
interior.put_ColorIndex(_variant_t((long)20)); //将底色改为浅青色
}
15.保存文件的实现代码
void CcontrolExcelView::OnBnClickedButtonSave()
{
// TODO: 在此添加控件通知处理程序代码
book.Save();
ExcelApp.Quit();
//释放
range.ReleaseDispatch();
sheet.ReleaseDispatch();
sheets.ReleaseDispatch();
book.ReleaseDispatch();
books.ReleaseDispatch();
ExcelApp.ReleaseDispatch();
}
16.我的软件效果图
17.学习遇到的问题:
1)VS2010的操作界面就那样,但是网站找的资料都是vc6.0的操作界面。总之,添加一个组件,对于一个新手来说也是艰辛的旅程。而代码,好说直接Copy就是了。对于任何一个菜鸟来说,抄代码还不容易。不过,这玩意儿看起来高大上,实现以后,并没有什么成就感。当然了,问题肯定是本菜鸟学的不够深。
2)想想看,改变一个底色也要一个类,然后那个类里面甚至有上百个函数,每个函数的参数类型,数值范围,作用功能等,基本上只能从参数名和函数名去判断。而且,因为时代在进一步,名字也变了,网上有些资料已经过时了。比如,现在函数是用put_XXX,旧版本的是用set_XXX。不明真相的群众要搞半天才恍然大悟。你妹的。不知道有谁有参考手册?我是没找到。
3)这项技术应用吗?用在大量地输入资料到excel上应该相当不错。当然了,要看是从哪个地方获取数据了,如果是数据库,我写过应不是问题;如果是文本,那么更加没有问题了;如果是word呢?那么你得去学下怎样从word获取数据了,也就是相关的组件;如果会死网页,呵呵你还得去学习下有关浏览器的组件。学无止境啊。
18.参考资料
http://blog.csdn.net/circlesquare/article/details/7220776