VS2010通过OLE操作Excel2010

来源:互联网 发布:巴克利生涯数据 编辑:程序博客网 时间:2024/05/16 01:10

我使用的语言是C++,网上有许多这方面的例子,但由于VS与Office版本的问题,都需要一些调整,下面是我在使用时遇到的一些问题集解决方法:

操作步骤:

a. project->add class->MFC class from typelib 导入Excel.exe,一般都在C:/Program Files/Microsoft Office/Office14路径下;

b. 选中以下几项_Application,_WorkSheet,_WorkBook,WorkSheets,WorkBooks,Range,然后导入;




c. 导入后在工程中添加CApplication,CWorkSheet,CWorkBook,CWorkSheets,CWorkBooks,CRange这些类;

然后需要把这些类的头文件中的第一句话 #import ".......EXCEL.EXE" nonamespace 删除;

引入之后如果编译遇到错误,Not enough actual parameters for macro 'DialogBoxW'. 让人头疼!

解决方法是在CRange类中,

VARIANT DialogBox()
{
  VARIANT result;
  InvokeHelper(0xf5, DISPATCH_METHOD, VT_VARIANT, (void*)&result, NULL);
  return result;
}

 

DialogBox()前面添加下划线变成_DialogBox(),解决了!

d.添加头文件OperateExcelFile.h

[cpp] view plain copy
  1. #pragma once  
  2.   
  3. //OLE的头文件  
  4. #include "CRange.h"  
  5. #include "CWorkbook.h"  
  6. #include "CWorkbooks.h"  
  7. #include "CWorksheet.h"  
  8. #include "CWorksheets.h"  
  9. #include "CApplication.h"  
  10.   
  11. ///  
  12. ///用于OLE的方式的EXCEL读写,  
  13. class IllusionExcelFile  
  14. {  
  15.   
  16. public:  
  17.   
  18.     //构造函数和析构函数  
  19.     IllusionExcelFile();  
  20.     virtual ~IllusionExcelFile();  
  21.   
  22. protected:  
  23.     ///打开的EXCEL文件名称  
  24.     CString       open_excel_file_;  
  25.   
  26.     ///EXCEL BOOK集合,(多个文件时)  
  27.     CWorkbooks    excel_books_;   
  28.     ///当前使用的BOOK,当前处理的文件  
  29.     CWorkbook     excel_work_book_;   
  30.     ///EXCEL的sheets集合  
  31.     CWorksheets   excel_sheets_;   
  32.     ///当前使用sheet  
  33.     CWorksheet    excel_work_sheet_;   
  34.     ///当前的操作区域  
  35.     CRange        excel_current_range_;   
  36.   
  37.   
  38.     ///是否已经预加载了某个sheet的数据  
  39.     BOOL          already_preload_;  
  40.     ///Create the SAFEARRAY from the VARIANT ret.  
  41.     COleSafeArray ole_safe_array_;  
  42.   
  43. protected:  
  44.   
  45.     ///EXCEL的进程实例  
  46.     static CApplication excel_application_;  
  47. public:  
  48.   
  49.     ///  
  50.     void ShowInExcel(BOOL bShow);  
  51.   
  52.     ///检查一个CELL是否是字符串  
  53.     BOOL    IsCellString(long iRow, long iColumn);  
  54.     ///检查一个CELL是否是数值  
  55.     BOOL    IsCellInt(long iRow, long iColumn);  
  56.   
  57.     ///得到一个CELL的String  
  58.     CString GetCellString(long iRow, long iColumn);  
  59.     ///得到整数  
  60.     int     GetCellInt(long iRow, long iColumn);  
  61.     ///得到double的数据  
  62.     double  GetCellDouble(long iRow, long iColumn);  
  63.   
  64.     ///取得行的总数  
  65.     int GetRowCount();  
  66.     ///取得列的总数  
  67.     int GetColumnCount();  
  68.   
  69.     ///使用某个shet,shit,shit  
  70.     BOOL LoadSheet(long table_index,BOOL pre_load = FALSE);  
  71.     ///通过名称使用某个sheet,  
  72.     BOOL LoadSheet(LPCTSTR sheet,BOOL pre_load = FALSE);  
  73.     ///通过序号取得某个Sheet的名称  
  74.     CString GetSheetName(long table_index);  
  75.   
  76.     ///得到Sheet的总数  
  77.     int GetSheetCount();  
  78.   
  79.     ///打开文件  
  80.     BOOL OpenExcelFile(LPCTSTR file_name);  
  81.     ///关闭打开的Excel 文件,有时候打开EXCEL文件就要  
  82.     void CloseExcelFile(BOOL if_save = FALSE);  
  83.     //另存为一个EXCEL文件  
  84.     void SaveasXSLFile(const CString &xls_file);  
  85.     ///取得打开文件的名称  
  86.     CString GetOpenFileName();  
  87.     ///取得打开sheet的名称  
  88.     CString GetLoadSheetName();  
  89.   
  90.     ///写入一个CELL一个int  
  91.     void SetCellInt(long irow, long icolumn,int new_int);  
  92.     ///写入一个CELL一个string  
  93.     void SetCellString(long irow, long icolumn,CString new_string);  
  94.   
  95. public:  
  96.     ///初始化EXCEL OLE  
  97.     static BOOL InitExcel();  
  98.     ///释放EXCEL的 OLE  
  99.     static void ReleaseExcel();  
  100.     ///取得列的名称,比如27->AA  
  101.     static char *GetColumnName(long iColumn);  
  102.   
  103. protected:  
  104.   
  105.     //预先加载  
  106.     void PreLoadSheet();  
  107. };  

e.添加cpp文件OperateExcelFile.cpp

[cpp] view plain copy
  1. #include "StdAfx.h"  
  2. #include "IllusionExcelFile.h"  
  3.   
  4.   
  5.   
  6. COleVariant  
  7. covTrue((short)TRUE),  
  8. covFalse((short)FALSE),  
  9. covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);      
  10.   
  11. //  
  12. CApplication IllusionExcelFile::excel_application_;  
  13.   
  14.   
  15. IllusionExcelFile::IllusionExcelFile():  
  16.     already_preload_(FALSE)  
  17. {  
  18. }  
  19.   
  20. IllusionExcelFile::~IllusionExcelFile()  
  21. {  
  22.     //  
  23.     CloseExcelFile();  
  24. }  
  25.   
  26.   
  27. //初始化EXCEL文件,  
  28. BOOL IllusionExcelFile::InitExcel()  
  29. {  
  30.   
  31.     CoUninitialize();  
  32.     if(CoInitialize(NULL)==S_FALSE)   
  33.     {   
  34.         AfxMessageBox(_T("初始化COM支持库失败!"));   
  35.         return FALSE;   
  36.     }  
  37.     //创建Excel 2000服务器(启动Excel)   
  38.     if (!excel_application_.CreateDispatch(_T("Excel.Application"),NULL))   
  39.     {   
  40.         AfxMessageBox(_T("创建Excel服务失败,你可能没有安装EXCEL,请检查!"));   
  41.         return FALSE;  
  42.     }  
  43.   
  44.     excel_application_.put_DisplayAlerts(FALSE);   
  45.     return TRUE;  
  46. }  
  47.   
  48. //  
  49. void IllusionExcelFile::ReleaseExcel()  
  50. {  
  51.     excel_application_.Quit();  
  52.     excel_application_.ReleaseDispatch();  
  53.     excel_application_=NULL;  
  54. }  
  55.   
  56. //打开excel文件  
  57. BOOL IllusionExcelFile::OpenExcelFile(LPCTSTR file_name)  
  58. {  
  59.     //先关闭  
  60.     CloseExcelFile();  
  61.       
  62.     //利用模板文件建立新文档   
  63.     excel_books_.AttachDispatch(excel_application_.get_Workbooks(),true);   
  64.   
  65.     LPDISPATCH lpDis = NULL;  
  66.     lpDis = excel_books_.Add(COleVariant(file_name));   
  67.     if (lpDis)  
  68.     {  
  69.         excel_work_book_.AttachDispatch(lpDis);   
  70.         //得到Worksheets   
  71.         excel_sheets_.AttachDispatch(excel_work_book_.get_Worksheets(),true);   
  72.           
  73.         //记录打开的文件名称  
  74.         open_excel_file_ = file_name;  
  75.   
  76.         return TRUE;  
  77.     }  
  78.       
  79.     return FALSE;  
  80. }  
  81.   
  82. //关闭打开的Excel 文件,默认情况不保存文件  
  83. void IllusionExcelFile::CloseExcelFile(BOOL if_save)  
  84. {  
  85.     //如果已经打开,关闭文件  
  86.     if (open_excel_file_.IsEmpty() == FALSE)  
  87.     {  
  88.         //如果保存,交给用户控制,让用户自己存,如果自己SAVE,会出现莫名的等待  
  89.         if (if_save)  
  90.         {  
  91.             ShowInExcel(TRUE);  
  92.         }  
  93.         else  
  94.         {  
  95.             //  
  96.             excel_work_book_.Close(COleVariant(short(FALSE)),COleVariant(open_excel_file_),covOptional);  
  97.             excel_books_.Close();  
  98.         }  
  99.   
  100.         //打开文件的名称清空  
  101.         open_excel_file_.Empty();  
  102.     }  
  103.   
  104.       
  105.   
  106.     excel_sheets_.ReleaseDispatch();  
  107.     excel_work_sheet_.ReleaseDispatch();  
  108.     excel_current_range_.ReleaseDispatch();  
  109.     excel_work_book_.ReleaseDispatch();  
  110.     excel_books_.ReleaseDispatch();  
  111. }  
  112.   
  113. void IllusionExcelFile::SaveasXSLFile(const CString &xls_file)  
  114. {  
  115.     excel_work_book_.SaveAs(COleVariant(xls_file),  
  116.         covOptional,  
  117.         covOptional,  
  118.         covOptional,  
  119.         covOptional,  
  120.         covOptional,  
  121.         0,  
  122.         covOptional,  
  123.         covOptional,  
  124.         covOptional,  
  125.         covOptional,  
  126.         covOptional);  
  127.     return;  
  128. }  
  129.   
  130.   
  131. int IllusionExcelFile::GetSheetCount()  
  132. {  
  133.     return excel_sheets_.get_Count();  
  134. }  
  135.   
  136.   
  137. CString IllusionExcelFile::GetSheetName(long table_index)  
  138. {  
  139.     CWorksheet sheet;  
  140.     sheet.AttachDispatch(excel_sheets_.get_Item(COleVariant((long)table_index)),true);  
  141.     CString name = sheet.get_Name();  
  142.     sheet.ReleaseDispatch();  
  143.     return name;  
  144. }  
  145.   
  146. //按照序号加载Sheet表格,可以提前加载所有的表格内部数据  
  147. BOOL IllusionExcelFile::LoadSheet(long table_index,BOOL pre_load)  
  148. {  
  149.     LPDISPATCH lpDis = NULL;  
  150.     excel_current_range_.ReleaseDispatch();  
  151.     excel_work_sheet_.ReleaseDispatch();  
  152.     lpDis = excel_sheets_.get_Item(COleVariant((long)table_index));  
  153.     if (lpDis)  
  154.     {  
  155.         excel_work_sheet_.AttachDispatch(lpDis,true);  
  156.         excel_current_range_.AttachDispatch(excel_work_sheet_.get_Cells(), true);  
  157.     }  
  158.     else  
  159.     {  
  160.         return FALSE;  
  161.     }  
  162.       
  163.     already_preload_ = FALSE;  
  164.     //如果进行预先加载  
  165.     if (pre_load)  
  166.     {  
  167.         PreLoadSheet();  
  168.         already_preload_ = TRUE;  
  169.     }  
  170.   
  171.     return TRUE;  
  172. }  
  173.   
  174. //按照名称加载Sheet表格,可以提前加载所有的表格内部数据  
  175. BOOL IllusionExcelFile::LoadSheet(LPCTSTR sheet,BOOL pre_load)  
  176. {  
  177.     LPDISPATCH lpDis = NULL;  
  178.     excel_current_range_.ReleaseDispatch();  
  179.     excel_work_sheet_.ReleaseDispatch();  
  180.     lpDis = excel_sheets_.get_Item(COleVariant(sheet));  
  181.     if (lpDis)  
  182.     {  
  183.         excel_work_sheet_.AttachDispatch(lpDis,true);  
  184.         excel_current_range_.AttachDispatch(excel_work_sheet_.get_Cells(), true);  
  185.           
  186.     }  
  187.     else  
  188.     {  
  189.         return FALSE;  
  190.     }  
  191.     //  
  192.     already_preload_ = FALSE;  
  193.     //如果进行预先加载  
  194.     if (pre_load)  
  195.     {  
  196.         already_preload_ = TRUE;  
  197.         PreLoadSheet();  
  198.     }  
  199.   
  200.     return TRUE;  
  201. }  
  202.   
  203. //得到列的总数  
  204. int IllusionExcelFile::GetColumnCount()  
  205. {  
  206.     CRange range;  
  207.     CRange usedRange;  
  208.     usedRange.AttachDispatch(excel_work_sheet_.get_UsedRange(), true);  
  209.     range.AttachDispatch(usedRange.get_Columns(), true);  
  210.     int count = range.get_Count();  
  211.     usedRange.ReleaseDispatch();  
  212.     range.ReleaseDispatch();  
  213.     return count;  
  214. }  
  215.   
  216. //得到行的总数  
  217. int IllusionExcelFile::GetRowCount()  
  218. {  
  219.     CRange range;  
  220.     CRange usedRange;  
  221.     usedRange.AttachDispatch(excel_work_sheet_.get_UsedRange(), true);  
  222.     range.AttachDispatch(usedRange.get_Rows(), true);  
  223.     int count = range.get_Count();  
  224.     usedRange.ReleaseDispatch();  
  225.     range.ReleaseDispatch();  
  226.     return count;  
  227. }  
  228.   
  229. //检查一个CELL是否是字符串  
  230. BOOL IllusionExcelFile::IsCellString(long irow, long icolumn)  
  231. {  
  232.     CRange range;  
  233.     range.AttachDispatch(excel_current_range_.get_Item (COleVariant((long)irow),COleVariant((long)icolumn)).pdispVal, true);  
  234.     COleVariant vResult =range.get_Value2();  
  235.     //VT_BSTR标示字符串  
  236.     if(vResult.vt == VT_BSTR)         
  237.     {  
  238.         return TRUE;  
  239.     }  
  240.     return FALSE;  
  241. }  
  242.   
  243. //检查一个CELL是否是数值  
  244. BOOL IllusionExcelFile::IsCellInt(long irow, long icolumn)  
  245. {  
  246.     CRange range;  
  247.     range.AttachDispatch(excel_current_range_.get_Item (COleVariant((long)irow),COleVariant((long)icolumn)).pdispVal, true);  
  248.     COleVariant vResult =range.get_Value2();  
  249.     //好像一般都是VT_R8  
  250.     if(vResult.vt == VT_INT || vResult.vt == VT_R8)         
  251.     {  
  252.         return TRUE;  
  253.     }  
  254.     return FALSE;  
  255. }  
  256.   
  257. //  
  258. CString IllusionExcelFile::GetCellString(long irow, long icolumn)  
  259. {  
  260.      
  261.     COleVariant vResult ;  
  262.     CString str;  
  263.     //字符串  
  264.     if (already_preload_ == FALSE)  
  265.     {  
  266.         CRange range;  
  267.         range.AttachDispatch(excel_current_range_.get_Item (COleVariant((long)irow),COleVariant((long)icolumn)).pdispVal, true);  
  268.         vResult =range.get_Value2();  
  269.         range.ReleaseDispatch();  
  270.     }  
  271.     //如果数据依据预先加载了  
  272.     else  
  273.     {  
  274.         long read_address[2];  
  275.         VARIANT val;  
  276.         read_address[0] = irow;  
  277.         read_address[1] = icolumn;  
  278.         ole_safe_array_.GetElement(read_address, &val);  
  279.         vResult = val;  
  280.     }  
  281.   
  282.     if(vResult.vt == VT_BSTR)  
  283.     {  
  284.         str=vResult.bstrVal;  
  285.     }  
  286.     //整数  
  287.     else if (vResult.vt==VT_INT)  
  288.     {  
  289.         str.Format(_T("%d"),vResult.pintVal);  
  290.     }  
  291.     //8字节的数字   
  292.     else if (vResult.vt==VT_R8)       
  293.     {  
  294.         str.Format(_T("%0.0f"),vResult.dblVal);  
  295.     }  
  296.     //时间格式  
  297.     else if(vResult.vt==VT_DATE)      
  298.     {  
  299.         SYSTEMTIME st;  
  300.         VariantTimeToSystemTime(vResult.date, &st);  
  301.         CTime tm(st);   
  302.         str=tm.Format("%Y-%m-%d");  
  303.   
  304.     }  
  305.     //单元格空的  
  306.     else if(vResult.vt==VT_EMPTY)     
  307.     {  
  308.         str="";  
  309.     }    
  310.   
  311.     return str;  
  312. }  
  313.   
  314. double IllusionExcelFile::GetCellDouble(long irow, long icolumn)  
  315. {  
  316.     double rtn_value = 0;  
  317.     COleVariant vresult;  
  318.     //字符串  
  319.     if (already_preload_ == FALSE)  
  320.     {  
  321.         CRange range;  
  322.         range.AttachDispatch(excel_current_range_.get_Item (COleVariant((long)irow),COleVariant((long)icolumn)).pdispVal, true);  
  323.         vresult =range.get_Value2();  
  324.         range.ReleaseDispatch();  
  325.     }  
  326.     //如果数据依据预先加载了  
  327.     else  
  328.     {  
  329.         long read_address[2];  
  330.         VARIANT val;  
  331.         read_address[0] = irow;  
  332.         read_address[1] = icolumn;  
  333.         ole_safe_array_.GetElement(read_address, &val);  
  334.         vresult = val;  
  335.     }  
  336.       
  337.     if (vresult.vt==VT_R8)       
  338.     {  
  339.         rtn_value = vresult.dblVal;  
  340.     }  
  341.       
  342.     return rtn_value;  
  343. }  
  344.   
  345. //VT_R8  
  346. int IllusionExcelFile::GetCellInt(long irow, long icolumn)  
  347. {  
  348.     int num;  
  349.     COleVariant vresult;  
  350.   
  351.     if (already_preload_ == FALSE)  
  352.     {  
  353.         CRange range;  
  354.         range.AttachDispatch(excel_current_range_.get_Item (COleVariant((long)irow),COleVariant((long)icolumn)).pdispVal, true);  
  355.         vresult = range.get_Value2();  
  356.         range.ReleaseDispatch();  
  357.     }  
  358.     else  
  359.     {  
  360.         long read_address[2];  
  361.         VARIANT val;  
  362.         read_address[0] = irow;  
  363.         read_address[1] = icolumn;  
  364.         ole_safe_array_.GetElement(read_address, &val);  
  365.         vresult = val;  
  366.     }  
  367.     //  
  368.     num = static_cast<int>(vresult.dblVal);  
  369.   
  370.     return num;  
  371. }  
  372.   
  373. void IllusionExcelFile::SetCellString(long irow, long icolumn,CString new_string)  
  374. {  
  375.     COleVariant new_value(new_string);  
  376.     CRange start_range = excel_work_sheet_.get_Range(COleVariant(_T("A1")),covOptional);  
  377.     CRange write_range = start_range.get_Offset(COleVariant((long)irow -1),COleVariant((long)icolumn -1) );  
  378.     write_range.put_Value2(new_value);  
  379.     start_range.ReleaseDispatch();  
  380.     write_range.ReleaseDispatch();  
  381.   
  382. }  
  383.   
  384. void IllusionExcelFile::SetCellInt(long irow, long icolumn,int new_int)  
  385. {  
  386.     COleVariant new_value((long)new_int);  
  387.       
  388.     CRange start_range = excel_work_sheet_.get_Range(COleVariant(_T("A1")),covOptional);  
  389.     CRange write_range = start_range.get_Offset(COleVariant((long)irow -1),COleVariant((long)icolumn -1) );  
  390.     write_range.put_Value2(new_value);  
  391.     start_range.ReleaseDispatch();  
  392.     write_range.ReleaseDispatch();  
  393. }  
  394.   
  395.   
  396. //  
  397. void IllusionExcelFile::ShowInExcel(BOOL bShow)  
  398. {  
  399.     excel_application_.put_Visible(bShow);  
  400.     excel_application_.put_UserControl(bShow);  
  401. }  
  402.   
  403. //返回打开的EXCEL文件名称  
  404. CString IllusionExcelFile::GetOpenFileName()  
  405. {  
  406.     return open_excel_file_;  
  407. }  
  408.   
  409. //取得打开sheet的名称  
  410. CString IllusionExcelFile::GetLoadSheetName()  
  411. {  
  412.     return excel_work_sheet_.get_Name();  
  413. }  
  414.   
  415. //取得列的名称,比如27->AA  
  416. char *IllusionExcelFile::GetColumnName(long icolumn)  
  417. {     
  418.     static char column_name[64];  
  419.     size_t str_len = 0;  
  420.       
  421.     while(icolumn > 0)  
  422.     {  
  423.         int num_data = icolumn % 26;  
  424.         icolumn /= 26;  
  425.         if (num_data == 0)  
  426.         {  
  427.             num_data = 26;  
  428.             icolumn--;  
  429.         }  
  430.         column_name[str_len] = (char)((num_data-1) + 'A' );  
  431.         str_len ++;  
  432.     }  
  433.     column_name[str_len] = '\0';  
  434.     //反转  
  435.     _strrev(column_name);  
  436.   
  437.     return column_name;  
  438. }  
  439.   
  440. //预先加载  
  441. void IllusionExcelFile::PreLoadSheet()  
  442. {  
  443.   
  444.     CRange used_range;  
  445.   
  446.     used_range = excel_work_sheet_.get_UsedRange();   
  447.   
  448.   
  449.     VARIANT ret_ary = used_range.get_Value2();  
  450.     if (!(ret_ary.vt & VT_ARRAY))  
  451.     {  
  452.         return;  
  453.     }  
  454.     //  
  455.     ole_safe_array_.Clear();  
  456.     ole_safe_array_.Attach(ret_ary);   
  457. }  

f.在程序中包含OperateExcelFile.h文件就可以定义对象简单操作Excel文件了



http://blog.csdn.net/superbfly/article/details/18040445