1. 程式人生 > >傻瓜式教學:c++操作Excel

傻瓜式教學: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