2020年2月16日日曜日

30: 'soffice --convert-to'に暇をやって、直接にUNO APIを使用する

<このシリーズの前の記事 | このシリーズの目次 | このシリーズの次の記事>

'soffice --convert-to'は一部の限られたケースのみに良い。なぜかを、いくつかの図を用いて。幸運なことに、代わりに、直接にUNO APIを使用できる、容易に。

話題


About: UNO (Universal Network Objects)
About: LibreOffice
About: Apache OpenOffice
About: Javaプログラミング言語
About: C++
About: Microsoft .NET Framework
About: Pythonプログラミング言語

この記事の目次

記法

  • 'Office'は、LibreOfficeまたはApache OpenOfficeを意味する。

開始コンテキスト


  • 読者は、プログラマーである(特に、プロフェッショナルプログラマーでなくてもよい)。
  • 読者は、'soffice --convert-to'が何であるかの知識を持っている(実は、それを知っている必要は全然ない(UNO APIに直接に行けばよい))。

ターゲットコンテキスト



  • 読者は、'soffice --convert-to'は一部の限られたケースのみに良く、代わりに、直接にUNO APIを容易に使用できる理由を理解する。
ト書き
Hypothesizer 7、Objector 30A、Objector 30Bがコンピューターの前にいる。


オリエンテーション


Hypothesizer 7
本記事において私たちは、'soffice --convert-to'は一部の限られたケースのみに良く、代わりに、直接にUNO APIを容易に使用できる理由を理解します。

'soffice --convert-to'をご自分のプログラムから使用しようとして、何らかのエラーで失敗するとか、お望みのことをしてくれない(例えば、全シートのそれぞれのCSVファイルを作成してくれない)とか報告される多くの方がいらっしゃいますが、多分、そもそも、'soffice --convert-to'を使用するべきでないのです。

Objector 30A
'soffice --convert-to'のどこが悪いんだ?!というか、お前がどこか悪いんじゃないのか?!

Hypothesizer 7
...サー、実のところ、私は、'soffice --convert-to'がそれ自体として悪いと言っているのではなく、それは、ターミナル上で行なう、当座しのぎの、要求がさほど綿密でない、臨時仕事のためのものであって、真剣なプログラムから呼ぶためのものではないと申し上げているのです。

Objector 30A
お前は、タイトルで「'soffice --convert-to'に暇をやって」と言ったじゃないか!

Hypothesizer 7
ああ、それは、実のところ、残念な'タイトルの綾'です: 物事を正確に表現するというのは私の最重要使命の1つですが、本記事に正確なタイトルを付けると、どうしても長いものになってしまい、主要なサーチエンジンに無慈悲にカットされてしまうでしょう(かたわにされたタイトルはその役目を果たせないでしょう)。...他にどうできるというのでしょうか?...より正確には、勿論、一部の限られたケースにおいては、'soffice --convert-to'を妥当に使用できます。

Objector 30A
文句ばかり言いやがって!

Hypothesizer 7
私の人となりが論題ではないのです。

Objector 30B
あなたは'開始コンテキスト'で「プログラマー」と言ってるけど、どのプログラミング言語のなの?どのプログラミング言語でもいいというわけじゃないでしょう?

Hypothesizer 7
マダム、それは、ごもっともなご質問です。実際には、UNO APIは、直接に、Java、C++、任意の.NET Framework(多分、C#およびVisual Basic.NET)、Python、Office Basic、BeanShell、JavaScriptで使用できます、しかし、...

Objector 30B
私のプログラミング言語は含まれていませんね、PHPだけど。

Hypothesizer 7
...しかし、だからといって、他のプログラミング言語はどれもUNO APIの恩恵を受けられないということにはなりません、なぜなら、上記プログラミング言語の内のどれかのモジュールを呼べるかもしれませんから。PHPに関して言えば、PHPエクステンションをC++で作成できるはずです。

Objector 30B
「作成できるはず」?あらまあ!C++で1行も書いたことのない私が、どうやってPHPエクステンションをC++で作成できると想定されてるわけ?

Hypothesizer 7
えーと、あなたが出来ないのであれば、私が1つ作成しようという意図はあります、私はPHPで1行も書いたことがありませんが、実のところ。

Objector 30B
いつ?

Hypothesizer 7
'soffice --convert-to'を使用すべきでないとそれなりの数の人々が納得した時でしょう、多分。

Objector 30B
...


本体


1: 'soffice --convert-to'はどのように動作するか


Hypothesizer 7
以下は、'soffice --convert-to'が、ただ呼ばれた場合に、どのように動作するかを説明する図です。


Objector 30A
「ただ呼ばれた」というのはどういう意味だ?

Hypothesizer 7
Officeのフルインスタンスが事前に開始されていないという意味です。

Objector 30A
当然だ。なんで事前に開始しようと思うんだ?

Hypothesizer 7
...図を見てみましょう。Officeフルインスタンスが、'soffice --convert-to'呼び出し毎に、立ち上げられ、シャットダウンされています、矢印波線で示されているとおり。実は、それらの矢印波線はとても重いアクションを表しています。

Objector 30A
そうかい?

Hypothesizer 7
はい、そうです。オフィスインスタンスは、ファイルコンバージョンを行なえるようになるためには一人前のOfficeインスタンスになる必要があり、一人前のOfficeインスタンスになるのには時間がかかります。

Objector 30A
私は'--headless'オプションを指定している。

Hypothesizer 7
ああ、多くの方が'--convert-to'オプションにそのオプションを明示的に付加なさいますが、実のところ、実際上は全然意味ありません、なぜなら、'--convert-to'が使用されたとき、'--headless'オプションは自動的に暗黙に付加されるからです。

Objector 30A
そうかい?

Hypothesizer 7
はい、そうです。どのみち、一人前のOfficeインスタンスが必要とされ、それを立ち上げてシャットダウンするのはとても重いです。私のテストの結果を見てご確認ください。

Objector 30A
...「ただ呼ばれた」のでなかったらどうだ?

Hypothesizer 7
以下が、'soffice --convert-to'が、Officeフルインスタンスが事前に立ち上げられている場合に、どのように動作するかを説明する図です。


Objector 30A
...「Officeクライアント」?

Hypothesizer 7
はい。'soffice'呼び出しは、スリムなクライアントを開始し、そのクライアントが、事前に立ち上げられているOfficeフルインスタンスに、名前付きパイプを用いて接続します。

Objector 30A
それは重いアクションではないのか?

Hypothesizer 7
それは、それほど重くなく、実際、Officeフルインスタンスを立ち上げてシャットダウンするよりもはるかに軽いです。

Objector 30A
しかし、それでは、デーモンを作らなければならないということになるな?

Hypothesizer 7
必ずデーモンを作成しなければならないということではありませんが、作成したければ、デーモンを作成したり、Windowsサービスを作成したりするのは、とても容易です。実は、あるOfficeデーモンおよびあるOffice Windowsサービスをご紹介ずみです.

Objector 30A
...それでは、私は、'soffice --convert-to'に暇をやる必要はなく、Officeフルインスタンスを事前に立ち上げておけばよいだけだ、結局のところ。

Hypothesizer 7
しかしながら、'soffice --convert-to'オフィスクライアントが接続できる先は、同じコンピューターの同じオペレーティングシステムユーザーのOfficeフルインスタンスだけです。

Objector 30A
だから?

Hypothesizer 7
それでは、ファイルコンバージョン作業負荷、ファイル、アクセス権限を、ファイルコンバージョンサーバーに隔離できないでしょう。

Objector 30A
「ファイルコンバージョンサーバー」?私にそれが必要か?

Hypothesizer 7
それは勿論ご要件によりますが、コンバージョンサーバーがないと、ファイルコンバージョン作業負荷があなたのアプリケーション全体をスローダウンさせる可能性があります、例えば。

Objector 30A
'soffice --convert-to'コマンドをファイルコンバージョンサーバーへSSHか何かを介して送ればよいだけだ。

Hypothesizer 7
仰るとおりです: 実のところ、私は、'soffice --convert-to'をSSHを介して呼ぶパフォーマンスをテストしました

Objector 30A
ふーむ...

Hypothesizer 7
しかしながら、もっと致命的なことは、'soffice --convert-to'では、あなたは、ある制限内で我慢しなければならないということです。

Objector 30A
「制限」とは何のことだ?

Hypothesizer 7
以下の図を見てみましょう。


ファイルをコンバートするというのは、実際には、ただ、コンバート元ファイルをオープンし、そのドキュメントをあるドキュメント格納プロパティ群(コンバート先フォーマットを決定するフィルター名を含む)でもって格納し、そのドキュメントをクローズするというだけのことです。

Objector 30A
そうかい?

Hypothesizer 7
はい、そうです。しかし、'soffice --convert-to'を通してでは、ドキュメント格納プロパティ群の完全な指定をすることができません、なぜなら、それらの内の一部は、文字列や数値のような単純データではなく、UNOオブジェクトやシーケンスのようなもっと複雑なデータだからです(どうすればUNOオブジェクトをコマンドラインで指定できますか?)。

Objector 30A
「どうすれば」と私に聞かれても...

Hypothesizer 7
それに、ある種のことを遂行したければ、あなたはドキュメントに手を加える必要があるでしょう。

Objector 30A
「ある種のこと」?

Hypothesizer 7
例えば、あるスプレッドシートドキュメントの任意のシート(先頭シートではなく)または全シートのそれぞれをCSVファイルにコンバートしたいかもしれません。

Objector 30A
したいな、実のところ。

Hypothesizer 7
または、あるドキュメントのあるページのサイズを変更したい(例えば、A4横に)かもしれません。

Objector 30A
それは可能なのか?

Hypothesizer 7
'soffice --convert-to'ではできませんが、はい、容易に、UNO APIを使えば。

Objector 30A
なぜ、'soffice --convert-to'ではできないのか?

Hypothesizer 7
上の図を見てください。'soffice --convert-to'ファンクションは変更不能なファンクションです。そこには、そうした調整処理を差し込む余地が全然ありません。

Objector 30A
...


2: 直接にUNO APIを使用したファイルコンバージョンはどのように動作するか


Hypothesizer 7
以下は、直接にUNO APIを使用したファイルコンバージョンがどのように動作するかを説明する図です。


ご覧になられるとおり、ファイルコンバージョン毎に何らかのプロセスを立ち上げてシャットダウンしたり何らかの接続をしたり、ということはありません。

Objector 30A
じゃあ、直接UNO APIを使うほうが高速だと君は主張してるんだな?

Hypothesizer 7
そのように、私によって主張されていますし、私のテストによって実地検証されています

Objector 30A
それに、私は「ある制限内で我慢」しなくてもよいと君は主張してるんだな?

Hypothesizer 7
はい、しております。以下の図を見てみましょう。


それは、あなたのプログラムなので、「tailor the document(ドキュメントに手を加える)」部分をあなたは自由に差し込むことができ、可能な全てのドキュメント格納プロパティ群を指定することもできます。


3: 直接にUNO APIを使用するのはどれほど難しいのか?


Objector 30A
直接にUNO APIを使うのが最も効率的で最も制約が少ない方法だというのは理解するが、難しいからそこには行きたくないわけだ。

Hypothesizer 7
実のところ、それは全然難しくありません、どうしてそのような神話がはびこるのか推測はできますが。

Objector 30A
じゃあ、推測しろ!

Hypothesizer 7
簡潔に言うと、オフィシャル文書がずさんなのです。

Objector 30A
...じゃあ、どうすればいいんだ?

Hypothesizer 7
少なくとも、UNOの基本を以下の図を見て理解しましょう。


Objector 30A
...「UNO proxy」?「UNO interface」?

Hypothesizer 7
第一に、コンバート元ファイルはあなたのプログラム内へロードされるのではなく、Officeフルインスタンス内へロードされるのであることを理解しましょう。

Objector 30A
うむ?ふーむ、私のプログラムはただ、Officeフルインスタンスにファイルをロードするように依頼するだけか。

Hypothesizer 7
したがって、ドキュメントは、あなたのプログラム内で操作されるのではなく、Officeフルインスタンス内で操作されます。

Objector 30A
じゃあ、私のプログラムはただ、Officeフルインスタンスにドキュメントを操作するように依頼するだけか。

Hypothesizer 7
あなたのプログラムは、Officeフルインスタンスにドキュメントを操作するように、UNOプロキシを介して依頼します。以下が、UNOの面倒な(難しくは全然ありませんが)側面です: UNOプロキシはどれも、1 UNOインターフェイスに対応します、UNOオブジェクト全体ではなく。

Objector 30A
はーはあー。

Hypothesizer 7
例えば、あなたのプログラムはまず、ドキュメントUNOオブジェクトへのAAA UNOプロキシを取得してドキュメントを一定の方法で操作します(正確に言えば、Officeフルインスタンスに操作するように依頼しますが、以後はそれほど正確でなく言わせてください)が、もしも、あなたのプログラムがドキュメントUNOオブジェクトを、CCC UNOインターフェイスでカバーされている方法で操作したければ、あなたのプログラムは、ドキュメントUNOオブジェクトへのCCC UNOプロキシを取得しなければならないでしょう。

Objector 30A
それは面倒だな、間違いなく。

Hypothesizer 7
それは簡明ですが、面倒であることは否定できません。

面倒な点は、一部の典型的なUNOオブジェクトは多数(数十)のUNOインターフェイスを実装しているということです。

Objector 30A
「数十」。...せいぜい数個だと予測してたが。

Hypothesizer 7
しかしながら、もっと面倒な点は、あるUNOオブジェクトがどのUNOインターフェイスを実装しているかを知るのが面倒だということです。

Objector 30A
はあ?

Hypothesizer 7
あなたが、EEE UNOプロキシをあるメソッドのリターンとして取得するとき、あなたが知っているのは、それが、EEE UNOインターフェイスを実装している何らかのUNOオブジェクトUNOプロキシであるということだけです、一般的に言って。

Objector 30A
それでは、そのUNOオブジェクトがDDD UNOインターフェイスも実装していることを私はどうすれば知ることができるのか?

Hypothesizer 7
実のところ、それを知る100%確実な方法はありません、しかし、ほとんどの場合、UNO APIリファレンスに基づいて推測したり、プログラムを使って知ることができます。

Objector 30A
...どのUNOオブジェクトがどんなUNOインターフェイスを実装しているかを説明したリファレンスはないのか?

Hypothesizer 7
UNOコンポーネントについての包括的なリファレンスはありません(突然にUNOコンポーネントという用語を使用したことに怯えないでください。私は用語を明確に弁別して使用しています)、UNO APIリファレンスは、UNOインターフェイスについてのものなので。

Objector 30A
...

Hypothesizer 7
いずれにせよ、いくつかの動作可能なサンプルが本サイトで紹介されているので、あなたのUNO APIプログラムをゼロから書く必要はありません。もしも、労力を省きたいということでしたら、サンプルに基づいて、ご自分のドキュメント格納プロパティ群とドキュメントテーラーをセットすればよいだけです。

Objector 30A
...


4: サードパーティ製ツールはどうなのか?


Objector 30A
代わりにサードパーティ製ツールを使えばいいんだろ?

Hypothesizer 7
私が理解する限り、サードパーティ製ツールはどれも、'soffice --convert-to'のラッパーかUNO APIのラッパーです。

前者には私は取り合いません、なぜなら、第1セクションで取り上げた問題があるのが避けられないからです。

後者について言えば、そのツールの趣旨がファイルコンバージョンのコアロジックをラップすることなのであれば、そのようなラッパーの必要性を全然私は認めません。

Objector 30A
「コアロジック」とはどういう意味だ?

Hypothesizer 7
コアロジックというのは、Officeインスタンスに接続し、ファイルをオープンし、ドキュメントを格納し、ドキュメントをクローズし、Officeインスタンスから切断することです。それは、充分にシンプルであって、いかなるまともな動作可能サンプルにおいても既に提供されており、全然、変更する必要がありません。あなたは、そのまともな動作可能サンプルからそのロジックをご自分のコードベースにコピーすればよいだけです。

Objector 30A
コードをコピーするというのが良い行ないだとは思わんね。

Hypothesizer 7
それは、あなたのコードベース内でコードをコピーする場合の話です、私の意見では。世界のどこかで誰かがあるライブラリを作成したからといって、なぜ、世界の他の誰もがそのライブラリをブラックボックスとして盲目的に使用しなければらない義務を負うのでしょうか?

Objector 30A
...コードをコピーするのは悪い行ないだ!

Hypothesizer 7
実のところ、あなたがそのようなライブラリを使用するか否かはどうでもよいことです: コアロジックはただの固定されたルーチンにすぎないので、それをどんな方法であろうが速やかに一度あなたのプログラムに組み込んでしまい、あなた固有の関心事へ移ればよいだけのことです。

Objector 30A
「固有の関心事」?何が私の「固有の関心事」なのだ?

Hypothesizer 7
あなた固有の関心事は、あなたの要件にとって正しいドキュメント格納プロパティ群および正しいドキュメントテーラーを指定することのはずです。


5: 結びとその先


Hypothesizer 7
平たく言うと、'soffice --convert-to'は、真剣なプログラムから呼ぶためのものではなくて、ターミナル上で行なう、当座しのぎの、要求がさほど綿密でない、臨時仕事のためのものです。それは、'soffice --convert-to'は非効率で制限的だからです。

'soffice --convert-to'をラップする任意のサードパーティ製ツールは、その同じ特徴を継承しているはずです。

'soffice --convert-to'ができないことをもしも行なう必要があるのであれば、多分、直接にUNO APIを使用することでそうできます。

UNO APIを使用するのは全然難しくありませんが、UNOコンポーネントについての包括的なリファレンスがないという障壁はあります。

実のところ、ファイルコンバージョンのコアロジックは充分シンプルなので、サードパーティ製ラッパーなど必要なく、私たちの目下の関心事は、特定のニーズそれぞれ(例えば、'.docx'、'.xlsx'等ファイルにオープンパスワードをセットする任意のCSVフォーマットをセットする、一群の詳細なPDFパラメータをセットする、スプレッドシートドキュメントの全てのシートをCSVファイルに書くn任意のワードプロセッサードキュメントのページのサイズをセットする任意のスプレッドシートドキュメントのページのサイズをセットする、等)に対して、どのようなドキュメント格納プロパティ群およびドキュメントテーラーを指定すべきかということであり、それらについて、他の記事で見ていきます。


参考資料


<このシリーズの前の記事 | このシリーズの目次 | このシリーズの次の記事>