c++操作Excel

来源:互联网 发布:udp3100端口 编辑:程序博客网 时间:2024/06/05 15:24
[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. 理论性的东西就是不讲了,简单的就是用微软提供的组件来操作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.添加创建文档或打开文档的实现代码:

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. void CcontrolExcelView::OnBnClickedButtonOpenFile()  
  2. {  
  3.     // TODO: 在此添加控件通知处理程序代码  
  4.   
  5.     LPDISPATCH lpDisp = NULL;  
  6.   
  7.     //创建Excel 服务器(启动Excel)  
  8.     if(!ExcelApp.CreateDispatch(_T("Excel.Application"),NULL))  
  9.     {  
  10.         AfxMessageBox(_T("启动Excel服务器失败!"));  
  11.         return;  
  12.     }  
  13.   
  14.     /*判断当前Excel的版本*/  
  15.     CString strExcelVersion = ExcelApp.get_Version();  
  16.     int iStart = 0;  
  17.     strExcelVersion = strExcelVersion.Tokenize(_T("."), iStart);  
  18.     if (_T("11") == strExcelVersion)  
  19.     {  
  20.         //AfxMessageBox(_T("当前Excel的版本是2003。"));  
  21.         GetDlgItem(IDC_EDIT_VERSIONS)->SetWindowText(_T("Excel2003"));  
  22.     }  
  23.     else if (_T("12") == strExcelVersion)  
  24.     {  
  25.         //AfxMessageBox(_T("当前Excel的版本是2007。"));  
  26.         GetDlgItem(IDC_EDIT_VERSIONS)->SetWindowText(_T("Excel2007"));  
  27.     }  
  28.     else  
  29.     {  
  30.         //AfxMessageBox(_T("当前Excel的版本是其他版本。"));  
  31.         GetDlgItem(IDC_EDIT_VERSIONS)->SetWindowText(_T("Excel"));  
  32.     }  
  33.   
  34.     ExcelApp.put_Visible(TRUE);  
  35.     ExcelApp.put_UserControl(TRUE);  
  36.   
  37.     /*得到工作簿容器*/  
  38.     books.AttachDispatch(ExcelApp.get_Workbooks());  
  39.   
  40.     /*打开一个工作簿,如不存在,则新增一个工作簿*/  
  41.     CString strBookPath = m_strPathName;  
  42.     try  
  43.     {  
  44.         /*打开一个工作簿*/  
  45.         lpDisp = books.Open(strBookPath,   
  46.             vtMissing, vtMissing, vtMissing, vtMissing, vtMissing,  
  47.             vtMissing, vtMissing, vtMissing, vtMissing, vtMissing,   
  48.             vtMissing, vtMissing, vtMissing, vtMissing);  
  49.         book.AttachDispatch(lpDisp);  
  50.     }  
  51.     catch(...)  
  52.     {  
  53.         /*增加一个新的工作簿*/  
  54.         lpDisp = books.Add(vtMissing);  
  55.         book.AttachDispatch(lpDisp);  
  56.     }  
  57.   
  58.     /*得到工作簿中的Sheet的容器*/  
  59.     sheets.AttachDispatch(book.get_Sheets());  
  60.     /*打开一个Sheet,如不存在,就新增一个Sheet*/  
  61.     CString strSheetName = _T("NewSheet");  
  62.     try  
  63.     {  
  64.         /*打开一个已有的Sheet*/  
  65.         lpDisp = sheets.get_Item(_variant_t(strSheetName));  
  66.         sheet.AttachDispatch(lpDisp);  
  67.     }  
  68.     catch(...)  
  69.     {  
  70.         /*创建一个新的Sheet*/  
  71.         lpDisp = sheets.Add(vtMissing, vtMissing, _variant_t((long)1), vtMissing);  
  72.         sheet.AttachDispatch(lpDisp);  
  73.         sheet.put_Name(strSheetName);  
  74.     }  
  75. }  
这里面注释已经够多了,我也不像废话了。


10.写入单元格的代码

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. void CcontrolExcelView::OnBnClickedButtonWrite()  
  2. {  
  3.     // TODO: 在此添加控件通知处理程序代码  
  4.     //获取单元格  
  5.     UpdateData(TRUE);  
  6.     CString strRange;  
  7.     strRange.Format(_T("%d"), m_lRow);  
  8.     strRange = m_strColumn + strRange;  
  9.     //获取range  
  10.     LPDISPATCH lpDisp = NULL;  
  11.     lpDisp = sheet.get_Range(COleVariant(strRange), COleVariant(strRange));  
  12.     range.AttachDispatch(lpDisp);  
  13.     range.put_Value(vtMissing, COleVariant(m_strRange));  
  14.   
  15. }  

11.读取单元格的代码

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. void CcontrolExcelView::OnBnClickedButtonRead()  
  2. {  
  3.     // TODO: 在此添加控件通知处理程序代码  
  4.     //获取单元格  
  5.     UpdateData(TRUE);  
  6.     CString strRange;  
  7.     strRange.Format(_T("%d"), m_lRow);  
  8.     strRange = m_strColumn + strRange;  
  9.     //获取range  
  10.     LPDISPATCH lpDisp = NULL;  
  11.     lpDisp = sheet.get_Range(COleVariant(strRange), COleVariant(strRange));  
  12.     range.AttachDispatch(lpDisp);  
  13.     VARIANT ret = range.get_Value(vtMissing);  
  14.       
  15.     switch (ret.vt)  
  16.     {  
  17.     case VT_R8:  
  18.         {  
  19.             m_strRange.Format(_T("%d"), (int)ret.dblVal);  
  20.         }  
  21.         break;  
  22.   
  23.     case VT_BSTR:  
  24.         {  
  25.             m_strRange = ret.bstrVal;  
  26.         }  
  27.         break;  
  28.   
  29.     case VT_I4:  
  30.         {  
  31.             m_strRange.Format(_T("%ld"), (int)ret.lVal);  
  32.         }  
  33.         break;  
  34.   
  35.     default:  
  36.         {  
  37.   
  38.         }  
  39.         break;  
  40.     }  
  41.     UpdateData(FALSE);  
  42. }  

12.改变单元格边框的实现代码

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. void CcontrolExcelView::OnBnClickedButtonStyle()  
  2. {  
  3.     // TODO: 在此添加控件通知处理程序代码  
  4.     //获取单元格  
  5.     UpdateData(TRUE);  
  6.     CString strRange;  
  7.     strRange.Format(_T("%d"), m_lRow);  
  8.     strRange = m_strColumn + strRange;  
  9.     //获取range  
  10.     LPDISPATCH lpDisp = NULL;  
  11.     lpDisp = sheet.get_Range(COleVariant(strRange), COleVariant(strRange));  
  12.     range.AttachDispatch(lpDisp);  
  13.   
  14.     // 然后设置外边框    
  15.     // LineStyle=线型(1~13) Weight=线宽 ColorIndex=线的颜色(-4105为自动, 1为黑色)     
  16.     long lColor  = RGB(255, 0, 0);  
  17.     COleVariant varColor(lColor);  
  18.     range.BorderAround(_variant_t(long(3)), 3, 3, vtMissing);//设置边框   
  19.   
  20. }  

13.改变单元格字体的实现代码

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. void CcontrolExcelView::OnBnClickedButtonFont()  
  2. {  
  3.     // TODO: 在此添加控件通知处理程序代码  
  4.     UpdateData(TRUE);  
  5.     CString strRange;  
  6.     strRange.Format(_T("%d"), m_lRow);  
  7.     strRange = m_strColumn + strRange;  
  8.     //获取range  
  9.     LPDISPATCH lpDisp = NULL;  
  10.     lpDisp = sheet.get_Range(COleVariant(strRange), COleVariant(strRange));  
  11.     range.AttachDispatch(lpDisp);  
  12.   
  13.     CFont0 ft;  
  14.     ft.AttachDispatch(range.get_Font());  
  15.     ft.put_Name(_variant_t(_T("华文行楷")));  
  16.     ft.put_Size(_variant_t(8));  
  17.     ft.put_Color(_variant_t(RGB(255, 0, 0)));  
  18.       
  19. }  

14.改变单元格底色的实现代码

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. void CcontrolExcelView::OnBnClickedButtonDise()  
  2. {  
  3.     // TODO: 在此添加控件通知处理程序代码  
  4.     UpdateData(TRUE);  
  5.     CString strRange;  
  6.     strRange.Format(_T("%d"), m_lRow);  
  7.     strRange = m_strColumn + strRange;  
  8.     //获取range  
  9.     LPDISPATCH lpDisp = NULL;  
  10.     lpDisp = sheet.get_Range(COleVariant(strRange), COleVariant(strRange));  
  11.     range.AttachDispatch(lpDisp);  
  12.   
  13.     //改变底色  
  14.     Cnterior interior;  
  15.     interior.AttachDispatch(range.get_Interior());  
  16.     interior.put_ColorIndex(_variant_t((long)20));  //将底色改为浅青色  
  17. }  

15.保存文件的实现代码

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. void CcontrolExcelView::OnBnClickedButtonSave()  
  2. {  
  3.     // TODO: 在此添加控件通知处理程序代码  
  4.     book.Save();  
  5.   
  6.     ExcelApp.Quit();  
  7.     //释放  
  8.     range.ReleaseDispatch();  
  9.     sheet.ReleaseDispatch();  
  10.     sheets.ReleaseDispatch();  
  11.     book.ReleaseDispatch();  
  12.     books.ReleaseDispatch();  
  13.     ExcelApp.ReleaseDispatch();  
  14. }  


16.学习遇到的问题:

1)VS2010的操作界面就那样,但是网站找的资料都是vc6.0的操作界面。总之,添加一个组件,对于一个新手来说也是艰辛的旅程。而代码,好说直接Copy就是了。对于任何一个菜鸟来说,抄代码还不容易。不过,这玩意儿看起来高大上,实现以后,并没有什么成就感。当然了,问题肯定是本菜鸟学的不够深。

2)想想看,改变一个底色也要一个类,然后那个类里面甚至有上百个函数,每个函数的参数类型,数值范围,作用功能等,基本上只能从参数名和函数名去判断。而且,因为时代在进一步,名字也变了,网上有些资料已经过时了。比如,现在函数是用put_XXX,旧版本的是用set_XXX。不明真相的群众要搞半天才恍然大悟。你妹的。不知道有谁有参考手册?我是没找到。


3)这项技术应用吗?用在大量地输入资料到excel上应该相当不错。当然了,要看是从哪个地方获取数据了,如果是数据库,我写过应不是问题;如果是文本,那么更加没有问题了;如果是word呢?那么你得去学下怎样从word获取数据了,也就是相关的组件;如果会死网页,呵呵你还得去学习下有关浏览器的组件。委屈学无止境啊。


17.参考资料

http://blog.csdn.NET/circlesquare/article/details/7220776

0 0