OpenOffice Automation:はじめに

仕事のために、異なるオペレーティングシステムで動作する無料のメカニズムを使用して、Excelからデータをロードおよびアンロードするメカニズムを開発する必要がありました。

なぜなら Linuxでサービスが動作する必要があったため、OLEを介した相互作用のメカニズムは適切ではありませんでした。

実装には、C ++経由でAPIに直接アクセスできるOpenOfficeが選択されました。



LinuxでOffice APIを開く



ドキュメントは非常に乏しいことが判明し、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でロードおよびアンロードします。



All Articles