如何在C ++中获得Excel单元格的值

如果有人知道如何从Excel :: Window指针到打开的Excel单元格中的实际值,请让我知道。 这里是任务条件: – Excel正在单一窗口中运行,在一张表上有一个工作簿 – 有些单元格有数据(为了简化,让我们假设只有一个单元[1,1]有数据,即“a”)问题是如何发现只有一个单元有数据,单元是[1,1],数据是“a”。 从这里开始是一个代码片段:

int main( int argc, CHAR* argv[]) { CoInitialize( NULL ); HWND excelWindow = FindWindow(L"XLMAIN", NULL); EnumChildWindows(excelWindow, (WNDENUMPROC) EnumChildProc, (LPARAM)1); return 0; } BOOL CALLBACK EnumChildProc(HWND hwnd, LPARAM) { WCHAR szClassName[64]; if(GetClassNameW(hwnd, szClassName, 64)) { if(_wcsicmp(szClassName, L"EXCEL7") == 0) { Excel::Window* pWindow = NULL; HRESULT hr = AccessibleObjectFromWindow(hwnd, OBJID_NATIVEOM, __uuidof(Excel::Window), (void**)&pWindow); if(hr == S_OK) { // Here we need to answer the question using pWindow pWindow->Release(); } return false; } } return true; } 

这是最后使用的代码:

 #include <windows.h> #include <oleacc.h> #import "C:\Program Files (x86)\Common Files\microsoft shared\OFFICE14\MSO.DLL" no_implementation rename("RGB", "ExclRGB") rename("DocumentProperties", "ExclDocumentProperties") rename("SearchPath", "ExclSearchPath") #import "C:\Program Files (x86)\Common Files\microsoft shared\VBA\VBA6\VBE6EXT.OLB" no_implementation #import "C:\Program Files (x86)\Microsoft Office\Office14\EXCEL.EXE" rename("DialogBox", "ExclDialogBox") rename("RGB", "ExclRGB") rename("CopyFile", "ExclCopyFile") rename("ReplaceText", "ExclReplaceText") #include <string> using std::string; BOOL CALLBACK EnumChildProc(HWND hwnd, LPARAM) { WCHAR szClassName[64]; if(GetClassNameW(hwnd, szClassName, 64)) { if(_wcsicmp(szClassName, L"EXCEL7") == 0) { //Get AccessibleObject Excel::Window* pWindow = NULL; IDispatch* pXlSheet = NULL; HRESULT hr = AccessibleObjectFromWindow(hwnd, OBJID_NATIVEOM, __uuidof(Excel::Window), (void**)&pWindow); if(hr == S_OK) { try { VARIANT result; VariantInit(&result); AutoWrap(DISPATCH_PROPERTYGET, &result, pWindow, L"ActiveSheet", 0); pXlSheet = result.pdispVal; _variant_t sheetName; VariantInit(&sheetName); if ((pXlSheet != NULL) && (pXlSheet != (IDispatch*)0xCCCCCCCC)) AutoWrap(DISPATCH_PROPERTYGET, &sheetName, pXlSheet, L"Name", 0); // get cell which you need string location = "C5"; location += ":" + location; // cell is a range with the same start/end cells OLECHAR *sOleText=new OLECHAR[location.length()+1]; mbstowcs(sOleText,location.c_str(),location.length()+1); IDispatch *pXlRange; // Get Range from Sheet VARIANT parm; parm.vt = VT_BSTR; parm.bstrVal = ::SysAllocString(sOleText); VARIANT result; VariantInit(&result); AutoWrap(DISPATCH_PROPERTYGET, &result, pXlSheet, L"Range", 1, parm); VariantClear(&parm); pXlRange = result.pdispVal; Excel::RangePtr cell = pXlRange; Excel::CharactersPtr ptr = cell->Characters; _bstr_t text = ptr->Text; // here is needed text } catch (...) { } } return false; // Stops enumerating through children } } return true; } void main( int argc, CHAR* argv[]) { CoInitialize(NULL); HWND excelWindow = FindWindow(L"XLMAIN", NULL); EnumChildWindows(excelWindow, (WNDENUMPROC) EnumChildProc, (LPARAM)1); CoUninitialize(); } 

AutoWrap()函数取自http://support.microsoft.com/kb/216686/en-us?fr=1 ,而来自http://www.northatlantawebdesign.com/index.php/的最初示例2009/07/15 / access-microsoft-excel-2007-com-api-through-microsoft-active-accessibility /感谢所有的帮助。

丹尼尔,

我相信你正在使用Excel COM来访问它。 我从来没有用C ++做过这个,但是我想它应该和C#不一样。 你最棘手的任务应该是导入必要的库来做到这一点。 但是我相信你已经做到了。

你应该使用这样的东西:

 int full_cells = 0; Excel::_Worksheet worksheet = pWindow->ActiveSheet; for(int j = 1; j < worksheet.Columns.Count; j++) { for (int i = 1; i < worksheet.Rows.Count; i++) { if(worksheet.Cells[i][j].Value != "") { full_cells++; cout << worksheet.Cells[i][j].Value; } } } 

请注意我没有testing过这个代码。 我只是告诉你它应该是什么样子。 您应该阅读这里的文档: http : //msdn.microsoft.com/en-us/library/ms262200.aspx并适当地使用它。

希望能帮助到你。