なぜなら Linuxでサービスが動作する必要があったため、OLEを介した相互作用のメカニズムは適切ではありませんでした。
実装には、C ++経由でAPIに直接アクセスできるOpenOfficeが選択されました。
ドキュメントは非常に乏しいことが判明し、OLEを介さない作業の例はほとんどありませんでした。 そこで、すべての研究をハブに関する1つの記事にまとめることにしました
記事のサンプルアウトライン:
1. C ++を介したOpenOffice APIの使用開始
1.1。 ヘッダー生成
1.2。 RDBタイプファイルの生成
1.3。 Visual Studio 2008のセットアップ
1.4。 ダイナミックdllを作成する
2.プログラムでDLLを再利用する
2.1。 小さなデータアップロードプログラムの例
原則として、DLLに十分な機能がある場合は、手順1を繰り返す必要はありません。
1. C ++を介したOpenOffice APIの使用開始
このセクションは、オフィスwiki: wiki.services.openoffice.org/wiki/SDKInstallationで詳細に説明されています。
APIの使用を開始するには、 download.services.openoffice.org / files / stableアドレスからSDKをダウンロードする必要があります。 SDKのバージョンが、インストールされているオフィスのバージョンと一致していることが重要です。
SDKを任意のディレクトリにインストールします。
補助ユーティリティgnu make、zipをインストールします(必要な場合)
1.1。 ヘッダー生成
SDKを含むディレクトリ内に、別のバッチファイルを生成するsetsdkenv_windows.batバッチファイルがあります。
質問に答えることでそれを実現します。
環境変数が設定されたバッチファイルが生成されます。
コンソールを開き、生成されたバッチファイルを実行し、同じ準備されたコンソールで特定のバージョンのオフィス用のヘッダーファイルを生成します。
生成チーム:
cppumaker -Gc -BUCR -O "c:\Program Files\OpenOffice_SDK\sdk\inludecpp" "c:\Program Files\OpenOffice.org 3\URE\misc\types.rdb" "c:\Program Files\OpenOffice.org 3\Basis\program\offapi.rdb"
どこで
c:\ Program Files \ OpenOffice_SDK \ sdk \ inludecpp-生成するフォルダー
c:\ Program Files \ OpenOffice.org 3 \-オフィスへのパス
1.2。 RDBファイルタイプの生成。
また、開始するには、ご使用のオフィスのバージョン専用のRDBファイルを生成する必要があります。
RDBファイルは、OpenOfficeの特定のバージョンのタイプとインターフェースの説明を含むファイルのようなものです。
これは次のコマンドで実行されます。
"C:\Program Files\OpenOffice.org 3\URE\bin\regmerge" "d:\oo\OOAPI\Debug\OOAPI.rdb" / "c:\Program Files\OpenOffice.org 3\URE\misc\types.rdb"
C:\ Program Files \ OpenOffice.org 3 \はオフィスへのパスです
d:\ oo \ OOAPI \ Debug \-ファイルが生成されるパス
その後、コマンドで登録します:
"C:\Program Files\OpenOffice.org 3\URE\bin\regcomp" -register -r "d:\oo\OOAPI\Debug\OOAPI.rdb" -c connector.uno.dll
"C:\Program Files\OpenOffice.org 3\URE\bin\regcomp" -register -r "d:\oo\OOAPI\Debug\OOAPI.rdb" -c remotebridge.uno.dll
"C:\Program Files\OpenOffice.org 3\URE\bin\regcomp" -register -r "d:\oo\OOAPI\Debug\OOAPI.rdb" -c bridgefac.uno.dll
"C:\Program Files\OpenOffice.org 3\URE\bin\regcomp" -register -r "d:\oo\OOAPI\Debug\OOAPI.rdb" -c uuresolver.uno.dll
1.3。 Visual Studio 2008のセットアップ
ヘッダーファイルと以下を含めます。
ツール->オプション->プロジェクト-> VC ++ディレクトリ->ファイルを含める
生成されたヘッダーファイルを含むフォルダーを追加します:<oo_sdk_path> \ inludecpp
ツール->オプション->プロジェクト-> VC ++ディレクトリ->ライブラリファイル
<oo_sdk_path> \ libディレクトリを追加します
ツール->オプション->プロジェクト-> VC ++ディレクトリ->実行可能ファイル
<office_programm_dir> \プログラムディレクトリを追加します
プロジェクトのプロパティ:
構成を「すべての構成」に変更します
追加のライブラリを追加
[プロパティ]-> [リンカー]-> [追加オプションのComandLine]
いずれかを追加します:
isal.lib icppu.lib icppuhelper.lib isal.lib isalhelper.lib ireg.lib irmcxt.lib stlport_vc71.lib
すべては、オフィスで作業するためのコンソールプログラムを作成する準備ができています。
1.4。 ダイナミックdllを作成する
多くの便利な例がここにあります: wiki.services.openoffice.org/wiki/Calc/API/Programming
DLLの作業計画は次のようなものです。
-プログラムの開始時に、RDBファイルの可用性を確認し、存在しない場合は生成が行われます。
接続、genRdb関数
コンピューターの管理者権限がない場合は、オフィスの一般的なバージョン用にRDBを事前に生成することをお勧めします。
-OpenOfficeサーバーを起動し、リッスンするポートを設定します
startServer、オフィスサーバーのアドレスは、getOOPath関数によってレジストリから認識されます。
-プログラムはオフィスサーバーに接続します
-新しいオフィスフレームが作成されます。新しいファイルまたはxlsファイルがインポートされます。
-その後、コンテンツを管理するコマンドを送信できます
-xlsファイルをディスクにエクスポート
関数exportToUrl
-逆のメカニズムも可能です:imopt xls file and reading data from it
関数getVal、getText
DLLコードを囲み、十分なコメントがあることを願っています。 完全なプロジェクトはこちらからダウンロードできます 。
ooapi.h:
// #define OOAPI3 __declspec(dllexport) #define WNT 1 #include <stdio.h> #include <wchar.h> #include <sal/main.h> #include <cppuhelper/bootstrap.hxx> #include <osl/file.hxx> #include <osl/process.h> // , #include <com/sun/star/beans/XPropertySet.hpp> #include <com/sun/star/bridge/XUnoUrlResolver.hpp> #include <com/sun/star/frame/XComponentLoader.hpp> #include <com/sun/star/lang/XMultiComponentFactory.hpp> #include <com/sun/star/registry/XSimpleRegistry.hpp> #include <com/sun/star/sheet/XSpreadsheetDocument.hpp> #include <com/sun/star/sheet/XSpreadsheet.hpp> #include <com/sun/star/container/XIndexAccess.hpp> #include <com/sun/star/table/XCellRange.hpp> #include <com/sun/star/table/BorderLine.hpp> #include <com/sun/star/table/CellHoriJustify.hpp> #include <com/sun/star/table/XColumnRowRange.hpp> #include <com/sun/star/table/XMergeableCell.hpp> #include <com/sun/star/table/XMergeableCellRange.hpp> #include <com/sun/star/table/TableBorder.hpp> #include <com/sun/star/beans/XPropertySet.hpp> #include <com/sun/star/frame/XStorable.hpp> #include <com/sun/star/util/XMergeable.hpp> #include <string> #include <locale> #include <io.h> #include <iostream> #include <sstream> using namespace rtl; using namespace std; using namespace com::sun::star::uno; using namespace com::sun::star::lang; using namespace com::sun::star::beans; using namespace com::sun::star::bridge; using namespace com::sun::star::frame; using namespace com::sun::star::registry; using namespace com::sun::star::sheet; using namespace com::sun::star::table; using namespace com::sun::star::container; using namespace com::sun::star::util; // OOAPI3 bool connect(const char *file, bool hidden); OOAPI3 void disconnect(); OOAPI3 bool selectSheet(short sheet); OOAPI3 void setVal(int, int, double); OOAPI3 void setText(int x, int y, const wchar_t *text); OOAPI3 bool setBold(int x, int y); OOAPI3 bool setFontColor(int x, int y, int r, int g, int b); OOAPI3 bool setBgColor(int x, int y, int r, int g, int b); OOAPI3 bool setFontSize(int x, int y, short size); OOAPI3 bool setItalic(int x, int y); OOAPI3 bool setHoriz(int x, int y, short hor); OOAPI3 bool setBorders(int x, int y, bool lft, bool tp, bool rt, bool dn, short r, short g, short b); OOAPI3 bool setColWidth(int col, long width); OOAPI3 bool mergeRange(const char *range); OOAPI3 bool exportToUrl(const wchar_t *url); OOAPI3 double getVal(int x, int y); OOAPI3 wchar_t* getText(int x, int y); OOAPI3 bool isWin(); OOAPI3 bool isInstall();
ooapi.cpp:
#include "stdafx.h" // wine, , bool isWin() { // wine #ifdef ISWIN return ISWIN; #endif HMODULE h = LoadLibrary(L"ntdll.dll"); bool win = (h != NULL); if(h != NULL) { win = GetProcAddress(h, "wine_get_version") == NULL; FreeLibrary(h); } #define ISWIN win printf("module load on win: %u\n", win); return win; } // , string getOOPath() { // , #ifdef OOPATH return OOPATH; #endif string path; // HKEY hKey = NULL; wchar_t * buf = NULL; ULONG dim = 0; RegOpenKeyEx( HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Classes\\opendocument.CalcDocument.1\\protocol\\StdFileEditing\\server"), 0, KEY_ALL_ACCESS, &hKey ); RegQueryValueEx(hKey, TEXT(""), NULL, NULL, NULL, &dim); buf = new wchar_t[dim + 1]; RegQueryValueEx(hKey, TEXT(""), NULL, NULL, (UCHAR*)buf, &dim); RegCloseKey(hKey); // unicode string wstring upath(buf); ostringstream stm ; const ctype<char>& ctfacet = use_facet< ctype<char> >( stm.getloc() ) ; for( size_t i=0 ; i < upath.size() ; ++i ) stm << ctfacet.narrow( upath[i], 0 ) ; path = stm.str(); delete buf; if(path == "") return ""; // , path = path.substr(0, path.length()-20); printf("server path: %s\n", path.c_str()); #define OOPATH path return path; } // void createProcess(string app) { STARTUPINFO StartupInfo; ZeroMemory(&StartupInfo,sizeof(StartupInfo)); StartupInfo.cb = sizeof(StartupInfo); StartupInfo.dwFlags = STARTF_USESHOWWINDOW; StartupInfo.wShowWindow = SW_MAXIMIZE; PROCESS_INFORMATION ProcessInfo; // // wine, RDB int len = lstrlenA(app.c_str()); BSTR utext = SysAllocStringLen(NULL, len); ::MultiByteToWideChar(CP_ACP, 0, app.c_str(), len, utext, len); ::SysFreeString(utext); // if (CreateProcess(NULL, utext,NULL,NULL,false,CREATE_NO_WINDOW|NORMAL_PRIORITY_CLASS, NULL,NULL,&StartupInfo,&ProcessInfo)) { if (ProcessInfo.hProcess != NULL) { //, while (WaitForSingleObject(ProcessInfo.hProcess,200) == WAIT_TIMEOUT) { Sleep(100); } } } } // RDB void genRDB() { string rdb = "OOAPI.rdb"; if(access("OOAPI.rdb",0) != -1) { //rdb return; } printf("generate RDB\n"); // wine // RDB string oopath = getOOPath(); string oogen = "\"" + oopath + "\\URE\\bin\\regmerge\" \"" + rdb + "\" / \"" + oopath + "\\URE\\misc\\types.rdb\" \"" + oopath + "\\Basis\\program\\offapi.rdb\""; createProcess(oogen); // string regpath; regpath = "\"" + oopath + "\\URE\\bin\\regcomp\" -register -r \"" + rdb + "\" -c connector.uno.dll"; createProcess(regpath); regpath = "\"" + oopath + "\\URE\\bin\\regcomp\" -register -r \"" + rdb + "\" -c remotebridge.uno.dll"; createProcess(regpath); regpath = "\"" + oopath + "\\URE\\bin\\regcomp\" -register -r \"" + rdb + "\" -c bridgefac.uno.dll"; createProcess(regpath); regpath = "\"" + oopath + "\\URE\\bin\\regcomp\" -register -r \"" + rdb + "\" -c uuresolver.uno.dll"; createProcess(regpath); } // , , - :) bool isInstall() { return getOOPath() != ""; } // , void startServer() { string server_path; server_path = "\"" + getOOPath() + "\\program\\soffice\" \"-accept=socket,host=localhost,port=2083;urp;StarOffice.ServiceManager\""; //createProcess(server_path); // WinExec(server_path.c_str(), SW_HIDE); } //######### // Reference< XComponent > xComponent; // Any rSheet; Reference< XMultiComponentFactory > xMultiComponentFactoryClient_copy; // , bool connect(const char *file, bool hidden) { // SAL_IMPLEMENT_MAIN_WITH_ARGS // sal_main() sal_detail_initialize(NULL, NULL); // , OUString sConnectionString(RTL_CONSTASCII_USTRINGPARAM("uno:socket,host=localhost,port=2083;urp;StarOffice.ServiceManager")); // OUString sFileString = OUString::createFromAscii(file); // genRDB(); // startServer(); printf("init server start OK\n"); // RDB Reference< XSimpleRegistry > xSimpleRegistry(::cppu::createSimpleRegistry() ); xSimpleRegistry->open( OUString( RTL_CONSTASCII_USTRINGPARAM( "OOAPI.rdb") ), sal_True, sal_False ); printf("init rdb OK\n"); //- , // UNO open office Reference< XComponentContext > xComponentContext(::cppu::bootstrap_InitialComponentContext( xSimpleRegistry ) ); Reference< XMultiComponentFactory > xMultiComponentFactoryClient( xComponentContext->getServiceManager() ); xMultiComponentFactoryClient_copy = xMultiComponentFactoryClient; Reference< XInterface > xInterface = xMultiComponentFactoryClient->createInstanceWithContext( OUString::createFromAscii( "com.sun.star.bridge.UnoUrlResolver" ), xComponentContext ); Reference< XUnoUrlResolver > resolver( xInterface, UNO_QUERY ); printf("init OK\n"); // , - int i = 200; while(i > 0) { try { Sleep(300); xInterface = Reference< XInterface >( resolver->resolve( sConnectionString ), UNO_QUERY ); i = 0; } catch ( Exception& e ) { i--; if(i == 0) { // printf("can not connect to server FAIL\n"); return false; } } } printf("connect to server OK\n"); Reference< XPropertySet > xPropSet( xInterface, UNO_QUERY ); xPropSet->getPropertyValue( OUString::createFromAscii("DefaultContext") ) >>= xComponentContext; Reference< XMultiComponentFactory > xMultiComponentFactoryServer( xComponentContext->getServiceManager() ); Reference < XComponentLoader > xComponentLoader( xMultiComponentFactoryServer->createInstanceWithContext( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop" ) ), xComponentContext ), UNO_QUERY ); printf("before create OK\n"); string fl = file; if(fl.find(".xls") != string::npos) { // xls Sequence<PropertyValue> props(2); props[0].Name = OUString::createFromAscii( "FilterName" ); props[0].Value <<= OUString::createFromAscii( "MS Excel 97" ); // wine , if(hidden) { props[1].Name = OUString::createFromAscii( "Hidden" ); props[1].Value <<= hidden; } xComponent = xComponentLoader->loadComponentFromURL(sFileString, OUString( RTL_CONSTASCII_USTRINGPARAM("_blank") ), 0, props); } else { // Sequence<PropertyValue> props(1); if(hidden) { props[0].Name = OUString::createFromAscii( "Hidden" ); props[0].Value <<= hidden; } // xComponent = xComponentLoader->loadComponentFromURL(sFileString, OUString( RTL_CONSTASCII_USTRINGPARAM("_blank") ), 0, props); } printf("create oocalc OK\n"); return true; } // bool selectSheet(short sheet) { // Reference< XSpreadsheetDocument > rSheetDoc (xComponent, UNO_QUERY); Reference< XSpreadsheets > rSheets = rSheetDoc->getSheets(); // Reference< XIndexAccess > rSheetsByIndex (rSheets, UNO_QUERY); try { rSheet = rSheetsByIndex->getByIndex( (short)sheet ); } catch( Exception &e ) { disconnect(); return false; } return true; } // void setVal(int x, int y, double val) { Reference< XSpreadsheet > rSpSheet (rSheet, UNO_QUERY); // Reference< XCell > rCell = rSpSheet->getCellByPosition(x, y); // rCell->setValue(val); } // void setText(int x, int y, const wchar_t *text) { Reference< XSpreadsheet > rSpSheet (rSheet, UNO_QUERY); Reference< XCell > rCell = rSpSheet->getCellByPosition(x, y); rCell->setFormula(OUString::OUString(text)); } // bool setBold(int x, int y) { Reference< XSpreadsheet > rSpSheet (rSheet, UNO_QUERY); Reference< XCell > rCell = rSpSheet->getCellByPosition(x, y); try { Reference< XPropertySet > rCellProps (rCell, UNO_QUERY); Any mPropVal; mPropVal <<= makeAny((short)150); rCellProps->setPropertyValue(OUString::createFromAscii("CharWeight"), mPropVal); return true; } catch( Exception &e ) { return false; } } // bool setItalic(int x, int y) { Reference< XSpreadsheet > rSpSheet (rSheet, UNO_QUERY); Reference< XCell > rCell = rSpSheet->getCellByPosition(x, y); try { Reference< XPropertySet > rCellProps (rCell, UNO_QUERY); Any mPropVal4; mPropVal4 <<= makeAny((short)2); rCellProps->setPropertyValue(OUString::createFromAscii("CharPosture"), mPropVal4); return true; } catch( Exception &e ) { return false; } } // bool setFontColor(int x, int y, int r, int g, int b) { Reference< XSpreadsheet > rSpSheet (rSheet, UNO_QUERY); Reference< XCell > rCell = rSpSheet->getCellByPosition(x, y); try { Reference< XPropertySet > rCellProps (rCell, UNO_QUERY); Any mPropVal1; mPropVal1 <<= makeAny(RGB(b,g,r)); rCellProps->setPropertyValue(OUString::createFromAscii("CharColor"), mPropVal1); return true; } catch( Exception &e ) { return false; } } // bool setBgColor(int x, int y, int r, int g, int b) { Reference< XSpreadsheet > rSpSheet (rSheet, UNO_QUERY); Reference< XCell > rCell = rSpSheet->getCellByPosition(x, y); try { Reference< XPropertySet > rCellProps (rCell, UNO_QUERY); Any mPropVal1; mPropVal1 <<= makeAny(RGB(b,g,r)); rCellProps->setPropertyValue(OUString::createFromAscii("CellBackColor"), mPropVal1); return true; } catch( Exception &e ) { return false; } } // bool setFontSize(int x, int y, short size) { Reference< XSpreadsheet > rSpSheet (rSheet, UNO_QUERY); Reference< XCell > rCell = rSpSheet->getCellByPosition(x, y); try { Reference< XPropertySet > rCellProps (rCell, UNO_QUERY); Any mPropVal3; mPropVal3 <<= makeAny((short)size); rCellProps->setPropertyValue(OUString::createFromAscii("CharHeight"), mPropVal3); return true; } catch( Exception &e ) { return false; } } // bool setHoriz(int x, int y, short hor) { Reference< XSpreadsheet > rSpSheet (rSheet, UNO_QUERY); Reference< XCell > rCell = rSpSheet->getCellByPosition(x, y); try { Reference< XPropertySet > rCellProps (rCell, UNO_QUERY); Any mPropVal5; mPropVal5 <<= makeAny((short)hor); rCellProps->setPropertyValue(OUString::createFromAscii("HoriJustify"), mPropVal5); return true; } catch( Exception &e ) { return false; } } // bool setBorders(int x, int y, bool lft, bool tp, bool rt, bool dn, short r, short g, short b) { try { Reference< XSpreadsheet > rSpSheet (rSheet, UNO_QUERY); Reference< XCell > rCell = rSpSheet->getCellByPosition(x, y); Reference< XPropertySet > rCellProps (rCell, UNO_QUERY); BorderLine bl; bl.Color = RGB(b,g,r); //rgb ? bl.OuterLineWidth = 10; TableBorder b; if(lft) b.LeftLine = bl; if(tp) b.TopLine = bl; if(rt) b.RightLine = bl; if(dn) b.BottomLine = bl; b.VerticalLine = b.HorizontalLine = bl; b.IsVerticalLineValid = true; b.IsHorizontalLineValid = true; b.IsLeftLineValid = lft; b.IsRightLineValid = rt; b.IsTopLineValid = tp; b.IsBottomLineValid = dn; rCellProps->setPropertyValue(OUString::createFromAscii("TableBorder"),makeAny(b)); return true; } catch( Exception &e ) { return false; } } // bool setColWidth(int col, long width) { try { Reference< XColumnRowRange > rSheetColRange (rSheet, UNO_QUERY); Reference< XTableColumns > rSheetColumns = rSheetColRange->getColumns(); Any rCol = rSheetColumns->getByIndex(col); Reference< XPropertySet > rColProps (rCol, UNO_QUERY); rColProps->setPropertyValue(OUString::createFromAscii("Width"),makeAny(width*100)); return true; } catch( Exception &e ) { return false; } } // bool mergeRange(const char *range) { try { Reference< XCellRange > rSheetCellRange (rSheet, UNO_QUERY); Reference< XCellRange> rCellRange = rSheetCellRange->getCellRangeByName(OUString::createFromAscii(range)); Reference< XMergeable > rSheetCellMerge (rCellRange, UNO_QUERY); rSheetCellMerge->merge(true); return true; } catch( Exception &e ) { return false; } } // xls bool exportToUrl(const wchar_t *url) { try { Reference<XStorable> xStore (xComponent, UNO_QUERY); Sequence<PropertyValue> storeProps(1); storeProps[0].Name = OUString::createFromAscii( "FilterName" ); storeProps[0].Value <<= OUString::createFromAscii( "MS Excel 97" ); xStore->storeToURL( OUString::OUString(url), storeProps ); return true; } catch( Exception &e ) { return false; } } // double getVal(int x, int y) { Reference< XSpreadsheet > rSpSheet (rSheet, UNO_QUERY); Reference< XCell > rCell = rSpSheet->getCellByPosition(x, y); return rCell->getValue(); } // () wchar_t* getText(int x, int y) { Reference< XSpreadsheet > rSpSheet (rSheet, UNO_QUERY); Reference< XCell > rCell = rSpSheet->getCellByPosition(x, y); OUString buf = rCell->getFormula(); return buf.pData->buffer; } // void disconnect() { Reference< XComponent >::query( xMultiComponentFactoryClient_copy )->dispose(); sal_detail_deinitialize(); }
最終チャット:DLLを使用してExcelでロードおよびアンロードします。