2019年8月25日日曜日

15: LibreOfficeをファイルコンバータとして最適に用いる(コンセプト)

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

'soffice --convert-to'をプログラムからというのは、非効率であり制約を多く受けます。サードパーティツールの必要はありません。もっと良い方法があります。OpenOfficeにも適用可能。

話題


About: UNO (Universal Network Objects)
About: LibreOffice
About: Apache OpenOffice

この記事の目次


開始コンテキスト



ターゲットコンテキスト



  • 読者は、LibreOfficeまたはApache OpenOfficeをファイルコンバーターとして最適に使用する方法のコンセプトを知る。

オリエンテーション


本記事の本パートはコンセプトについてのものです。実装については、本記事の後続のパート群があります、JavaでC++でC#でPythonでLibreOfficeまたはApache OpenOffice Basicで

LibreOfficeまたはApache OpenOfficeデーモンを作成する方法の記事およびLibreOfficeまたはApache OpenOffice Microsoft Windowsサービスを作成する方法の記事があります。

オフィスファイルをオープニングパスワードでUNOを用いて暗号化する方法の記事があります。

OpenDocumentファイルに編集パスワードをUNOを用いてセットすることについての記事があります。

バイナリWord/Excelファイルに編集パスワードをUNOを用いてセットすることについての記事があります。

There is Office Open XMLファイルに編集パスワードをUNOを用いてセットすることについての記事があります。

ワードプロセッサドキュメントのページのサイズをUNOを用いてセットすることについての記事があります。

スプレッドシートドキュメントのページのサイズをUNOを用いてセットすることについての記事があります。

ワードプロセッサドキュメントの任意のページプロパティをUNOを用いてセットすることについての記事があります。

スプレッドシートドキュメントの任意のページプロパティをUNOを用いてセットすることについての記事があります。

任意のオフィスドキュメントをPDFファイルとしてフル仕様指定でUNOを用いてエクスポートすることについての記事があります。

任意のスプレッドシートをCSVへ任意のフォーマットでUNOを用いて書き出すことについての記事があります。

任意のスプレッドシートドキュメントの全スプレッドシートをCSVファイル群へUNOを用いて書き出すことについての記事があります。


本体

ト書き
Special-Student-7、Lenard(Pythonプログラマー )、Abby(C#プログラマー)がコンピュータの前にいる。


1: 'soffice --convert-to'を真剣なプログラム(特にサーバープログラム)からというのは推奨しない


Special-Student-7
多くの人々が'soffice --convert-to'を彼らのプログラムからファイルをコンバートすることに用いることに固執しているようですが、私は、それを真剣なプログラムのために用いることは、全く推奨しません。

Lenard
. . . 「真剣な」とはどういう意味です?私のプログラムはジョークだと言ってるのですか?

Special-Student-7
サー、その逆で、あなたのプログラムは真剣なものだと想定しており、したがって、もっと適切な方法を欲されるかもしれないと想定しているのです。

Lenard
. . . どんな種類のプログラムが「真剣な」のです、具体的には?

Special-Student-7
典型的な例は、多くの人々に使われるサーバープログラムです、Webアプリケーションのような。

しかし、スタンドアロンプログラムも真剣かもしれません、もしも、高パフォーマンスが求められたり、なんらか特定の要求があるのであれば。

Lenard
「特定の要求」?

Special-Student-7
例えば、署名されたPDFファイルを得る全スプレッドシートをCSVファイル群へエクスポートさせる、ドキュメントを何らかの形で調整する(ここおよびここ、例えば)、等です。

Lenard
. . . なんで、'soffice --convert-to'は、「真剣な」プログラムには悪いのです?

Special-Student-7
ある記事に詳述されているとおり、その方法は非効率であり制約が多くあります。

Lenard
. . . 実行ごとにオフィスインスタンスをスタートしてシャットダウンするからそれはスローだと言われているわけだ . . .

Special-Student-7
他にもありますが。

Abby
私の複数'soffice --convert-to'実行が同時動作できないんだけど!

Special-Student-7
あなたのだけではありません、マダム、どなたのもです。

Abby
どうすべきなの?!

Special-Student-7
非効率でよろしいのでしたら、実行群をシンクロナイズなさればよいだけです。

Abby
全然よくないわ!

Special-Student-7
それでは、'soffice --convert-to'を使うこと自体がそもそもバッドアイデアであると、言わざるを得ません。

ご注意いただきたいのですが、私は、'soffice --convert-to'を絶対的に否定しているのではありません。それは半端な作業のためのものであって、基本的にターミナル上で間に合わせの手立てと使われるのものだと申し上げているのです。


2: サードパーティツールは特に必要ない


Abby
「バッドアイデア」と言われても、代わりにどうすべきなの? . . . ああ、サードパーティツールを使うべきだと?

Special-Student-7
えーと、あるサードパーティツールが便利だとお感じでしたら、それをお使いになることを私は絶対的に否定はしません、しかし、正直に言って、私は、どんなサードパーティツールを使う必要も見出しません。

Abby
なんで?

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

前者は、不可避に'soffice --convert-to'の問題群を引き継いでいます(それらはある程度糊塗されているかもしれませんが)。

後者についての不可避な懸念は、ラッパーの厚さです: もしも、ラッパーが薄すぎれば、それほど省力化になりません; もしも、ラッパーが厚すぎれば、自由度が奪われすぎているということになります。いずれにせよ、どなたかによるラッパーにはバグの可能性、将来放棄される懸念、気に入らない趣味を我慢しなければならないという苦渋がつきまとい、そうした不利を補うほど十分に便利なサードパーティラッパーを私は見つけていません。

結局のところ、UNO APIを直接に使って問題なくできます、サードパーティラッパーなどなくても。

Abby
私が問題なくできるとあなたがどうやって知ってるわけ?あなたは私について何を知ってるわけ、ミスター?

Special-Student-7
もしも、あなたが真剣なプログラムをプログラミングするよう任務を帯びた方なのであれば、それが、知るべきこととして十分なことです。


3: 直接にUNO APIを使うのはそんなに難しくない


Special-Student-7
断言しますが、直接にUNO APIを使うのはそんなに難しくありません。

Lenard
「そんなに難しく」?どんなに難しくです?

Special-Student-7
UNO APIが本当にそうであるよりも難しく思われるかもしれない理由の1つは、それほど良くないオフィシャルドキュメントです。UNOの基本的要素を理解しさえすれば、UNO APIはかなり率直なものです、いくぶん煩わしさがありますが。

Lenard
じゃあ、煩わしいんだ!

Special-Student-7
煩わしいというのは、コードが長くなりがちだという点においてです。

Lenard
じゃあ、長くなるんだ!

Special-Student-7
それは、主に、UNOプロキシメカニズムのためで、そこでは、UNOプロキシUNOインターフェイス毎に取得しなければなりません(典型的なUNOコンポーネントは多くのUNOインターフェイスを実装している中で)、しかし、メカニズムはいかなる意味でも難しくありません、おしりの穴が少し痛む(pain in the ass)こととして、どのUNOインターフェイスたちUNOオブジェクトが実装しているかを調査しなければならないということはありますが。

Lenard
じゃあ、私のけつの穴が痛くなる(pain in my ass)んだ!なんて残酷な世界だ!

Special-Student-7
しかし、ファイルコンバージョンという限られたケースについては、その情報は本記事の中に示され、したがって、あなたのおしりの穴に何の問題もないでしょう。

Lenard
おう?私のけつの穴は大丈夫?

Special-Student-7
あなたのおしりの穴には問題がないでしょう。

それに、動作するコードを各プログラミング言語にてお示しするので、もしもお望みでしたらこと、それを単にコピーして済ますこともおできになります、そして、コピーされるべきコードの長さは、あなたの作業量に対して影響しないはずです。


4: UNO APIによるファイルコンバージョンロジック


Special-Student-7
UNO APIで任意のファイルをコンバートするというのは、元のファイルをオープンし、オープンされたドキュメントをターゲットフォーマットにて格納し、オープンされたドキュメントをクローズするというだけのことです。

まともなプログラマーであれば、そのような基本的なタスクを書くことに躊躇しないでしょう。

Abby
「オープンされたドキュメントをターゲットフォーマットにて格納し」というのはうさんくさく簡単すぎるように表現されてるように思えるんですけどね。それって、実は、100行ぐらい要したりするんんじゃないの?

Special-Student-7
それは、実際に、格納メソッドを、ある引数に格納フィルター名を指定してコールするだけのことです。

Abby
1行なのね、それじゃあ?

Special-Student-7
えーと、1行か否かはあなたがコードをどう書くかによります: UNOのいつもの煩わしさとして、あなたは、格納メソッドを持つUNOプロキシを取得しなければなりませんし、当該引数は実際にはプロパティのシーケンスであって、したがって、それは、それらの準備を1行に押し込めるか否かの問題です。

Abby
「プロパティのシーケンス」はうさんくさいわ。たくさんのプロパティをセットしないといけないみたい。

Special-Student-7
特にそういうことはありません。それは、ターゲットファイルのためのいくつか特定の指定を指示するためのものです。特定の指定をお考えでなかったら、格納フィルター名が、指定される必要のある唯一のものです。

Abby
どんな格納フィルター名を指定できるの?

Special-Student-7
以下が、典型的な格納フィルターです。

名前記述
writer8OpenDocument Textファイへのフィルター
calc8OpenDocument Spreadsheetファイルへのフィルター
impress8OpenDocument Presentationファイルへのフィルター
MS Word 2007 XMLMicrosoft Word 2007 XMLファイルへのフィルター
Calc MS Excel 2007 XMLMicrosoft Excel 2007 XMLファイルへのフィルター
Impress MS PowerPoint 2007 XMLMicrosoft PowerPoint 2007 XMLファイルへのフィルター
MS Word 97Microsoft Word 97ファイルへのフィルター
MS Excel 97Microsoft Excel 97ファイルへのフィルター
MS PowerPoint 97Microsoft PowerPoint 97ファイルへのフィルター
Text - txt - csv (StarCalc)CSVファイルへのフィルター
writer_pdf_ExportWriterドキュメントからPDFファイルへのフィルター
calc_pdf_ExportCalcドキュメントからPDFファイルへのフィルター
impress_pdf_ExportImpressドキュメントからPDFファイルへのフィルター
draw_pdf_ExportDrawドキュメントからPDFファイルへのフィルター
EPUBEPUBファイルへのフィルター
XHTML Writer FileWriterドキュメントからXHTMLファイルへのフィルター
XHTML Calc FileCalcdドキュメントからXHTMLファイルへのフィルター
XHTML Impress FileImpressドキュメントからXHTMLファイルへのフィルター
XHTML Draw FileDrawドキュメントからXHTMLファイルへのフィルター
writer_jpg_ExportWriterドキュメントからJPEGファイルへのフィルター
calc_jpg_ExportCalcドキュメントからJPEGファイルへのフィルター
impress_jpg_ExportImpressドキュメントからJPEGファイルへのフィルター
draw_jpg_ExportDrawドキュメントからJPEGファイルへのフィルター
writer_png_ExportWriterドキュメントからPNGファイルへのフィルター
calc_png_ExportCalcドキュメントからPNGファイルへのフィルター
impress_png_ExportImpressドキュメントからPNGファイルへのフィルター
draw_png_ExportDrawドキュメントからPNGファイルへのフィルター
writer_layout_dumpWriterドキュメントからWriterレイアウトファイルへのフィルター

Abby
"シーケンス"というのは . . .

Special-Student-7
'シーケンス'はUNOデータタイプの1つであって、C#の'配列'にマップされています、例えば。

Abby
じゃあ、それだけなの?ただ、オープンして、格納して、クローズするだけ?

Special-Student-7
はい、基本としては。もしも、ドキュメントを調整したいのであれば、それに加えて、調整に応じた方法を知る必要がありますが。

Abby
騙されてるような気がする。

Special-Student-7
その必要はありません。私が推測するには、UNOプログラミングを開始するのに最も高いハードルは、コーディングではなく、開発環境を構築することおよびあなたのプログラムをビルドするために参照されるべきものが何かを知ることです。オフィシャルドキュメントは、参照されるべきJarファイル群、ヘッダファイル群、ライブラリ群、等について詳述しませんから。

Abby
じゃあ、私は騙されてるわけね。

Special-Student-7
そうでないと期待しています: そのハードルは、ある記事(Linux用またはMicrosoft Windows用)に含まれている適切な情報でクリアできます。

Abby
でもそうなったとしても、私のプログラム内にファイルコンバージョンロジックだけを書いて終わりというわけではないでしょう?

Special-Student-7
あなたは、あなたのプログラムをオフィスインスタンスへ、ある記事(Java用C++用C#用Python用)にしたがって接続することができます。


5: 4つの可能な方法、非推奨のものを含めて


Special-Student-7
私は自分の方法についてためらいがありませんが、あなたはまだ他のオプションをご検討されているかもしれません。

LibreOfficeまたはApache OpenOfficeを用いてファイルをコンバートする4つの可能な方法を考えて見ましょう、推奨されない方法を含めて。

方法1は、あなたのプログラムにただ'soffice --convert-to'を実行させることです。

方法2は、オフィスインスタンス(LibreOfficeまたはApache OpenOfficeインスタンス)を事前に開始しておき、あなたのプログラムに'soffice --convert-to'を、オフィスインスタンスのオペレーティングシステムユーザーで実行させることです。オフィスインスタンスが'soffice --convert-to'実行によってシャットダウンされないように留意される必要があります。

方法3は、オフィスインスタンスを事前にTCP/IPソケットUNOサーバーとして開始しておき、ファイルコンバージョンロジックをあなたの外部UNOクライアントに実装することです。

方法4は、オフィスインスタンスを事前にTCP/IPソケットUNOサーバーとして開始しておき、ファイルコンバージョンロジックをオフィスインスタンス内にUNOサービスまたはマクロとして実装し、あなたの外部UNOクライアントにそのUNOサービスまたはマクロを呼び出させることです。

Abby
えーと、方法2で、どうしたら、"オフィスインスタンスがシャットダウンされないように留意"できるわけ?

Special-Student-7
私が今までに試したどのオフィスバージョンでも、もしもオフィスインスタンスをヘッドレスモードまたはインビジブルモードでただ開始しただけだと、'soffice --convert-to'実行はそのオフィスインスタンスをシャットダウンします。したがって、ある後のセクションに記述された対策を取られるか、オフィスインスタンスを非ヘッドレス、非インビジブルモードで開始される必要があります。

Abby
オフィスインスタンスをWindowsサービスにするべきじゃあないの?

Special-Student-7
必ずそうすべきということはありませんが、オフィスインスタンスをLinuxデーモンまたはWindowsサービスにするのは確かにリーズナブルなオプションです(そうする方法はある記事(デーモン用またはWindowsサービス用に説明されています)。

Abby
. . . "UNOサービス"はどうやって作れるの?

Special-Student-7
それは、Java用C++用Python用のある記事に説明されています。

Abby
C#と私が無視されてる!

Special-Student-7
サーバー部分はC#では作成できません、外部UNOクライアントをC#で作成することはできますが。したがって、あなたのオプションは、サーバー部分にJava、C++、Pythonを使うか、方法3でいくことです。


6: 上記4つの方法の効率以外の含み


Special-Student-7
上記4つの方法の効率を次セクションにて見る前に、4つの方法の効率以外の含みを検討します。

方法1と方法2の深刻な問題は、'soffice --convert-to'の複数同時実行が失敗することです、少なくとも、私が今までに試みたオフィスバージョンでは。

Abby
それは、効率問題でしょう、実際には、だって、結局、リクエスト群をシンクロナイズドしなければならないから、それは効率問題以外の何物でもない。

Special-Student-7
えーと、あなたは実質的に正しいと私は思います、私が申し上げたのは、シンクロナイズするという解決策にあなたが向かう前には、それは、効率以外の問題であるように見えるかもしれないということです。

Abby
いずれにせよ、同時には1実行しかできないというのは、一定のトラフィック下では受け入れられません。

Special-Student-7
方法1および方法2の別の問題は、'soffice --convert-to'の実行は、オフィスサーバーに対してローカルでなければならないということです。

Abby
それは、私のプログラムはオフィスインスタンスと同一コンピュータ内にいないといけないということね . . .

Special-Student-7
えーと、実行をプログラムがオフィスインスタンスコンピュータへSSHか何かを介して送るということは可能ですが。

Abby
ああ、それは可能ね、でもオーバーヘッドがある。

Special-Student-7
それに、実行はオフィスインスタンスオペレーティングシステムユーザーによって行なわれなければなりません。

Abby
ふーん、それは致命的じゃないけど、望ましくはないわね; 私のWebアプリケーションは別のユーザーで動かしたいわ、だって、ドキュメントファイルに直接アクセスする権限は必要ないはずだもの。

Special-Student-7
方法1および方法2の別の問題は、コンバージョンの仕様について、あなたはフルコントロールを持ってないことです。

Abby
方法3と方法4はフルコントロールを持ってるの?

Special-Student-7
はい。ドキュメント格納メソッドへフルにプロパティ群を指定することに加えて、それらは、ドキュメントをいかなる形においても調整することができます。

Lenard
"調整"?私がドキュメントを調整したがってるって?

Special-Student-7
私は存じません。 . . . しかし、スタイルを変更できたり、ページヘッダか何かを追加できたり、等すれば、それは便利かもしれません。

Lenard
方法3および方法4の効率以外の含みは何?

Special-Student-7
それらには上記の問題がありません。

Lenard
他の問題は?

Special-Student-7
一部の人々は、UNO APIが彼らのプログラミング言語、例えばPHPで使えないことに苦情を唱えるかもしれません。

Lenard
ああ、それは彼らの問題だ。

Special-Student-7
えーと、もしも彼らのプログラミング言語がUNO APIを直接に使えないとしても、UNO APIを、例えばJavaか何かで実装されたWebアプリケーションを介して間接に使うことは可能なはずです。それに、PHPは、C++で書かれたPHPエクステンションを持つことが可能なはずです。

Lenard
彼らがJavaで、またはC++で何か書けるものと、あなたは想定するべきじゃない。

Special-Student-7
彼らの全員が自らそうできると想定してはいません、しかし、彼らは誰かに代わりにそうしてくれるように頼んだりできないのでしょうか?

Lenard
私は知らない; それは彼らの問題だ。


7: 4つの方法の効率を比較する


Special-Student-7
いくつかのファイルをコンバートするのにかかる時間を4つの方法にて比較しましょう。

10個のとても小さな(それぞれ33文字を含む)ODFテキストドキュメントを10個のMicrosoft Word 97-2003ファイルに、上記4つの方法のそれぞれでコンバートするのにかかる時間を計測しました(全てのテストプログラムはC++で書かれています)。各オフィスインスタンスはテストプログラムと同一のコンピュータにヘッドレスモードにています。方法1および方法2は、SSHを介さずに、またはSSHを介してテストしています。SSHを介したテストは、'ssh'コマンドをファイルコンバージョン毎に実行して行われたか(SSH-1)または一度だけSSHコネクションを確立して複数ファイルコンバージョンコマンドをその単一SSHコネクションを通して送ったか(SSH-2)で行なわれました。

結果を判断されるにあたっては、テストコンピュータ(Linuxマシン)はとても低速であり単一コアCPU1つのみを持っているという事実に留意してください。

以下が、各方法の5回テストの最小・最大タイムを除外した平均タイム(ミリ秒)です。

@出力
+------------+------+------+------+------+------+------+-----+-----+
|The way     |1 not |1     |1     |2 not |2     |2     |3    |4    |
|            |via   |via   |via   |via   |via   |via   |     |     |
|            |SSH   |SSH-1 |SSH-2 |SSH   |SSH-1 |SSH-2 |     |     |
+------------+------+------+------+------+------+------+-----+-----+
|The time    |32,899|52,733|27,859| 3,448|20,281| 5,276|3,066|2,873|
+------------+------+------+------+------+------+------+-----+-----+
|The overhead|30,026|49,860|24,986|   575|17,408| 2,403|  193|    0|
+------------+------+------+------+------+------+------+-----+-----+

Lenard
ふーむ、方法1とSSH-1が疑いなく遅いということは分かる . . .

Special-Student-7
それは予期されたとおりです、メカニズムを考慮すれば。

方法1がそんなに遅い理由は、コンバージョン毎にオフィスインスタンスをスタートアップ・シャットダウンすることで、それは、確かに無視できない時間をとります。

Abby
なんで、方法2はそんなに違うわけ?

Special-Student-7
'soffice'実行がどのように動作するかをご理解ください。方法2では、'soffice --convert-to'は、新たなオフィスインスタンスを開始しません。

それが、少なくとも方法2を取られるようお勧めする理由です、もしも、どうしても'soffice --convert-to'を使うと言われる場合には。

Lenard
SSH を介さない方法2とSSH-2を介する方法2は、それぞれ、方法4の1.2倍、1.8倍を要すると . . .

Special-Student-7
多分、その比率を考えるのはあまり有用でありません、なぜなら、それらは、純粋にファイルをコンバートした時間に依存するからです。それが、私がオーバーヘッドタイムをそこに示した理由です。

Lenard
"オーバーヘッドタイム"?

Special-Student-7
純粋にファイルをコンバートするのにかかった時間は、全ての方法について同じはずです; 問題は、他の部分にかかった時間です。

Lenard
すると、SSHを介さない方法2でのファイルコンバージョン毎のオーバーヘッドタイムは約57ミリ秒と、 . . . 大したことはないな、SSH-2を介した方法2の2.4秒は考えさせるけどな。

Special-Student-7
勿論、それはあなたのシステム要件に依存するでしょう。

Abby
方法2が十分良さそうだわ。

Special-Student-7
しかし、同時実行問題を忘れるべきではありません。


8: オフィスインスタンスがシャットダウンされるのを防ぐ方法


Special-Student-7
方法2で行かれると仮定して、オフィスインスタンスをヘッドレスモードまたはインビジブルモードで単純に開始したら、'soffice --convert-to'実行はもれなくそのインスタンスをシャットダウンします、少なくとも私が試した全てのオフィスバージョンにおいては。

Lenard
なんとおせっかいな!何でそんなことをするんだ?

Special-Student-7
結局のところ、'soffice --convert-to'は方法1を想定しており、したがって、それが開始したという想定のインスタンスをクリーンアップしないといけないと考えるのです。

Lenard
なるほど。

Special-Student-7
いずれにせよ、あなたのプログラムはオフィスインスタンスがシャットダウンさるのを防ぐことができます、シャットダウンに対して拒否権発動することによって。

Lenard
そんなことをできる?「拒否権」?大統領のように?

Special-Student-7
はい。あなたのプログラムは、自らをオフィスインスタンスへオフィスインスタンス終了試行リスナーとして登録します、すると、オフィスインスタンスが自らをシャットダウンしようとする時に、あなたのプログラムはそれがオーケーであるかを尋ねられ、あなたのプログラムは"ノー!"と答えることができます。

以下は、各プログラミング言語における、オフィスインスタンス終了試行リスナーおよびそのインスタンスを登録・登録解除するコード断片です、そこで'l_underlyingRemoteUnoObjectsContextInXComponentContext'は、当該オフィスインスタンスへのUNOオブジェクト群コンテキストです。

@Java ソースコード
~

~
import com.sun.star.frame.TerminationVetoException;
import com.sun.star.frame.XDesktop;
import com.sun.star.frame.XTerminateListener;
import com.sun.star.lib.uno.helper.WeakBase;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XInterface;
~

public class Test1Test {
	private static class OfficeTerminationQueryListener extends WeakBase implements XTerminateListener {
		public OfficeTerminationQueryListener () {
		}
		
		@Override
		public void queryTermination (com.sun.star.lang.EventObject a_event) throws TerminationVetoException {
			throw new TerminationVetoException ();
		}
		
		@Override
		public void notifyTermination (com.sun.star.lang.EventObject a_event) {
		}
		
		@Override
		public void disposing (com.sun.star.lang.EventObject a_event) {
		}
	}
	
	public static void main (String [] a_argumentsArray) {
		~
				XDesktop l_unoDesktopInXDesktop = UnoRuntime.queryInterface (XDesktop.class, (XInterface) l_underlyingRemoteUnoObjectsContextInXComponentContext.getValueByName ("/singletons/com.sun.star.frame.theDesktop"));
				OfficeTerminationQueryListener l_officeTerminationQueryListener = new OfficeTerminationQueryListener ();
				l_unoDesktopInXDesktop.addTerminateListener (l_officeTerminationQueryListener);
				~
				l_unoDesktopInXDesktop.removeTerminateListener (l_officeTerminationQueryListener);
				~
		~
	}
}

@C++ ソースコード
// .hpp file
~
	~
	#include <com/sun/star/frame/XTerminateListener.hpp>
	#include <com/sun/star/lang/EventObject.hpp>
	#include <cppuhelper/compbase1.hxx>
	~
	
	using namespace ::std;
	using namespace ::com::sun::star::frame;
	using namespace ::com::sun::star::lang;
	using namespace ::cppu;
	~
	
	~
				class Test1Test {
					private:
						class OfficeTerminationQueryListener: public WeakImplHelper1 <XTerminateListener> {
							public:
								OfficeTerminationQueryListener ();
								virtual ~OfficeTerminationQueryListener ();
								virtual void SAL_CALL queryTermination (::com::sun::star::lang::EventObject const & a_event) override;
								virtual void SAL_CALL notifyTermination (::com::sun::star::lang::EventObject const & a_event) override;
								virtual void SAL_CALL disposing (::com::sun::star::lang::EventObject const & a_event) override;
						};
					public:
						static int main (int const & a_argumentsNumber, char const * const a_argumentsArray []);
				};
	~
~

// .cpp file
~
#include <com/sun/star/frame/TerminationVetoException.hpp>
#include <com/sun/star/frame/XDesktop.hpp>
#include <com/sun/star/uno/Any.hxx>
#include <com/sun/star/uno/Reference.hxx>
~
#include "theBiasPlanet/unoUtilities/stringsHandling/UnoExtendedStringHandler.hpp"
~

using namespace ::com::sun::star::frame;
using namespace ::com::sun::star::uno;
~
using namespace ::theBiasPlanet::unoUtilities::stringsHandling;
~

~
			Test1Test::OfficeTerminationQueryListener::OfficeTerminationQueryListener (): WeakImplHelper1 <XTerminateListener> () {
			}
			
			Test1Test::OfficeTerminationQueryListener::~OfficeTerminationQueryListener () {
			}
			
			void SAL_CALL Test1Test::OfficeTerminationQueryListener::queryTermination (::com::sun::star::lang::EventObject const & a_event) {
				throw TerminationVetoException ();
			}
			
			void SAL_CALL Test1Test::OfficeTerminationQueryListener::notifyTermination (::com::sun::star::lang::EventObject const & a_event) {
			}
			
			void SAL_CALL Test1Test::OfficeTerminationQueryListener::disposing (::com::sun::star::lang::EventObject const & a_event) {
			}
			
			int Test1Test::main (int const & a_argumentsNumber, char const * const a_argumentsArray []) {
				~
						Reference <XDesktop> l_unoDesktopInXDesktop ( * ( (Reference <XInterface> *) l_underlyingRemoteUnoObjectsContextInXComponentContext->getValueByName (UnoExtendedStringHandler::getOustring ("/singletons/com.sun.star.frame.theDesktop")).getValue ()), UNO_QUERY);
						Reference <XTerminateListener> l_officeTerminationQueryListener (new OfficeTerminationQueryListener ());
						l_unoDesktopInXDesktop->addTerminateListener (l_officeTerminationQueryListener);
						~
						l_unoDesktopInXDesktop->removeTerminateListener (l_officeTerminationQueryListener);
						~
				~
			}
~

"UnoExtendedStringHandler::getOustring"は、標準文字列からUNO文字列を得る私のユーティリティメソッドです。

@C# ソースコード
~
			~
			using uno;
			using uno.util;
			using unoidl.com.sun.star.frame;
			using unoidl.com.sun.star.lang;
			using unoidl.com.sun.star.uno;
			~
			
			public class Test1Test {
				private class OfficeTerminationQueryListener: WeakBase, XTerminateListener {
					public OfficeTerminationQueryListener () {
					}
					
					public void queryTermination (unoidl.com.sun.star.lang.EventObject a_event) {
						throw new TerminationVetoException ();
					}
					
					public void notifyTermination (unoidl.com.sun.star.lang.EventObject a_event) {
					}
					
					public void disposing (unoidl.com.sun.star.lang.EventObject a_event) {
					}
				}
				
				public void main (String [] a_argumentsArray) {
					~
								XDesktop l_unoDesktopInXDesktop = (XDesktop) (l_underlyingRemoteUnoObjectsContextInXComponentContext.getValueByName ("/singletons/com.sun.star.frame.theDesktop").Value);
								OfficeTerminationQueryListener l_officeTerminationQueryListener = new OfficeTerminationQueryListener ();
								l_unoDesktopInXDesktop.addTerminateListener (l_officeTerminationQueryListener);
								~
								l_unoDesktopInXDesktop.removeTerminateListener (l_officeTerminationQueryListener);
								~
					~
				}
			}
~

@Python ソースコード
from typing import List
from typing import cast
~
import uno
from com.sun.star.frame import TerminationVetoException
from com.sun.star.frame import XDesktop
from com.sun.star.frame import XTerminateListener
from com.sun.star.lang import EventObject as com_sun_star_lang_EventObject
from com.sun.star.uno import XInterface
from unohelper import Base as UnoBase
~

class Test1Test:
	class OfficeTerminationQueryListener (UnoBase, XTerminateListener):
		def __init__ (a_this: "Test1Test.OfficeTerminationQueryListener") -> None:
			None
		
		def queryTermination (a_this: "Test1Test.OfficeTerminationQueryListener", a_event: com_sun_star_lang_EventObject) -> None:
			raise TerminationVetoException ()
		
		def notifyTermination (a_this: "Test1Test.OfficeTerminationQueryListener", a_event: com_sun_star_lang_EventObject) -> None:
			None
		
		def disposing (a_this: "Test1Test.OfficeTerminationQueryListener", a_event: com_sun_star_lang_EventObject) -> None:
			None
			
	@staticmethod
	def main (a_arguments: List [str]) -> None:
		~
				l_unoDesktopInXDesktop: XDesktop = cast (XDesktop, cast (XInterface, l_underlyingRemoteUnoObjectsContextInXComponentContext.getValueByName ("/singletons/com.sun.star.frame.theDesktop")))
				l_officeTerminationQueryListener: "Test1Test.OfficeTerminationQueryListener" = Test1Test.OfficeTerminationQueryListener ()
				l_unoDesktopInXDesktop.addTerminateListener (l_officeTerminationQueryListener)
				~
				l_unoDesktopInXDesktop.removeTerminateListener (l_officeTerminationQueryListener)
				~
		~


9: いくつかのプログラミング言語における実装を本記事の引き続くパートにて見ます


Special-Student-7
これで、私たちは、LibreOfficeまたはApache OpenOfficeを用いて最適にファイルをコンバートする方法のコンセプトを理解しました。

いくつかのプログラミング言語(JavaC++C#PythonLibreOffice Basic)における実装を本記事の引き続くパートにて見ます。


参考資料


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