傻瓜式教學:c++操作Excel
理論性的東西就是不講了,簡單的就是用微軟提供的元件來操作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.新增建立文件或開啟文件的實現程式碼:
void CcontrolExcelView::OnBnClickedButtonOpenFile()
{
// TODO: 在此新增控制元件通知處理程式程式碼
LPDISPATCH lpDisp = NULL;
//建立Excel 伺服器(啟動Excel)
if(!ExcelApp.CreateDispatch(_T("Excel.Application"),NULL))
{
AfxMessageBox(_T("啟動Excel伺服器失敗!"));
return;
}
/*判斷當前Excel的版本*/
CString strExcelVersion = ExcelApp.get_Version();
int iStart = 0;
strExcelVersion = strExcelVersion.Tokenize(_T("."), iStart);
if (_T("11") == strExcelVersion)
{
//AfxMessageBox(_T("當前Excel的版本是2003。"));
GetDlgItem(IDC_EDIT_VERSIONS)->SetWindowText(_T("Excel2003"));
}
else if (_T("12") == strExcelVersion)
{
//AfxMessageBox(_T("當前Excel的版本是2007。"));
GetDlgItem(IDC_EDIT_VERSIONS)->SetWindowText(_T("Excel2007"));
}
else
{
//AfxMessageBox(_T("當前Excel的版本是其他版本。"));
GetDlgItem(IDC_EDIT_VERSIONS)->SetWindowText(_T("Excel"));
}
ExcelApp.put_Visible(TRUE);
ExcelApp.put_UserControl(TRUE);
/*得到工作簿容器*/
books.AttachDispatch(ExcelApp.get_Workbooks());
/*開啟一個工作簿,如不存在,則新增一個工作簿*/
CString strBookPath = m_strPathName;
try
{
/*開啟一個工作簿*/
lpDisp = books.Open(strBookPath,
vtMissing, vtMissing, vtMissing, vtMissing, vtMissing,
vtMissing, vtMissing, vtMissing, vtMissing, vtMissing,
vtMissing, vtMissing, vtMissing, vtMissing);
book.AttachDispatch(lpDisp);
}
catch(...)
{
/*增加一個新的工作簿*/
lpDisp = books.Add(vtMissing);
book.AttachDispatch(lpDisp);
}
/*得到工作簿中的Sheet的容器*/
sheets.AttachDispatch(book.get_Sheets());
/*開啟一個Sheet,如不存在,就新增一個Sheet*/
CString strSheetName = _T("NewSheet");
try
{
/*開啟一個已有的Sheet*/
lpDisp = sheets.get_Item(_variant_t(strSheetName));
sheet.AttachDispatch(lpDisp);
}
catch(...)
{
/*建立一個新的Sheet*/
lpDisp = sheets.Add(vtMissing, vtMissing, _variant_t((long)1), vtMissing);
sheet.AttachDispatch(lpDisp);
sheet.put_Name(strSheetName);
}
}
這裡面註釋已經夠多了,我也不像廢話了。
10.寫入單元格的程式碼
void CcontrolExcelView::OnBnClickedButtonWrite()
{
// TODO: 在此新增控制元件通知處理程式程式碼
//獲取單元格
UpdateData(TRUE);
CString strRange;
strRange.Format(_T("%d"), m_lRow);
strRange = m_strColumn + strRange;
//獲取range
LPDISPATCH lpDisp = NULL;
lpDisp = sheet.get_Range(COleVariant(strRange), COleVariant(strRange));
range.AttachDispatch(lpDisp);
range.put_Value(vtMissing, COleVariant(m_strRange));
}
11.讀取單元格的程式碼
void CcontrolExcelView::OnBnClickedButtonRead()
{
// TODO: 在此新增控制元件通知處理程式程式碼
//獲取單元格
UpdateData(TRUE);
CString strRange;
strRange.Format(_T("%d"), m_lRow);
strRange = m_strColumn + strRange;
//獲取range
LPDISPATCH lpDisp = NULL;
lpDisp = sheet.get_Range(COleVariant(strRange), COleVariant(strRange));
range.AttachDispatch(lpDisp);
VARIANT ret = range.get_Value(vtMissing);
switch (ret.vt)
{
case VT_R8:
{
m_strRange.Format(_T("%d"), (int)ret.dblVal);
}
break;
case VT_BSTR:
{
m_strRange = ret.bstrVal;
}
break;
case VT_I4:
{
m_strRange.Format(_T("%ld"), (int)ret.lVal);
}
break;
default:
{
}
break;
}
UpdateData(FALSE);
}
12.改變單元格邊框的實現程式碼
void CcontrolExcelView::OnBnClickedButtonStyle()
{
// TODO: 在此新增控制元件通知處理程式程式碼
//獲取單元格
UpdateData(TRUE);
CString strRange;
strRange.Format(_T("%d"), m_lRow);
strRange = m_strColumn + strRange;
//獲取range
LPDISPATCH lpDisp = NULL;
lpDisp = sheet.get_Range(COleVariant(strRange), COleVariant(strRange));
range.AttachDispatch(lpDisp);
// 然後設定外邊框
// LineStyle=線型(1~13) Weight=線寬 ColorIndex=線的顏色(-4105為自動, 1為黑色)
long lColor = RGB(255, 0, 0);
COleVariant varColor(lColor);
range.BorderAround(_variant_t(long(3)), 3, 3, vtMissing);//設定邊框
}
13.改變單元格字型的實現程式碼
void CcontrolExcelView::OnBnClickedButtonFont()
{
// TODO: 在此新增控制元件通知處理程式程式碼
UpdateData(TRUE);
CString strRange;
strRange.Format(_T("%d"), m_lRow);
strRange = m_strColumn + strRange;
//獲取range
LPDISPATCH lpDisp = NULL;
lpDisp = sheet.get_Range(COleVariant(strRange), COleVariant(strRange));
range.AttachDispatch(lpDisp);
CFont0 ft;
ft.AttachDispatch(range.get_Font());
ft.put_Name(_variant_t(_T("華文行楷")));
ft.put_Size(_variant_t(8));
ft.put_Color(_variant_t(RGB(255, 0, 0)));
}
14.改變單元格底色的實現程式碼
void CcontrolExcelView::OnBnClickedButtonDise()
{
// TODO: 在此新增控制元件通知處理程式程式碼
UpdateData(TRUE);
CString strRange;
strRange.Format(_T("%d"), m_lRow);
strRange = m_strColumn + strRange;
//獲取range
LPDISPATCH lpDisp = NULL;
lpDisp = sheet.get_Range(COleVariant(strRange), COleVariant(strRange));
range.AttachDispatch(lpDisp);
//改變底色
Cnterior interior;
interior.AttachDispatch(range.get_Interior());
interior.put_ColorIndex(_variant_t((long)20)); //將底色改為淺青色
}
15.儲存檔案的實現程式碼
void CcontrolExcelView::OnBnClickedButtonSave()
{
// TODO: 在此新增控制元件通知處理程式程式碼
book.Save();
ExcelApp.Quit();
//釋放
range.ReleaseDispatch();
sheet.ReleaseDispatch();
sheets.ReleaseDispatch();
book.ReleaseDispatch();
books.ReleaseDispatch();
ExcelApp.ReleaseDispatch();
}
16.我的軟體效果圖
17.學習遇到的問題:
1)VS2010的操作介面就那樣,但是網站找的資料都是vc6.0的操作介面。總之,新增一個元件,對於一個新手來說也是艱辛的旅程。而程式碼,好說直接Copy就是了。對於任何一個菜鳥來說,抄程式碼還不容易。不過,這玩意兒看起來高大上,實現以後,並沒有什麼成就感。當然了,問題肯定是本菜鳥學的不夠深。
2)想想看,改變一個底色也要一個類,然後那個類裡面甚至有上百個函式,每個函式的引數型別,數值範圍,作用功能等,基本上只能從引數名和函式名去判斷。而且,因為時代在進一步,名字也變了,網上有些資料已經過時了。比如,現在函式是用put_XXX,舊版本的是用set_XXX。不明真相的群眾要搞半天才恍然大悟。你妹的。不知道有誰有參考手冊?我是沒找到。
3)這項技術應用嗎?用在大量地輸入資料到excel上應該相當不錯。當然了,要看是從哪個地方獲取資料了,如果是資料庫,我寫過應不是問題;如果是文字,那麼更加沒有問題了;如果是word呢?那麼你得去學下怎樣從word獲取資料了,也就是相關的元件;如果會死網頁,呵呵你還得去學習下有關瀏覽器的元件。學無止境啊。
18.參考資料
http://blog.csdn.net/circlesquare/article/details/7220776