top / index / prev / next / target / source

2005-11-20 diary: OpenOffice.org 2.0で UNOインタフェースを用いたファイル入出力

いがぴょん画像(小) 日記形式でつづる いがぴょんコラム ウェブページです。

old-v2

OpenOffice.org 2.0で UNOインタフェースを用いたファイル入出力

OpenOffice.org 2.0がリリースされたので、ひさしぶりに OpenOffice.org のAPIであるUNOインタフェースを試しました。

OpenOffice.org 2.0で UNOインタフェースを用いた疎通確認

OpenOffice.org 2.0がリリースされたので、ひさしぶりにUNOインタフェースを試してみました。今回は OpenOffice.org 2.0においても OpenOffice.org 1.1.x系と同じ雰囲気で動作するかどうかを調べるのが目的です。まずは一次リソースとなるべき情報源をチェックしました。

私は OpenOffice.1.1.x系と UNOインタフェースに対しては 劇的な変化は加えられていないように読み取りました。というかドキュメントが更新されているのかどうかも私は現時点では不明です。

またドキュメントから下記の4つのjarファイルが必要そうに読み取ることができました。これらのファイルは、OpenOffice.org 2.0/program/classesディレクトリに格納されています。これらについて Java側のCLASSPATHに通るように設定します。

OpenOffice.org 2.0のUNOサポート付きでの起動

事前に OpenOffice.org 2.0を UNOサポート付きで起動します。(既に OpenOffice.orgが起動している場合には、一旦終了してから下記コマンドで起動します。とくにクイックランチが動作している場合には、事前に一旦終了させておくことが重要です。) コマンドライン: UNOインタフェース付きでOpenOffice.org 2.0を起動するためのコマンドライン例

"C:\Program Files\OpenOffice.org 2.0\program\soffice" "-accept=socket,port=8100;urp;"

JavaからOpenOffice.orgを操作するサンプル

とりあえずCalcを新規作成した上で PDFファイルを生成するサンプルです。OpenOffice.org 2.0 + Windows XP SP2

/*
 * OpenOffice.org: Excelファイルの新規作成サンプル
 * Copyright (C) 2005 伊賀敏樹<br>
 * 作成日: 2005/06/12<br>
 * 更新日: 2005/11/20 OpenOffice.org 2.0で動作確認<br>
 */

import java.io.File;

import com.sun.star.beans.Property;
import com.sun.star.beans.PropertyValue;
import com.sun.star.beans.XPropertySet;
import com.sun.star.beans.XPropertySetInfo;
import com.sun.star.bridge.XBridge;
import com.sun.star.bridge.XBridgeFactory;
import com.sun.star.comp.helper.Bootstrap;
import com.sun.star.connection.ConnectionSetupException;
import com.sun.star.connection.NoConnectException;
import com.sun.star.connection.XConnection;
import com.sun.star.connection.XConnector;
import com.sun.star.frame.XComponentLoader;
import com.sun.star.frame.XController;
import com.sun.star.frame.XModel;
import com.sun.star.frame.XStorable;
import com.sun.star.lang.XComponent;
import com.sun.star.lang.XMultiComponentFactory;
import com.sun.star.sheet.XSpreadsheet;
import com.sun.star.sheet.XSpreadsheetDocument;
import com.sun.star.sheet.XSpreadsheetView;
import com.sun.star.sheet.XSpreadsheets;
import com.sun.star.text.XText;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;

/**
 * @author Tosiki IGA
 */
public class OOoWritePDFSample {
    /**
     * UNO接続で利用する接続先情報
     */
    public static final String DEFAULT_CONNECTION_STRING = "socket,host=localhost,port=8100,tcpNoDelay=1";

    /**
     * UNO接続で利用するソケットコネクション
     */
    private XConnection connection = null;

    public static void main(String[] args) {
        try {
            new OOoWritePDFSample().process();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public void process() throws Exception {
        System.out.println("Calcブックを新規作成してファイル保存します.");

        File fileTarget = new File("./sample.pdf");
        if (fileTarget.exists()) {
            fileTarget.delete();
        }

        System.out.println("OpenOfficeに接続するための前準備を実施します.");
        XBridge bridge = createOOoBridge(DEFAULT_CONNECTION_STRING);
        if (bridge == null) {
            return;
        }
        Object desktop = createDesktopInstance(bridge);
        if (desktop == null) {
            return;
        }
        System.out.println("OpenOfficeに接続するための前準備が完了しました.");

        XComponentLoader componentLoader = (XComponentLoader) UnoRuntime
                .queryInterface(XComponentLoader.class, desktop);

        System.out.println("Calcドキュメントを新規作成します.");
        PropertyValue[] loadProps = new PropertyValue[1];
        loadProps[0] = new PropertyValue();
        loadProps[0].Name = "Hidden";
        loadProps[0].Value = new Boolean(false);

        XComponent component = componentLoader.loadComponentFromURL(
                "private:factory/scalc", "_blank", 0, loadProps);
        XSpreadsheetDocument document = (XSpreadsheetDocument) UnoRuntime
                .queryInterface(XSpreadsheetDocument.class, component);

        System.out.println("Calcシートを新規作成します.");
        XSpreadsheets sheets = document.getSheets();
        sheets.insertNewByName("Sheet1", (short) 0);
        XSpreadsheet sheet = (XSpreadsheet) UnoRuntime.queryInterface(
                XSpreadsheet.class, sheets.getByName("Sheet1"));

        System.out.println("Sheet1をアクティブに設定します.");
        XModel model = (XModel) UnoRuntime.queryInterface(XModel.class,
                component);
        XController controller = model.getCurrentController();
        XSpreadsheetView view = (XSpreadsheetView) UnoRuntime.queryInterface(
                XSpreadsheetView.class, controller);
        view.setActiveSheet(sheet);

        System.out.println("A1に値をセット. (XText経由)");
        XText text = (XText) UnoRuntime.queryInterface(XText.class, sheet
                .getCellByPosition(0, 0));
        text.setString("test");

        System.out.println("A2に値をセット. (setValue経由)");
        sheet.getCellByPosition(0, 1).setValue(123456);

        System.out.println("A3に値をセット. (セルのプロパティFormulaLocal経由)");
        XPropertySet prop = (XPropertySet) UnoRuntime.queryInterface(
                XPropertySet.class, sheet.getCellByPosition(0, 2));
        prop.setPropertyValue("FormulaLocal", "256,512");
        prop.setPropertyValue("CellBackColor", new Integer(0xC0C0C0));

        if (false) {
            System.out.println("PropertySetInfoをデバッグ表示します.");
            XPropertySetInfo propinfo = prop.getPropertySetInfo();
            Property[] props = propinfo.getProperties();
            for (int index = 0; index < props.length; index++) {
                System.out.println("propertySet:" + props[index].Name + "="
                        + prop.getPropertyValue(props[index].Name).toString());
            }
        }

        Thread.sleep(2000);

        System.out.println("Calcドキュメントを指定のPDFファイル("
                + fileTarget.getAbsolutePath() + ")に保存処理します.");
        XStorable storable = (XStorable) UnoRuntime.queryInterface(
                XStorable.class, component);

        PropertyValue[] saveProps = new PropertyValue[1];
        saveProps[0] = new PropertyValue();
        saveProps[0].Name = "FilterName";
        saveProps[0].Value = "calc_pdf_Export";

        storable.storeToURL(fileTarget.toURL().toString(), saveProps);
        component.dispose();

        System.out.println("OpenOfficeへの接続の後処理(UNO接続のクローズ処理)を実施します.");
        connection.close();

        System.out.println("Calcブックを新規作成してPDFファイル保存の一連の処理を終了します.");
    }

    /**
     * OpenOfficへのブリッジ接続(UNO接続)をオープンします
     * 
     * @param 接続先情報
     * @return
     */
    public XBridge createOOoBridge(String connectionString) {
        System.out.println("OpenOfficへのブリッジ接続(UNO接続)をオープンします.");
        try {
            XComponentContext localContext = Bootstrap
                    .createInitialComponentContext(null);
            XMultiComponentFactory localServiceManager = localContext
                    .getServiceManager();
            XConnector connector = (XConnector) UnoRuntime.queryInterface(
                    XConnector.class, localServiceManager
                            .createInstanceWithContext(
                                    "com.sun.star.connection.Connector",
                                    localContext));
            try {
                connection = connector.connect(connectionString);
            } catch (NoConnectException ex) {
                System.err.println("UNO接続に失敗しました:" + ex.toString());
                return null;
            } catch (ConnectionSetupException ex) {
                System.err.println("UNO接続のセットアップに失敗しました:" + ex.toString());
                return null;
            }
            XBridgeFactory bridgeFactory = (XBridgeFactory) UnoRuntime
                    .queryInterface(XBridgeFactory.class, localServiceManager
                            .createInstanceWithContext(
                                    "com.sun.star.bridge.BridgeFactory",
                                    localContext));
            return bridgeFactory.createBridge("", "urp", connection, null);
        } catch (Exception ex) {
            System.err.println("ブリッジ作成処理全般を通して例外が発生しました.:" + ex.toString());
            return null;
        }
    }

    /**
     * OpenOfficeのデスクトップインスタンスを作成します.
     * 
     * @param bridge
     * @return
     */
    public static Object createDesktopInstance(XBridge bridge) {
        System.out.println("OpenOfficeのデスクトップインスタンスを作成します.");
        try {
            XMultiComponentFactory serviceManager = (XMultiComponentFactory) UnoRuntime
                    .queryInterface(XMultiComponentFactory.class, bridge
                            .getInstance("StarOffice.ServiceManager"));
            XPropertySet propertySet = (XPropertySet) UnoRuntime
                    .queryInterface(XPropertySet.class, serviceManager);
            XComponentContext remoteContext = (XComponentContext) UnoRuntime
                    .queryInterface(XComponentContext.class, propertySet
                            .getPropertyValue("DefaultContext"));
            XMultiComponentFactory remoteServiceManager = remoteContext
                    .getServiceManager();
            return remoteServiceManager.createInstanceWithContext(
                    "com.sun.star.frame.Desktop", remoteContext);
        } catch (Exception ex) {
            System.err.println("OpenOfficeのデスクトップインスタンス作成において例外が発生しました.:"
                    + ex.toString());
            return null;
        }
    }
}

とりあえず従来通り 動作してくれました。よかった、よかった

2005.12.08追記 OpenOffice.orgの日本語化に関する活動などで有名な可知さまからメールいただきました。

いがぴょん 様可知(catch)と申します。 KOF2005でもお会いしましたが、覚えておいででしょうか。たまたま、”OpenDocument”でググったところ日記に遭遇しましたので、メールを差し上げました。

「2005/11/20 日記: OpenOffice.org 2.0で UNOインタフェースを用いたファイル入出力」にて、OpenOffice.org SDKについて言及していましたが、OpenOffice.org2.0のSDKは、StarSuite8 SDKとして日本語化されています。

ダウンロードページは英語ですが、日本語版をダウンロードできます。ダウンロードにはユーザー登録が必要です。たしかJavaのときに登録したアカウントがそのまま使えたと思います。

ご参考になれば幸いです。今後とも、ヨロシクお願いします。

ここからいがぴょんツッコミありがとうございます。OpenOffice.org 2.0のSDKは なんと日本語化されていたのですね。全く知りませんでした。Sunさまさまですね。早速ダウンロードしてみます。

関連する日記

OpenOffice.org 2.0のフィルタ一覧

OpenOffice.org で利用可能なフィルタ一覧のURLをメモしておきます。

現時点で私が直接的に関係しそうなフィルタをメモしておきます。

OpenOffice.org 2.0を使って Excelブックを Calc形式に変換するサンプル

簡単に ExcelブックをCalc形式 (OpenDocument) に変換するサンプルを書いてみました。※そしてこれが、次期版 blancoReportの元ネタになります。 OOoExcel2CalcSample.java

/*
 * OpenOffice.org: Excel形式をCalc形式に変換するサンプル
 * Copyright (C) 2005 伊賀敏樹 作成日: 2005/11/20
 */

import java.io.File;

import com.sun.star.beans.PropertyValue;
import com.sun.star.beans.XPropertySet;
import com.sun.star.bridge.XBridge;
import com.sun.star.bridge.XBridgeFactory;
import com.sun.star.comp.helper.Bootstrap;
import com.sun.star.connection.ConnectionSetupException;
import com.sun.star.connection.NoConnectException;
import com.sun.star.connection.XConnection;
import com.sun.star.connection.XConnector;
import com.sun.star.frame.XComponentLoader;
import com.sun.star.frame.XStorable;
import com.sun.star.lang.XComponent;
import com.sun.star.lang.XMultiComponentFactory;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;

/**
 * @author IGA Tosiki
 */
public class OOoExcel2CalcSample {
    /**
     * UNO接続で利用する接続先情報
     */
    public static final String DEFAULT_CONNECTION_STRING = "socket,host=localhost,port=8100,tcpNoDelay=1";

    /**
     * UNO接続で利用するソケットコネクション
     */
    private XConnection connection = null;

    public static void main(String[] args) {
        try {
            new OOoExcel2CalcSample().process();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public void process() throws Exception {
        final File fileSource = new File("./sample.xls");
        if (fileSource.exists() == false) {
            throw new IllegalArgumentException("入力ファイル[" + fileSource.getName()
                    + "]が見つかりません。処理中断します。");
        }

        final File fileTarget = new File("./sample.ods");
        if (fileTarget.exists()) {
            if (fileTarget.delete() == false) {
                throw new IllegalArgumentException("出力ファイル["
                        + fileTarget.getName()
                        + "]が存在したので処理に先立ち削除しようとしましたが削除に失敗しました。処理中断します。");
            }
        }

        System.out.println("OpenOfficeに接続するための前準備を実施します.");
        XBridge bridge = createOOoBridge(DEFAULT_CONNECTION_STRING);
        if (bridge == null) {
            return;
        }
        Object desktop = createDesktopInstance(bridge);
        if (desktop == null) {
            return;
        }
        System.out.println("OpenOfficeに接続するための前準備が完了しました.");

        XComponentLoader componentLoader = (XComponentLoader) UnoRuntime
                .queryInterface(XComponentLoader.class, desktop);

        System.out.println("入力ファイルであるExcelドキュメントを開きます.");
        PropertyValue[] loadProps = new PropertyValue[1];
        loadProps[0] = new PropertyValue();
        loadProps[0].Name = "Hidden";
        loadProps[0].Value = new Boolean(false);

        // [file:///]となっていないとオープンできないので、URLを調整します。
        final String urlSource = fileSource.getCanonicalFile().toURL()
                .toString().replace("file:/", "file:///");
        final String urlTarget = fileTarget.getCanonicalFile().toURL()
                .toString().replace("file:/", "file:///");

        XComponent component = componentLoader.loadComponentFromURL(urlSource,
                "_blank", 0, loadProps);
        // XSpreadsheetDocument document = (XSpreadsheetDocument) UnoRuntime
        // .queryInterface(XSpreadsheetDocument.class, component);

        System.out.println("Excelファイル[" + fileSource.getAbsolutePath()
                + "]をCalcファイル[" + fileTarget.getAbsolutePath() + "]に変換処理します.");
        XStorable storable = (XStorable) UnoRuntime.queryInterface(
                XStorable.class, component);

        PropertyValue[] saveProps = new PropertyValue[1];
        saveProps[0] = new PropertyValue();
        saveProps[0].Name = "FilterName";
        saveProps[0].Value = "StarOffice XML (Calc)";

        storable.storeToURL(urlTarget, saveProps);
        component.dispose();

        System.out.println("OpenOfficeへの接続の後処理(UNO接続のクローズ処理)を実施します.");
        connection.close();

        System.out.println("Excelブックを新規作成してファイル保存の一連の処理を終了します.");
    }

    /**
     * OpenOfficへのブリッジ接続(UNO接続)をオープンします
     * 
     * @param 接続先情報
     * @return
     */
    public XBridge createOOoBridge(String connectionString) {
        System.out.println("OpenOfficへのブリッジ接続(UNO接続)をオープンします.");
        try {
            XComponentContext localContext = Bootstrap
                    .createInitialComponentContext(null);
            XMultiComponentFactory localServiceManager = localContext
                    .getServiceManager();
            XConnector connector = (XConnector) UnoRuntime.queryInterface(
                    XConnector.class, localServiceManager
                            .createInstanceWithContext(
                                    "com.sun.star.connection.Connector",
                                    localContext));
            try {
                connection = connector.connect(connectionString);
            } catch (NoConnectException ex) {
                System.err.println("UNO接続に失敗しました:" + ex.toString());
                return null;
            } catch (ConnectionSetupException ex) {
                System.err.println("UNO接続のセットアップに失敗しました:" + ex.toString());
                return null;
            }
            XBridgeFactory bridgeFactory = (XBridgeFactory) UnoRuntime
                    .queryInterface(XBridgeFactory.class, localServiceManager
                            .createInstanceWithContext(
                                    "com.sun.star.bridge.BridgeFactory",
                                    localContext));
            return bridgeFactory.createBridge("", "urp", connection, null);
        } catch (Exception ex) {
            System.err.println("ブリッジ作成処理全般を通して例外が発生しました.:" + ex.toString());
            return null;
        }
    }

    /**
     * OpenOfficeのデスクトップインスタンスを作成します.
     * 
     * @param bridge
     * @return
     */
    public static Object createDesktopInstance(XBridge bridge) {
        System.out.println("OpenOfficeのデスクトップインスタンスを作成します.");
        try {
            XMultiComponentFactory serviceManager = (XMultiComponentFactory) UnoRuntime
                    .queryInterface(XMultiComponentFactory.class, bridge
                            .getInstance("StarOffice.ServiceManager"));
            XPropertySet propertySet = (XPropertySet) UnoRuntime
                    .queryInterface(XPropertySet.class, serviceManager);
            XComponentContext remoteContext = (XComponentContext) UnoRuntime
                    .queryInterface(XComponentContext.class, propertySet
                            .getPropertyValue("DefaultContext"));
            XMultiComponentFactory remoteServiceManager = remoteContext
                    .getServiceManager();
            return remoteServiceManager.createInstanceWithContext(
                    "com.sun.star.frame.Desktop", remoteContext);
        } catch (Exception ex) {
            System.err.println("OpenOfficeのデスクトップインスタンス作成において例外が発生しました.:"
                    + ex.toString());
            return null;
        }
    }
}

この日記について