--- /dev/null
+\r
+//#include "stdafx.h"\r
+\r
+//#ifndef _UNICODE\r
+//#define _UNICODE\r
+//#endif\r
+\r
+#include <sstream>\r
+#include <map>\r
+//#include <cmath>\r
+//#include <TCHAR.H>\r
+\r
+using namespace std;\r
+\r
+#import "c:/program files (x86)/common files/microsoft shared/office12/mso.dll" \\r
+ rename( "RGB", "MSORGB" )\r
+\r
+using namespace Office;\r
+\r
+#import "c:/program files (x86)/common files/microsoft shared/vba/vba6/vbe6ext.olb" \\r
+\r
+using namespace VBIDE;\r
+\r
+#import "c:/program files (x86)/microsoft office/office12/excel.exe" \\r
+ rename( "DialogBox", "ExcelDialogBox" ) \\r
+ rename( "RGB", "ExcelRGB" ) \\r
+ rename( "CopyFile", "ExcelCopyFile" ) \\r
+ rename( "ReplaceText", "ExcelReplaceText" )\r
+\r
+#include "jni2.h"\r
+\r
+//#define SIMANTICS_DEBUG(...) \\r
+//{ FILE *fp = fopen("d:/excel.log", "ab"); fprintf(fp, __VA_ARGS__); fflush(fp); fclose(fp); }\r
+\r
+#define SIMANTICS_DEBUG(...)\r
+\r
+using namespace std;\r
+using namespace Excel;\r
+\r
+map<int, Excel::_WorksheetPtr> handles;\r
+static int handleCounter = 1;\r
+\r
+void replace(std::string &s, const std::string &s1, const std::string &s2) {\r
+\r
+ int index = 0;\r
+\r
+ index = s.find(s1, index);\r
+ while(index != std::string::npos) {\r
+ s.replace(index, s1.length(), s2.c_str(), s2.length());\r
+ index = s.find(s1, index + 1);\r
+ }\r
+\r
+}\r
+\r
+boolean getString(JNIEnv *env, jstring str, char *target) {\r
+\r
+ jboolean iscopy;\r
+ const char *chars = env->GetStringUTFChars(str, &iscopy);\r
+ if(!chars) return false;\r
+\r
+ strcpy(target, chars);\r
+\r
+ env->ReleaseStringUTFChars(str, chars);\r
+\r
+ return true;\r
+\r
+}\r
+\r
+string getString(JNIEnv *env, jstring str) {\r
+\r
+ jboolean iscopy;\r
+ const char *chars = env->GetStringUTFChars(str, &iscopy);\r
+ if(!chars) return 0;\r
+ string result = chars;\r
+ env->ReleaseStringUTFChars(str, chars);\r
+ return result;\r
+\r
+}\r
+\r
+Excel::_ApplicationPtr getApplication(bool create) {\r
+ \r
+ Excel::_ApplicationPtr application;\r
+\r
+ CLSID clsid;\r
+ HRESULT hr = CLSIDFromProgID(L"Excel.Application", &clsid);\r
+ if(FAILED(hr)) {\r
+ return 0;\r
+ }\r
+\r
+ if (!SUCCEEDED(application.GetActiveObject(clsid)))\r
+ {\r
+ if(create) {\r
+ hr = application.CreateInstance(clsid);\r
+ if(FAILED(hr)) {\r
+ return 0;\r
+ }\r
+ } else {\r
+ return 0;\r
+ }\r
+ }\r
+\r
+ application->EnableEvents = VARIANT_FALSE;\r
+\r
+ return application;\r
+\r
+}\r
+\r
+JNIEXPORT jint JNICALL Java_org_simantics_excel_Excel_init(JNIEnv *env, jobject) {\r
+\r
+ SIMANTICS_DEBUG("Excel init\r\n");\r
+\r
+ HRESULT hr = ::OleInitialize(NULL);\r
+ if(FAILED(hr)) {\r
+ return hr;\r
+ }\r
+\r
+ /*\r
+ Excel::_ApplicationPtr application = getApplication(true);\r
+ if(!application) return -1;\r
+ bstr_t version = application->GetVersion(0);\r
+ ostringstream os;\r
+ os << version << endl;\r
+ SIMANTICS_DEBUG("Init successful with version %s\r\n", os.str().c_str());\r
+\r
+ application->put_Interactive( 0, VARIANT_FALSE );\r
+ application->put_Visible( 0, VARIANT_FALSE );\r
+ */\r
+\r
+ return 0;\r
+\r
+}\r
+\r
+Excel::_WorkbookPtr getWorkbook(const Excel::_ApplicationPtr &application, const string &fileName) {\r
+\r
+ SIMANTICS_DEBUG("getWorkbook(%s)\r\n", fileName.c_str());\r
+\r
+ for(int i=0;i<application->Workbooks->Count;i++) {\r
+ _bstr_t fullName;\r
+ Excel::_WorkbookPtr workbook = application->Workbooks->GetItem( _variant_t(i+1) );\r
+ workbook->get_FullName(0, &fullName.GetBSTR());\r
+ std::string fullNameStr = fullName;\r
+ SIMANTICS_DEBUG("'%s'\r\n", fullNameStr.c_str());\r
+ if(fullNameStr == fileName) return workbook;\r
+ }\r
+\r
+ return 0;\r
+\r
+}\r
+\r
+Excel::_WorksheetPtr getWorksheet(const Excel::_WorkbookPtr workbook, const string &sheetName) {\r
+\r
+ SIMANTICS_DEBUG("getWorksheet(%s)\r\n", sheetName.c_str());\r
+\r
+ for(int i=0;i<workbook->Sheets->Count;i++) {\r
+ Excel::_WorksheetPtr sheet = workbook->Sheets->GetItem(_variant_t(i+1));\r
+ std:string name = sheet->Name;\r
+ SIMANTICS_DEBUG("'%s'\r\n", name.c_str());\r
+ if(name == sheetName) return sheet;\r
+ }\r
+\r
+ return 0;\r
+\r
+}\r
+\r
+char message[1024];\r
+\r
+JNIEXPORT jstring JNICALL Java_org_simantics_excel_Excel_open(JNIEnv *env, jobject, jstring fileName, jstring sheetName_) {\r
+\r
+ string name = getString(env, fileName);\r
+ string sheetName = getString(env, sheetName_);\r
+\r
+ _variant_t varOption( (long) DISP_E_PARAMNOTFOUND, VT_ERROR );\r
+\r
+ Excel::_ApplicationPtr application = getApplication(true);\r
+ if(!application) return env->NewStringUTF("Excel application could not be started.");\r
+\r
+ Excel::_WorkbookPtr workbook = getWorkbook(application, name);\r
+ if(!workbook) {\r
+\r
+ SIMANTICS_DEBUG("getWorkbook(%s) book was not found. Opening.\r\n", name.c_str());\r
+\r
+ FILE *fp = fopen(name.c_str(), "r");\r
+ if(fp) {\r
+\r
+ SIMANTICS_DEBUG("getWorkbook(%s) book was found. Opening file.\r\n", name.c_str());\r
+\r
+ fclose(fp);\r
+ workbook = application->Workbooks->OpenXML(_bstr_t(name.c_str()), \r
+ varOption, varOption);\r
+ if(!workbook) return env->NewStringUTF("File could not be opened.");\r
+\r
+ } else {\r
+\r
+ SIMANTICS_DEBUG("getWorkbook(%s) book was not found. Creating file.\r\n", name.c_str());\r
+\r
+ workbook = application->Workbooks->Add(varOption);\r
+\r
+ if(!workbook) return env->NewStringUTF("New workbook could not be created.");\r
+\r
+ try {\r
+\r
+ Excel::_WorksheetPtr sheet = workbook->Sheets->Add();\r
+ sheet->Name = _bstr_t(sheetName.c_str());\r
+\r
+ /*\r
+ // Does not work for some unknown reason\r
+ for(int i=0;i<workbook->Sheets->Count;i++) {\r
+ Excel::_WorksheetPtr sheet = workbook->Sheets->GetItem(_variant_t(i+1));\r
+ if(name != sheetName)\r
+ sheet->PutVisible(0, Excel::XlSheetVisibility::xlSheetVeryHidden);\r
+ }\r
+ */\r
+\r
+ workbook->SaveAs(_bstr_t(name.c_str()), varOption, varOption, varOption, varOption,\r
+ varOption, Excel::xlExclusive, varOption, varOption, varOption, varOption, 0);\r
+\r
+ } catch (_com_error& e) {\r
+ _bstr_t bstr = _bstr_t(e.ErrorMessage());\r
+ string s(bstr);\r
+ _bstr_t bstr2 = _bstr_t(e.Description());\r
+ string s2(bstr2);\r
+ SIMANTICS_DEBUG("getWorkbook(%s) book was not found. Creation error 1 '%s' '%s'\r\n", name.c_str(), s.c_str(), s2.c_str());\r
+ strcpy(message, s2.c_str());\r
+ return env->NewStringUTF(message);\r
+ } catch (exception& e) {\r
+ SIMANTICS_DEBUG("getWorkbook(%s) book was not found. Creation error 2 '%s'\r\n", name.c_str(), e.what());\r
+ return env->NewStringUTF(e.what());\r
+ } catch (...) {\r
+ SIMANTICS_DEBUG("getWorkbook(%s) book was not found. Creation error 3 \r\n", name.c_str());\r
+ return env->NewStringUTF("Undefined error");\r
+ }\r
+ \r
+\r
+ }\r
+\r
+ }\r
+\r
+ application->put_Interactive( 0, VARIANT_TRUE );\r
+ application->put_Visible( 0, VARIANT_TRUE );\r
+\r
+ workbook->Activate();\r
+\r
+ SIMANTICS_DEBUG("getWorkbook(%s) searches for sheet '%s'\r\n", name.c_str(), sheetName.c_str());\r
+\r
+ try {\r
+ Excel::_WorksheetPtr sheet = getWorksheet(workbook, sheetName);\r
+ if(!sheet) {\r
+ SIMANTICS_DEBUG("creating sheet %s for '%s'\r\n", sheetName.c_str(), name.c_str());\r
+ sheet = workbook->Sheets->Add();\r
+ sheet->Name = _bstr_t(sheetName.c_str());\r
+ }\r
+ int handle = handleCounter++;\r
+ SIMANTICS_DEBUG("opened handle %d for '%s'\r\n", handle, name.c_str());\r
+ handles[handle] = sheet;\r
+ ostringstream os;\r
+ os << handle;\r
+ return env->NewStringUTF(os.str().c_str());\r
+\r
+ } catch (_com_error& e) {\r
+ _bstr_t bstr = _bstr_t(e.ErrorMessage());\r
+ string s(bstr);\r
+ _bstr_t bstr2 = _bstr_t(e.Description());\r
+ string s2(bstr2);\r
+ SIMANTICS_DEBUG("getWorkbook(%s) book was not found. Creation error 1 '%s' '%s'\r\n", name.c_str(), s.c_str(), s2.c_str());\r
+ return env->NewStringUTF(s2.c_str());\r
+ } catch (exception& e) {\r
+ SIMANTICS_DEBUG("getWorkbook(%s) book was not found. Creation error 2 '%s'\r\n", name.c_str(), e.what());\r
+ return env->NewStringUTF(e.what());\r
+ } catch (...) {\r
+ SIMANTICS_DEBUG("getWorkbook(%s) book was not found. Creation error\r\n", name.c_str());\r
+ return env->NewStringUTF("Unhandled exception.");\r
+ }\r
+\r
+\r
+ //Excel::_WorksheetPtr sheet = workbook->ActiveSheet;\r
+ //if(!sheet) return -4;\r
+\r
+\r
+}\r
+\r
+string cellName(int row, int column) {\r
+\r
+ string result;\r
+\r
+ SIMANTICS_DEBUG("cellName(%d, %d) -> ", row, column);\r
+\r
+ do {\r
+ char rem = column % 26;\r
+ char c = 'A' + rem;\r
+ result += c;\r
+ column -= rem;\r
+ column /= 26;\r
+ } while(column);\r
+\r
+ ostringstream os;\r
+ os << (row + 1);\r
+ result += os.str();\r
+\r
+ SIMANTICS_DEBUG("%s\r\n", result.c_str());\r
+\r
+ return result;\r
+\r
+}\r
+\r
+/*\r
+Excel::_WorkbookPtr getWorkbook(int handle) {\r
+ map<int, Excel::_WorkbookPtr>::iterator it = handles.find(handle);\r
+ if(it != handles.end()) return (*it).second;\r
+ else return 0;\r
+}\r
+*/\r
+\r
+Excel::_WorksheetPtr getWorksheet(int handle) {\r
+ map<int, Excel::_WorksheetPtr>::iterator it = handles.find(handle);\r
+ if(it != handles.end()) return (*it).second;\r
+ else return 0;\r
+}\r
+\r
+JNIEXPORT jint JNICALL Java_org_simantics_excel_Excel_setDouble(JNIEnv *env, jobject, jint handle, jint row, jint column, jdouble value) {\r
+\r
+ SIMANTICS_DEBUG("setDouble(%d, %d, %f)\r\n", row, column, value);\r
+\r
+ Excel::_WorksheetPtr sheet = getWorksheet(handle);\r
+ if(!sheet) return -1;\r
+ Excel::RangePtr range = sheet->Cells;\r
+ if(!range) return -2;\r
+ range->Item[row+1][column+1] = value;\r
+\r
+ return 0;\r
+\r
+}\r
+\r
+JNIEXPORT jint JNICALL Java_org_simantics_excel_Excel_setString(JNIEnv *env, jobject, jint handle, jint row, jint column, jstring value) {\r
+\r
+ string val = getString(env, value);\r
+\r
+ SIMANTICS_DEBUG("setString(%d, %d, %s)\r\n", row, column, val.c_str());\r
+\r
+ Excel::_WorksheetPtr sheet = getWorksheet(handle);\r
+ if(!sheet) return -1;\r
+ Excel::RangePtr range = sheet->Cells;\r
+ if(!range) return -2;\r
+\r
+ const char *text = val.c_str();\r
+\r
+ range->Item[row+1][column+1] = text;\r
+ //range->Name[row+1][column+1] = text;\r
+\r
+ return 0;\r
+\r
+}\r
+\r
+JNIEXPORT jint JNICALL Java_org_simantics_excel_Excel_setName(JNIEnv *env, jobject, jint handle, jint row, jint column, jstring value) {\r
+\r
+ string val = getString(env, value);\r
+\r
+ SIMANTICS_DEBUG("setName(%d, %d, %s)\r\n", row, column, val.c_str());\r
+\r
+ Excel::_WorksheetPtr sheet = getWorksheet(handle);\r
+ if(!sheet) return -1;\r
+ //sheet->c\r
+ Excel::RangePtr range = sheet->GetRange(_variant_t(cellName(row, column).c_str()));\r
+ if(!range) return -2;\r
+ range->Name = _variant_t(val.c_str());\r
+\r
+\r
+ //range->Item[row+1][column+1] = text;\r
+ //range->Name[row+1][column+1] = text;\r
+\r
+ return 0;\r
+\r
+}\r
+\r
+JNIEXPORT jint JNICALL Java_org_simantics_excel_Excel_setVisible(JNIEnv *env, jobject, jint handle, jboolean value) {\r
+\r
+ SIMANTICS_DEBUG("setVisible(%d)\r\n", value);\r
+\r
+ Excel::_WorksheetPtr sheet = getWorksheet(handle);\r
+ if(!sheet) return -1;\r
+ Excel::_ApplicationPtr application = sheet->Application;\r
+ if(!application) return -2;\r
+\r
+ if(value) {\r
+ application->put_Interactive( 0, VARIANT_TRUE );\r
+ application->put_Visible( 0, VARIANT_TRUE );\r
+ } else {\r
+ application->put_Interactive( 0, VARIANT_FALSE );\r
+ application->put_Visible( 0, VARIANT_FALSE );\r
+ }\r
+\r
+ return 0;\r
+\r
+}\r
+\r
+JNIEXPORT jint JNICALL Java_org_simantics_excel_Excel_close(JNIEnv *env, jobject, jint handle) {\r
+\r
+ SIMANTICS_DEBUG("closing handle %d\r\n", handle);\r
+\r
+ Excel::_WorksheetPtr sheet = getWorksheet(handle);\r
+ if(!sheet) return -1;\r
+ Excel::_ApplicationPtr application = sheet->Application;\r
+ if(!application) return -2;\r
+\r
+ Excel::_WorkbookPtr workbook = (Excel::_WorkbookPtr)sheet->Parent;\r
+ if(!workbook) return -3;\r
+\r
+// SIMANTICS_DEBUG("About to save\r\n");\r
+ HRESULT hr = workbook->Save();\r
+// workbook->put_Saved(0, VARIANT_TRUE);\r
+ if(FAILED(hr)) {\r
+ SIMANTICS_DEBUG("Save failed with %d\r\n", hr);\r
+ return hr;\r
+ }\r
+// SIMANTICS_DEBUG("About to AcceptAllChanges\r\n");\r
+// HRESULT hr = workbook->AcceptAllChanges();\r
+// if(FAILED(hr)) {\r
+\r
+ //SIMANTICS_DEBUG("Close failed with %d\r\n", hr);\r
+ // return hr;\r
+ //}\r
+\r
+ // Release this reference for Close\r
+ handles.erase(handle);\r
+\r
+ map<int, Excel::_WorksheetPtr>::iterator it = handles.begin();\r
+ for(;it != handles.end();++it) {\r
+ Excel::_WorksheetPtr sheet2 = (*it).second;\r
+ Excel::_WorkbookPtr book = (Excel::_WorkbookPtr)sheet2->Parent;\r
+ // The book remains open\r
+ if(book->Name == workbook->Name) return 0;\r
+ }\r
+\r
+ //SIMANTICS_DEBUG("About to PutUserControl\r\n");\r
+ //workbook->PutUserControl(VARIANT_FALSE);\r
+ SIMANTICS_DEBUG("About to Close\r\n");\r
+ hr = workbook->Close(VARIANT_FALSE);\r
+ if(FAILED(hr)) {\r
+ SIMANTICS_DEBUG("Close failed with %d\r\n", hr);\r
+ return hr;\r
+ }\r
+\r
+ long remaining = 0;\r
+\r
+ application->Workbooks->get_Count(&remaining);\r
+ if(!remaining) {\r
+ application->put_Interactive( 0, VARIANT_FALSE );\r
+ application->put_Visible( 0, VARIANT_FALSE );\r
+ hr = application->Quit();\r
+ if(FAILED(hr)) {\r
+ SIMANTICS_DEBUG("Close failed with %d\r\n", hr);\r
+ return hr;\r
+ }\r
+ }\r
+\r
+// SIMANTICS_DEBUG("About to hide");\r
+\r
+// application->put_Interactive( 0, VARIANT_FALSE );\r
+// application->put_Visible( 0, VARIANT_FALSE );\r
+\r
+// if(handles.empty())\r
+// application->Quit();\r
+\r
+ return 0;\r
+\r
+}\r
+\r
+/**\r
+JNIEXPORT jdouble JNICALL Java_org_simantics_excel_Excel_getDouble(JNIEnv *env, jobject, jint handle, jint row, jint column) {\r
+\r
+ SIMANTICS_DEBUG("getDouble(%d, %d)\r\n", row, column);\r
+\r
+ Excel::_WorksheetPtr sheet = getWorksheet(handle);\r
+ if(!sheet) return 0.0; // TODO: NAN\r
+ Excel::RangePtr range = sheet->Cells;\r
+ if(!range) return 0.0; // TODO: NAN\r
+\r
+ variant_t val = range->Item[row+1][column+1];\r
+ if (val.vt != VT_NULL) {\r
+ try {\r
+ double d = val;\r
+ SIMANTICS_DEBUG("%f\r\n",d);\r
+ return d;\r
+ } catch (...) {\r
+ return 0.0; // TODO: NAN\r
+ }\r
+ }\r
+ return 0.0; // TODO: NAN\r
+\r
+}\r
+\r
+JNIEXPORT jstring JNICALL Java_org_simantics_excel_Excel_getString(JNIEnv *env, jobject, jint handle, jint row, jint column) {\r
+\r
+ //string val = getString(env, value);\r
+\r
+ SIMANTICS_DEBUG("getString(%d, %d)\r\n", row, column);\r
+\r
+ Excel::_WorksheetPtr sheet = getWorksheet(handle);\r
+ if(!sheet) return NULL;\r
+ Excel::RangePtr range = sheet->Cells;\r
+ if(!range) return NULL;\r
+\r
+ variant_t val = range->Item[row+1][column+1];\r
+ if (val.vt != VT_NULL) { // val.vt seems to be always VT_DISPATCH.\r
+ try {\r
+ //this call will crash the application, if the cell is empty!\r
+ _bstr_t bstrt = val;\r
+ TCHAR text[1024];\r
+ // TODO: this uses wide character (16-bit) while NewStringUTF expext regular character (8-bit), hence Java gets only the fisrt charater of the whole string.\r
+ _stprintf(text, _T("%s"), (LPCTSTR)bstrt);\r
+ //const char *text = bstrt;\r
+ SIMANTICS_DEBUG("%s\r\n",text);\r
+ \r
+ // this code returns "??" for all cells.\r
+ //BSTR bstr = val.bstrVal;\r
+ //const char *text = _com_util::ConvertBSTRToString(bstr);\r
+\r
+ jstring ret = env->NewStringUTF((const char*)text);\r
+ delete[] text;\r
+ return ret;\r
+ } catch (...) {\r
+ return NULL; \r
+ }\r
+ } \r
+ SIMANTICS_DEBUG("%d\r\n",val.vt);\r
+ return NULL; \r
+\r
+}\r
+*/
\ No newline at end of file