【EXCEL】VS2010;Excel2013;C++控制檯程式;讀檔案
阿新 • • 發佈:2019-02-15
【此處為廢話】這幾天boss讓給他的控制檯程式從TXT讀資料改成從EXCEL讀資料,各種度娘之後發現,真是天下部落格一大抄啊,於是我自己整理了一下。
【未解決】據各種度娘結果,在專案屬性中給已有的控制檯程式新增MFC支援,就可以了,然而,寶寶太渣,如下圖修改後,專案=》類導向=》新增類=》型別庫中的MFC類是灰色的。知道怎麼給現有的專案新增MFC支援的,請不吝賜教啦~
【正文】
1.新建控制檯程式,MFC選項打勾
2.專案=》類導向=》新增類=》型別庫中的MFC類
選擇“檔案”,選擇EXCEL.EXE所在路徑
C:\Program Files (x86)\Microsoft Office\Office15\Excel.exe
一般右鍵快捷方式=》開啟檔案所在位置,就可以找到;
如果不行,就先開啟一個excel,然後ctrl+out+delete,開啟工作管理員,右鍵正在執行的excel開啟檔案所在位置
如果只是讀的話,只要選5個匯入就可以啦
【注意】此時編譯可能有好多bug,可能
注意把每一個匯入的庫檔案的如下的import註釋並新增如下的標頭檔案
3.現在可以開始寫程式碼了。 我這邊單獨寫一個io類 標頭檔案主要是定義一些巨集,為了方便而已,可以不定義的
【初始化】
在正式呼叫前,必須初始化支援庫。可以在main中新增程式碼如下:
#轉載註明出處!!!
#include <afxdisp.h>
//#import "C:\\Program Files (x86)\\Microsoft Office\\Office15\\Excel.exe" no_namespace
此處應該還有一個bug,給那個出bug的函式前面加一個下劃線就可以了(懶,此處不貼圖)3.現在可以開始寫程式碼了。 我這邊單獨寫一個io類 標頭檔案主要是定義一些巨集,為了方便而已,可以不定義的
#ifndef IO_EXCEL_H #define IO_EXCEL_H #include "CApplication.h" #include "CRange.h" #include "CWorkbook.h" #include "CWorkbooks.h" #include "CWorksheet.h" #include "CWorksheets.h" /*定義好表的路徑和要讀的範圍大小*/ #define SHEET_PATH "C:\\Users\\APPLE\\Desktop\\data.xlsx" #define ROW_NUMBER_SHEET1 700 #define COL_NUMBER_SHEET1 8 #define ROW_NUMBER_SHEET2 203 #define COL_NUMBER_SHEET2 7 class IO_EXCEL { private: public: IO_EXCEL(); void readList(); #endif
[注意]#include "StdAfx.h" 如果後期要匯入新的cpp檔案,要加這個頭,當然啦,不加報錯的時候,你也可以比較直觀地看到#include "StdAfx.h"//貌似這個頭一定要加的 #include "IO_EXCEL.h" #include <sstream> void IO_EXCEL::readList() { CApplication app; CRange range; CWorkbooks books; CWorkbook book; CWorksheets sheets; CWorksheet sheet; LPDISPATCH lpDisp; COleVariant covTrue((short)TRUE), covFalse((short)FALSE), covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR); //開啟Excel服務 if (!app.CreateDispatch(_T("Excel.Application"),NULL)) { cout<<"Create Excel service failure!"<<endl; return ; } books = app.get_Workbooks();//我還沒怎麼懂直接get和AttachDispatch的差別,就先這樣子吧,如果是後者,記得釋放 cout<<"Ready to read excel"<<endl; lpDisp = books.Open(_T(SHEET_PATH),covOptional ,covOptional,covOptional,covOptional,covOptional,covOptional,covOptional,covOptional,covOptional,covOptional,covOptional,covOptional,covOptional,covOptional); cout<<"The path of sheet:"<<SHEET_PATH<<endl; book.AttachDispatch(lpDisp); //獲得表單集合 //sheets = book.get_Worksheets(); sheets.AttachDispatch(book.get_Worksheets(),true); cout<<"sheets.count:"<<sheets.get_Count()<<endl; //取第一張表 //sheet = sheets.get_Item(COleVariant((short)1)); sheet.AttachDispatch(sheets.get_Item(COleVariant((short)1)),true); //讀取表格內容 for(int i=2;i<=ROW_NUMBER_SHEET1;i++)//我這裡取2開始是因為我不想讀表頭了 { for(int j=1;j<=COL_NUMBER_SHEET1;j++) { range.AttachDispatch(sheet.get_Cells(),true);//位置初始化,因為get_Item實際是針對相對位置+i,+j的,所以為了看起來好理解,此處每次定位到最一開始的地方 range.AttachDispatch(range.get_Item (COleVariant((long)i),COleVariant((long)j)).pdispVal ); //正對當前range取相對位置 COleVariant vResult =range.get_Value2(); switch(j) { case 1: string str1=(CStringA(CString(vResult.bstrVal)));//可能不用這麼複雜的轉來轉去,但是我電腦上只有這樣子是沒有bug的 break; case 2: vResult.ChangeType(VT_R8);//第二列是double型別,所以要轉一下,否則cout不出來的, double d2=vResult.dblVal; break; case 3: //可以利用vResult.vt先看一下是什麼型別的,再轉型別,再。。 break; //就看你就幾列要處理了 } //開始讀第二張表 sheet.AttachDispatch(sheets.get_Item(COleVariant((short)2)),true); //讀取表格內容 for(int i=2;i<=ROW_NUMBER_SHEET2;i++) { for(int j=1;j<=COL_NUMBER_SHEET2;j++) { range.AttachDispatch(sheet.get_Cells(),true);//位置初始化 range.AttachDispatch(range.get_Item (COleVariant((long)i),COleVariant((long)j)).pdispVal ); //正對當前range取相對位置 COleVariant vResult =range.get_Value2(); switch(vResult.vt)//根據實際讀到的型別進行轉換,詳細型別請自行度娘了,我只是區分了數字和文字 { case VT_R8: vResult.ChangeType(VT_R8); cout<<vResult.dblVal<<"\t"; break; default: cout<<(CStringA(CString(vResult.bstrVal)))<<"\t"; break; } } } book.ReleaseDispatch(); app.ReleaseDispatch(); app.Quit(); }
【初始化】
在正式呼叫前,必須初始化支援庫。可以在main中新增程式碼如下:
//初始化COM支援庫
if (CoInitialize(NULL) != S_OK)
{
cout << "Failed to initialize the COM support library!" << endl;
return -1;
}
else {
cout << "Initialize the COM support library successful!" << endl;
}
#轉載註明出處!!!