VC中操作excel表格

使用Microsoft Office所帶的控件來實現代碼操作excel表格。

  最近由於工作需要,不得不操作Excel,包括基本的數據輸入輸出、字體設置、顏色設置、單元格的合併、填充色的設置,當然還包括圖表的生成以及漸近線的操作等。折騰了許久,項目終於完成了^_^。現在將學習操作Excel的點點滴滴記錄下來和大家一同分享,也作爲自己的一次總結。

      1、Excel的對象模型(有人稱其爲層次結構)

      打開一個Excel工作表,點擊“工具”->“宏”->“Visual Basic 編輯器”選項打開VB的編輯器,打開幫助文檔,裏面“Microsoft Excel Visual Basic 參考”下的“Microsoft Excel 對象模型”展示了完整的Excel的層次結構,是不是有點類似於MFC的繼承圖表啊?利用幫助文檔我們可以找到一些需要的知識,下面介紹一些類:

      _Application:表示整個的Excel應用程序,包含一個工作簿集合

      Workbooks:工作簿集合,包含N個工作簿(Workbook)

      _Workbook:工作簿,包含一個工作表(sheets)集合

      Worksheets:工作表集合,包含N個工作表

      _Worksheet:工作表,也就是我們在Excel中看到的Sheet1、Sheet2、Sheet3,它是我們操作Excel的基本單位

      Range:這是單元格的集合,我們知道Excel是由一個個的單元格組成的,通過Range來操作單元格

      Font:用於設置單元格的字體、顏色、字號、粗體設置

      Interior:設置底色

      Boards:設置區域內所有單元格的邊框,如果要設置一組區域的外邊框的話用Rang->BorderAround設置

      下面用一個具體的例子來說明怎麼通過MFC來操作Excel

      2、Excel庫的插入

      在我們MFC的工程中,按Ctrl+W打開MFC類嚮導對話框,點擊“Add Class...”->“From a type Library...”,找到你所使用的excel類型庫,我使用的在目錄C:/Program Files/Microsoft Office/OFFICE11下的“EXCEL.EXE”文件,查找時文件類型選“All Files”,然後添加我們所需要的類,通常以上列舉的前6類是必須的,其它的需要時再添加。我不認爲全部添加是一種好的做法,一個我覺得很亂,另外生成的excel.cpp文件會很大。我建議瀏覽一遍這些類,這樣當你做些操作時可以更清楚的知道需要添加哪些類。添加完需要的類後,我們就可以來做一些基本的操作了。

      3、Com支持庫的初始化

      通常在App的InitInstance()裏面加入初始化和關閉COM庫的操作,在DoModal()調用之前加入初始化的代碼:

     

  1. if (CoInitialize(NULL) != 0)   
  2. {   
  3.     AfxMessageBox("初始化COM支持庫失敗!");   
  4.     exit(1);   
  5. }   

      在return之前加入CoUninitialize(); 關閉CON庫。

      4、代碼演示一些基本的操作

      首先別忘了包含頭文件“excel.h”,若用到_variant_t()時,需要包含頭文件“comdef.h”和“comutil.h”,否則會出現錯誤:

error C2065: '_variant_t' : undeclared identifier”。

      下面的代碼包括了一些基本的操作:

  1. // 變量的定義  
  2.     _Application app;  
  3.     Workbooks books;  
  4.     _Workbook book;  
  5.     Worksheets sheets;  
  6.     _Worksheet sheet;  
  7.     Range range;  
  8.     LPDISPATCH lpDisp;      
  9.     COleVariant vResult;  
  10.   
  11.     CString str = "";  
  12.       
  13.     COleVariant  
  14.         covTrue((short)TRUE),  
  15.         covFalse((short)FALSE),  
  16.         covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);  
  17.       
  18.     //創建Excel 2003服務器(啓動Excel)  
  19.     if (!app.CreateDispatch("Excel.Application",NULL))   
  20.     {   
  21.         AfxMessageBox("Create Excel service failure!");  
  22.         return;  
  23.     }  
  24.   
  25.     // 設置爲FALSE時,後面的app.Quit();註釋要打開  
  26.     // 否則EXCEL.EXE進程會一直存在,並且每操作一次就會多開一個進程  
  27.     app.SetVisible(TRUE);  
  28.     books.AttachDispatch(app.GetWorkbooks(),true);  
  29.       
  30.     /* 
  31.     *   打開一個工作簿。 
  32.     *   Excel 2000 只需要13個參數就行,Excel 2003需要15個參數 
  33.     */  
  34.     lpDisp = books.Open("E://test.xls",  
  35.         covOptional, covOptional, covOptional, covOptional,  
  36.         covOptional, covOptional, covOptional, covOptional,  
  37.         covOptional, covOptional, covOptional, covOptional,  
  38.         covOptional, covOptional);  
  39.     ASSERT(lpDisp);  
  40.       
  41.     book.AttachDispatch(lpDisp);  
  42.       
  43.     // 得到Worksheets    
  44.     sheets.AttachDispatch(book.GetWorksheets(),true);   
  45.       
  46.     // 得到Worksheet  
  47.     sheet.AttachDispatch(sheets.GetItem(_variant_t((short)(1))));     
  48.       
  49.     // 得到全部Cells   
  50.     range.AttachDispatch(sheet.GetCells(),true);  
  51.   
  52.       
  53.     // 往單元格A1裏寫入字符串數據,就像操作矩陣一樣,第1行第1列  
  54.     range.SetItem(_variant_t((LONG)1),_variant_t((LONG)1),_variant_t("hello word!"));  
  55.   
  56.     // 往單元格A2裏寫入時間數據  
  57.     range.AttachDispatch(sheet.GetRange(_variant_t("A2"), _variant_t("A2")),true);  
  58.     range.SetValue2(_variant_t("2011/02/15"));  
  59.   
  60.     // 往單元格A3~A6裏寫入浮點數據  
  61.     range.AttachDispatch(sheet.GetRange(_variant_t("A3"), _variant_t("A6")),true);  
  62.     range.SetValue2(_variant_t((double)3.14));  
  63.   
  64.     // 設置單元格的列寬爲12  
  65.     range.AttachDispatch(sheet.GetRange(_variant_t("A1"), _variant_t("A1")),true);  
  66.     range.SetColumnWidth(_variant_t((long)12));  
  67.   
  68.     // 所有單元格居中顯示  
  69.     range.AttachDispatch(sheet.GetCells(),true);  
  70.     range.SetHorizontalAlignment(_variant_t((long)-4108)); // -4108:居中,-4131:靠左,-4152:靠右  
  71.     range.SetVerticalAlignment(_variant_t((long)-4108)); // -4108:居中,-4160:靠上,-4107:靠下  
  72.   
  73.     // 讀取單元格的數據,第4行第1列  
  74.     range.AttachDispatch(range.GetItem(_variant_t((long)(4)),_variant_t((long)(1))).pdispVal );  
  75.     vResult =range.GetValue(covOptional);  
  76.       
  77.     switch (vResult.vt)  
  78.     {  
  79.     case VT_BSTR:       // 字符串  
  80.         str=vResult.bstrVal;  
  81.         break;  
  82.     case VT_R8:         // 8字節的數字  
  83.         str.Format("%f",vResult.dblVal);  
  84.         break;  
  85.     case VT_DATE:       // 時間格式  
  86.         SYSTEMTIME st;  
  87.         VariantTimeToSystemTime(vResult.date, &st);  
  88.         break;  
  89.     case VT_EMPTY:      // 單元格空的  
  90.         str="";  
  91.         break;  
  92.     }  
  93.     //MessageBox(str);  
  94.   
  95.     Font ft;    // 要插入excel類庫裏面的Font類,下面類似  
  96.       
  97.     range.AttachDispatch(sheet.GetRange(_variant_t("A3"), _variant_t("A5")),true);  
  98.     ft.AttachDispatch(range.GetFont());  
  99.     ft.SetName(_variant_t("華文行楷")); // 字體   
  100.     ft.SetSize(_variant_t((long)12));   // 字號  
  101.     //ft.SetColorIndex(_variant_t((long)3));    // 字的顏色: 紅色  
  102.          ft.SetColor( _variant_t((long) RGB(255, 0, 0) ) );  
  103.     ft.SetBold(_variant_t((long)1));    // 1:粗體,0:非粗體  
  104.   
  105.     Interior it; // 底色設置  
  106.       
  107.     range.AttachDispatch(sheet.GetRange(_variant_t("C3"), _variant_t("E6")),true);  
  108.     it.AttachDispatch(range.GetInterior());       
  109.     it.SetColorIndex(_variant_t((long)20)); // 底色設置爲淺青色  
  110.   
  111.     Borders borders; // 先設置區域內所有單元格的邊框  
  112.     borders = range.GetBorders();  
  113.     borders.SetColorIndex(_variant_t((long)1));  
  114.     borders.SetLineStyle(_variant_t((long)1));  
  115.     borders.SetWeight(_variant_t((long)2));  
  116.   
  117.     // 然後設置外邊框  
  118.     // LineStyle=線型(1~13) Weight=線寬 ColorIndex=線的顏色(-4105爲自動, 1爲黑色)   
  119.     range.BorderAround(_variant_t((long)9),_variant_t((long)1),_variant_t((long)1),vtMissing);  
  120.   
  121.     range.AttachDispatch(sheet.GetRange(_variant_t("C8"), _variant_t("D9")),true);  
  122.     // 合併單元格  
  123.     range.Merge(_variant_t((long)0));  
  124.   
  125.   
  126.     book.Save();                    // 保存Excel的內容  
  127. //  app.SetDisplayAlerts(false);    // 不彈出對話框詢問是否保存  
  128. //  app.Quit();                     // 退出  
  129.   
  130.     //釋放對象    
  131.     range.ReleaseDispatch();  
  132.     sheet.ReleaseDispatch();  
  133.     sheets.ReleaseDispatch();  
  134.     book.ReleaseDispatch();  
  135.     books.ReleaseDispatch();  
  136.     app.ReleaseDispatch();  
[c-sharp] view plaincopy
  1. .h文件:  
  2. #include "comdef.h"   
  3. #include "excel.h"  
  4. class ExcelFile   
  5. {  
  6. public:  
  7. void ShowInExcel(bool bShow);  
  8. CString GetCell(int iRow, int iColumn);  
  9. int     GetCellInt(int iRow, int iColumn);  
  10. int GetRowCount();  
  11. int GetColumnCount();  
  12. bool LoadSheet(int iIndex);  
  13. CString GetSheetName(int iIndex);  
  14. static void InitExcel();  
  15. static void ReleaseExcel();  
  16. int GetSheetCount();  
  17. bool Open(CString FileName);  
  18. ExcelFile();  
  19. virtual ~ExcelFile();  
  20. protected:  
  21. private:  
  22. static _Application m_ExcelApp;  
  23.   
  24. Workbooks    m_Books;   
  25. _Workbook    m_Book;   
  26. Worksheets   m_sheets;   
  27. _Worksheet   m_sheet;   
  28. Range        m_Rge;   
  29. };  
  30. .cpp文件:  
  31. ExcelFile::ExcelFile()  
  32. {  
  33. }  
  34. ExcelFile::~ExcelFile()  
  35. {  
  36. m_Rge.ReleaseDispatch();   
  37. m_sheet.ReleaseDispatch();   
  38. m_sheets.ReleaseDispatch();   
  39. m_Book.ReleaseDispatch();   
  40. m_Books.ReleaseDispatch();   
  41. }  
  42. void ExcelFile::InitExcel()  
  43. {  
  44. //創建Excel 2000服務器(啓動Excel)   
  45. if (!m_ExcelApp.CreateDispatch("Excel.Application",NULL))   
  46. {   
  47. AfxMessageBox("創建Excel服務失敗!");   
  48. exit(1);   
  49. }   
  50. }  
  51. void ExcelFile::ReleaseExcel()  
  52. {  
  53. m_ExcelApp.ReleaseDispatch();  
  54. }  
  55. bool ExcelFile::Open(CString FileName)  
  56. {  
  57. //打開excel文件  
  58. //利用模板文件建立新文檔   
  59. m_Books.AttachDispatch(m_ExcelApp.GetWorkbooks(),true);   
  60. LPDISPATCH lpDis = NULL;  
  61. lpDis = m_Books.Add(_variant_t(FileName)); // 如何判斷文件是否打開?  
  62. if (lpDis)  
  63. {  
  64. m_Book.AttachDispatch(lpDis);   
  65. //得到Worksheets   
  66. m_sheets.AttachDispatch(m_Book.GetWorksheets(),true);   
  67. return true;  
  68. }  
  69. return false;  
  70. }  
  71. int ExcelFile::GetSheetCount()  
  72. {  
  73. return m_sheets.GetCount();  
  74. }  
  75. CString ExcelFile::GetSheetName(int iIndex)  
  76. {  
  77. _Worksheet sheet;  
  78. sheet.AttachDispatch(m_sheets.GetItem(_variant_t((long)iIndex)),true);  
  79. CString name = sheet.GetName();  
  80. sheet.ReleaseDispatch();  
  81. return name;  
  82. }  
  83. bool ExcelFile::LoadSheet(int iIndex)  
  84. {  
  85. LPDISPATCH lpDis = NULL;  
  86. m_Rge.ReleaseDispatch();  
  87. m_sheet.ReleaseDispatch();  
  88. lpDis = m_sheets.GetItem(_variant_t((long)iIndex));  
  89. if (lpDis)  
  90. {  
  91.         m_sheet.AttachDispatch(lpDis,true);  
  92.         m_Rge.AttachDispatch(m_sheet.GetCells(), true);  
  93.         return true;  
  94. }  
  95. return false;  
  96. }  
  97. int ExcelFile::GetColumnCount()  
  98. {  
  99. Range range;  
  100. Range usedRange;  
  101. usedRange.AttachDispatch(m_sheet.GetUsedRange(), true);  
  102. range.AttachDispatch(usedRange.GetColumns(), true);  
  103. int count = range.GetCount();  
  104. usedRange.ReleaseDispatch();  
  105. range.ReleaseDispatch();  
  106. return count;  
  107. }  
  108. int ExcelFile::GetRowCount()  
  109. {  
  110. Range range;  
  111. Range usedRange;  
  112. usedRange.AttachDispatch(m_sheet.GetUsedRange(), true);  
  113. range.AttachDispatch(usedRange.GetRows(), true);  
  114. int count = range.GetCount();  
  115. usedRange.ReleaseDispatch();  
  116. range.ReleaseDispatch();  
  117. return count;  
  118. }  
  119. CString ExcelFile::GetCell(int iRow, int iColumn)  
  120. {  
  121. Range range;  
  122. range.AttachDispatch(m_Rge.GetItem (COleVariant((long)iRow),COleVariant((long)iColumn)).pdispVal, true);  
  123.     COleVariant vResult =range.GetValue2();  
  124. CString str;  
  125. if(vResult.vt == VT_BSTR)       //字符串  
  126. {  
  127. str=vResult.bstrVal;  
  128. }  
  129. else if (vResult.vt==VT_INT)  
  130. {  
  131.         str.Format("%d",vResult.pintVal);  
  132. }  
  133. else if (vResult.vt==VT_R8)     //8字節的數字   
  134. {  
  135. str.Format("%f",vResult.dblVal);  
  136. //str.Format("%.0f",vResult.dblVal);  
  137. //str.Format("%1f",vResult.fltVal);  
  138. }  
  139. else if(vResult.vt==VT_DATE)    //時間格式  
  140. {  
  141. SYSTEMTIME st;  
  142. VariantTimeToSystemTime(vResult.date, &st);  
  143. }  
  144. else if(vResult.vt==VT_EMPTY)   //單元格空的  
  145. {  
  146.     str="(NULL)";  
  147. }   
  148. range.ReleaseDispatch();  
  149. return str;  
  150. }  
  151. int ExcelFile::GetCellInt(int iRow, int iColumn)  
  152. {  
  153. Range range;  
  154. range.AttachDispatch(m_Rge.GetItem(COleVariant((long)iRow),COleVariant((long)iColumn)).pdispVal, true);  
  155. COleVariant vResult =range.GetValue2();  
  156. int num;  
  157. num = (int)vResult.date;  
  158. range.ReleaseDispatch();  
  159. return num;  
  160. }  
  161. void ExcelFile::ShowInExcel(bool bShow)  
  162. {  
  163. m_ExcelApp.SetVisible(bShow);  
  164. }  

發佈了23 篇原創文章 · 獲贊 8 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章