vs2010操做office2010

目的:經過vc++讀取和寫入excel
環境:vs2012 office2010
1.建立一個新的工程,選擇mfc application,選擇dialog,在advanced features選擇automation(這一項我不肯定有沒有必要,查資料說要選上,我就選上了)
2.建立完工程後,在dialog對話框上右擊,選擇class wizard(或是ctrl+shift+x)
3.在add class下拉框內選擇add class from typelib
4.在add class from下面選擇file,而後你的office安裝目錄下的EXCEL.EXE(個人目錄是C:\Program Files (x86)\Microsoft Office\Office14\EXCEL.EXE)
5.在下面添加6個類到咱們的工程,(_Application, Worksheets, _Worksheet, Workbooks, _Workbook, Range)注意有的有下劃線,別添加錯了
6.這個時候若是直接編譯程序會提示錯誤,大致錯誤的信息以下
大致錯誤的信息以下
[plain] view plain copy
Error 1 error C1083: Cannot open compiler generated file: ‘d:\code\vc\exceltojson\exceltojson\debug\excel.tlh’: Permission denied d:\code\vc\exceltojson\exceltojson\capplication.h 3 1 EXCELToJSON c++

[plain] view plain copy
2 IntelliSense: declaration modifiers are incompatible with previous declaration d:\code\VC\EXCELToJSON\EXCELToJSON\Debug\excel.tlh 573 19 EXCELToJSON json

出現不少錯誤,幾乎都與excel.tlh這個文件相關。
解決方法就是把導入的6個類對應的頭文件最開始的一句話
[cpp] view plain copymarkdown

import 「C:\Program Files (x86)\Microsoft Office\Office14\EXCEL.EXE」 no_namespace

註釋掉,也就是刪掉。具體緣由不明,估計是這個已經更新不用了,可是模版裏面沒有改。因此引用了沒有的東西出的錯
7.作完上面的操做,再編譯一下,可能還有錯誤,錯誤提示以下:
[plain] view plain copy
Error 2 error C2059: syntax error : ‘,’ d:\code\vc\exceltojson\exceltojson\crange.h 336 1 EXCELToJSON app

[plain] view plain copy
3 IntelliSense: expected a type specifier d:\code\VC\EXCELToJSON\EXCELToJSON\CRange.h 336 10 EXCELToJSON 函數

解決方法,把Range這個類自動生成的頭文件(我這是CRage.h)裏面的
[cpp] view plain copy
VARIANT DialogBox()
{
VARIANT result;
InvokeHelper(0xf5, DISPATCH_METHOD, VT_VARIANT, (void*)&result, NULL);
return result;
} ui

改爲
[cpp] view plain copy
VARIANT _DialogBox()
{
VARIANT result;
InvokeHelper(0xf5, DISPATCH_METHOD, VT_VARIANT, (void*)&result, NULL);
return result;
} spa

也就是前面加一個下劃線。具體緣由不明,估計是新版本後有同名的函數
(PS: 汗,話說ms也真夠坑爹,本身的各類不兼容)
8.這個時候編譯一下,估計沒什麼問題了,那麼咱們就須要寫代碼操做excel了。網上找的代碼都差很少,不過裏面有幾句初始化com的
[cpp] view plain copy
::CoInitialize(NULL);
if(!AfxOleInit())
{
AfxMessageBox(L」cannot initialize com」);
return 0;
}
::CoUninitialize(); debug

在新版本的vs上會引發這個錯誤
Debug Assertion Failed!
Program: D:\code\VC\EXCELToJSON\Debug\EXCELToJSON.exe
File: f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\oleinit.cpp
Line: 49
For information on how your program can cause an assertion failure, see the Visual C++ documentation on asserts.
(Press Retry to debug the application)
這個錯誤提示更是個坑,主要緣由是你的com組件初始化了兩次。是由AfxOleInit這個函數致使的。(PS:你說我初始化兩次不行,直說不就好了,整得跟真事似的,我哪來的f盤。真是無語。再說,這麼常見的問題,爲何不能有一個準確的解釋)
解決方法就是把這一段初始化的程序刪掉,不用了。爲何?你能夠全局匹配一下AfxOleInit,你會發如今app class內(就是和你的dlg class同名,僅僅差了Dlg的一個建立工程是系統自建的類,好比個人EXCELToJSONDlg.cpp,咱們的代碼大部分都是寫到這裏面,而後會有一個EXCELToJSON.cpp類。就是在這個類裏面),系統自建的代碼有了這個初始化的程序:excel

[cpp] view plain copy
// Initialize OLE libraries
if (!AfxOleInit())
{
AfxMessageBox(IDP_OLE_INIT_FAILED);
return FALSE;
} code

9.這樣應該沒什麼問題了,在你的程序內引入上面6個類的頭文件,而後就能夠操做了。實例以下:
[cpp] view plain copy

include 「stdafx.h」

include 「EXCELToJSON.h」

include 「EXCELToJSONDlg.h」

include 「DlgProxy.h」

include 「afxdialogex.h」

include 「CApplication.h」

include 「CRange.h」

include 「CWorkbook.h」

include 「CWorkbooks.h」

include 「CWorksheet.h」

include 「CWorksheets.h」

void CEXCELToJSONDlg::OnBnClickedButtonConvert()
{
// TODO: Add your control notification handler code here
CApplication app;
CRange range;
CWorkbook book;
CWorkbooks books;
CWorksheet sheet;
CWorksheets sheets;
LPDISPATCH lpdisp;
COleVariant vresult;
COleVariant covtrue((short)TRUE);
COleVariant covfalse((short)FALSE);
COleVariant covoptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);

//create the server  
if(!app.CreateDispatch(L"Excel.Application"))  
{  
    AfxMessageBox(L"Cannot start Excel server");  
    return;  
}  
app.put_Visible(FALSE);  
books.AttachDispatch(app.get_Workbooks());  

//open file  
lpdisp = books.Open(  
    ExcelFile,  
    covoptional, covfalse, covoptional, covoptional, covoptional,  
    covoptional, covoptional, covoptional, covoptional, covoptional,  
    covoptional, covoptional, covoptional, covoptional);  

//get workbook  
book.AttachDispatch(lpdisp);  

//get worksheets  
sheets.AttachDispatch(book.get_Worksheets());  

lpdisp = book.get_ActiveSheet();  
sheet.AttachDispatch(lpdisp);  

//get the used range  
CRange usedrange;  
usedrange.AttachDispatch(sheet.get_UsedRange());  

//get used row  
range.AttachDispatch(usedrange.get_Rows());  
long irownum = range.get_Count();  
long istartrow = usedrange.get_Row();  

//get used column  
range.AttachDispatch(usedrange.get_Columns());  
long icolnum = range.get_Count();  
long istartcol = usedrange.get_Column();  

CString skey = L"";  
CString svalue = L"";  
for(int j=2; j<icolnum+1; j++)  
{  
    JSON JSONObject;  
    range.AttachDispatch(usedrange.get_Item(COleVariant((long)1), COleVariant((long)j)).pdispVal);  
    vresult = range.get_Text();       
    JSONObject.LanguageTag = vresult.bstrVal;  
    for(int i=2; i<irownum+1; i++)  
    {  
        range.AttachDispatch(usedrange.get_Item(COleVariant((long)i), COleVariant((long)1)).pdispVal);  
        vresult = range.get_Text();  
        skey = vresult.bstrVal;  
        range.AttachDispatch(usedrange.get_Item(COleVariant((long)i), COleVariant((long)j)).pdispVal);  
        vresult = range.get_Text();  
        svalue = vresult.bstrVal;  

    }  


}  
double dvalue = 3;  
usedrange.put_Item(COleVariant((long)2), COleVariant((long)2), COleVariant((double)dvalue));//write to excel  
book.Save();  
book.Close(covoptional, COleVariant(ExcelFile), covoptional);  
books.Close();  
app.Quit();

}

上面代碼是打開一個指定路徑的excel,而後得到使用的sheet(也就是你最後一次保存退出的那個sheet,這個你也能夠經過裏面的其餘方法得到excel裏面的其餘sheet),而後得到這個sheet內使用過的區域,並遍歷獲取其數據,後面一點是向指定的地方插入一個數據。在vs2012下,裏面的一些函數名字變了,setItem 改爲put_Item等,你能夠在提示的函數內找一下,看名字,應該能猜出來

xlsx文件實際上是一個zip的壓縮包,你能夠改其後綴名而後解壓,裏面都是一些xml文件和一些圖片等配置文件。若是你有時間,能夠本身解碼excel文件。 頂 0 踩

相關文章
相關標籤/搜索