2020年4月12日日曜日

38: ワードプロセッサードキュメントのページのサイズをUNOを用いてセットする

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

任意のワードプロセッサードキュメント(典型的には、OpenDocument Text/Office Open XML Document/Microsoft Wordファイルに関連付けられている)、LibreOfficeを用いて

話題


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

この記事の目次


開始コンテキスト



ターゲットコンテキスト



  • 読者は、LibreOfficeまたはApache OpenOfficeインスタンスにロードされた任意のワードプロセッサードキュメントの任意のページのサイズを読者のプログラムからセットする方法を知る。
ト書き
Hypothesizer 7、Objector 38A、Objector 38Bがコンピューターの前にいる。


オリエンテーション


Hypothesizer 7
本記事では、LibreOfficeまたはApache OpenOfficeインスタンスにロードされた任意のワードプロセッサードキュメントの任意のページのサイズを、私たちのプログラムからセットする方法を知ります。

ご注目いただきたいのですが、私は「ワードプロセッサードキュメント」と言ったのであって、「ワードプロセッサードキュメントファイル」とは言いませんでした。

Objector 38A
はあ?お前、うわごとを言ってるのか?

Hypothesizer 7
...サー、私は単語群をとても注意深く使います。ファイルというのは、ビット群のシーケンスがあるストレージ(例えば、ハードディスク)に格納されたものであり、'ドキュメント'で私が意味するのは、ひとかたまりのドキュメント的情報を代表するオブジェクトです。

Objector 38A
お前は間違いなくうわごとを言っている。

Hypothesizer 7
...LibreOfficeメニューで'File' -> 'New' -> 'Text Document'とすると、新たなドキュメントが作成されますが、それは、いかなるファイルにも関連付けられていません、少なくとも、まだ。ある特定のフォーマットのドキュメントファイルをLibreOfficeインスタンスにロードすると、それは、LibreOfficeインスタンス内のドキュメントになります。...とにかく、そうしたドキュメントはジェネリックです。

Objector 38A
...「ジェネリック」とはどういう意味だ?

Hypothesizer 7
私が言っているのは、そうしたドキュメントはどれも、何か特定のファイルフォーマットのものというわけではないということです: ファイルフォーマットは、ドキュメントがストレージに格納される際にそれがどのようにシリアライズされるかだけの問題です。

Objector 38A
だから何だ?

Hypothesizer 7
私は、私たちが行なうことを正確に述べたかったのです: 私たちはファイルのページのサイズをセットするのではなく、ドキュメントのページのサイズをセットします。あなたが、その後にそのドキュメントをいかなるファイルフォーマットで格納するか、もしくはそのドキュメントを全然格納しないかは、全く問題ではありません。

Objector 38A
それじゃあ、本テクニックを、ワードプロセッサーファイルではなく、PDFファイルを作成するために使えるということだな、例えば?

Hypothesizer 7
はい。ドキュメントはワードプロセッサードキュメントでなければなりませんが、格納されるファイルはワードプロセッサーファイルである必要はありません。

Objector 38A
ドキュメントをプレーンテキストファイルに格納しようとしたらどうなる?

Hypothesizer 7
勿論、そうできますが、勿論、ページサイズ情報は失われます、プレーンテキストフォーマットはそんな情報を保持できませんから。

Objector 38B
スプレッドシートドキュメントはどうなったの?

Hypothesizer 7
マダム、ご心配なく: 次記事で取り扱われます。


本体


1: メカニズムとその影響を理解する


Hypothesizer 7
実のところ、ページサイズはページ自体にはセットされておらず、ページに割り当てられたスタイルにセットされています。

Objector 38A
お前なあ、うわごと言ってるぞ。

Hypothesizer 7
...ワードプロセッサードキュメントはいくつかのページスタイルを持っており、その内の1つが各ページに割り当てられています。

Objector 38A
だから何だ?

Hypothesizer 7
重要なことは、通常、1つのページスタイルが複数のページに割り当てられているということです。

Objector 38A
だから?

Hypothesizer 7
したがって、そのページスタイルのページサイズが変更されると、そのページスタイルが割り当てられている全てのページのサイズが変わります。

Objector 38A
じゃあ、それら全てのページのサイズを変えるのに、1つのページスタイルだけを変えれば済むわけだな。

Hypothesizer 7
もしも、その動作にご満足でしたら、それで結構でしょうが、もしも、1つのページだけのサイズを変えたいのであれば、新たなページスタイルを作成・セットアップし、その新たなページスタイルをその単一ページに割り当てなければならないでしょう。

Objector 38A
それは、私のプログラムからできるのか?

Hypothesizer 7
問題なく出来ます。

Objector 38A
どうやって?

Hypothesizer 7
後続のあるセクションにて論じます。


2: ワードプロセッサードキュメントの全ページスタイル群を取得する


Hypothesizer 7
ワードプロセッサードキュメントに格納されている全ページスタイル群を取得しましょう。

実のところ、以下は、それを行なうJavaコードです('a_unoDocumentInXComponent'は、ドキュメントUNOオブジェクトです)。

@Java ソースコード
import com.sun.star.container.XNameContainer;
import com.sun.star.frame.XModel;
import com.sun.star.lang.XComponent;
import com.sun.star.style.XStyleFamiliesSupplier;
import com.sun.star.text.XTextDocument;
import com.sun.star.uno.AnyConverter;
import com.sun.star.uno.UnoRuntime;

		XComponent a_unoDocumentInXComponent;
		~
		XTextDocument l_unoTextDocumentInXTextDocument = (XTextDocument) UnoRuntime.queryInterface (XTextDocument.class, a_unoDocumentInXComponent);
		if (l_unoTextDocumentInXTextDocument == null) {
			// "The document is not any text document.");
		}
		else {
			XModel l_unoTextDocumentInXModel = (XModel) UnoRuntime.queryInterface (XModel.class, l_unoTextDocumentInXTextDocument);
			XStyleFamiliesSupplier l_unoTextDocumentInXStyleFamiliesSupplier = (XStyleFamiliesSupplier) UnoRuntime.queryInterface (XStyleFamiliesSupplier.class, l_unoTextDocumentInXTextDocument);
			XNameContainer l_pageStylesInXNameContainer = (XNameContainer) AnyConverter.toObject (XNameContainer.class, l_unoTextDocumentInXStyleFamiliesSupplier.getStyleFamilies ().getByName ("PageStyles"));
		}

Objector 38A
...その「ドキュメントUNOオブジェクト」はどこから来たのだ?

Hypothesizer 7
'開始コンテキスト'が述べているとおり、それをご存知であると想定されています。

Objector 38A
...

Hypothesizer 7
...もっと詳しく言うと、それは、ある以前の記事のここに記述されています。

Objector 38A
...いずれにせよ、全ページスタイルは別に欲しくないんだ、ある特定ページのページスタイルだけが欲しいわけ。

Hypothesizer 7
そうする準備として、全ページスタイル群を取得しました。それらの内の1つを選ぶ方法は、次セクションで知ります。

Objector 38B
C#版は示さないの?

Hypothesizer 7
ああ、実のところ、本記事には、Javaコードのみを準備しました(多分、いくつかの他のプログラミング言語のコードを以後に示すでしょう)。今のところは、Java版からご自分のプログラミング言語の版をあなたが導けるように期待しています。

Objector 38B
...


3: 意図するページのページスタイルを取得する


Hypothesizer 7
意図するページのページスタイルの名前を事前にご存知でしたら、そのページスタイルを、以下のようにして、取得できます('l_pageStyleName'は、その名前です)。

@Java ソースコード
import com.sun.star.beans.XPropertySet;
import com.sun.star.style.XStyle;

				String l_pageStyleName = null;
				XPropertySet l_pageStyleInXPropertySet = null;
				~
				l_pageStyleInXPropertySet = UnoRuntime.queryInterface (XPropertySet.class, AnyConverter.toObject (XStyle.class, l_pageStylesInXNameContainer.getByName (l_pageStyleName)));

Objector 38A
名前をどうやって事前に知ると想定されているんだ?

Hypothesizer 7
そのドキュメントを作成した方がページスタイル割り当てをシステマティックに計画していたら、例えば、先頭ページは'First Page'ページスタイルを持つべし、その他のページ群は'Default Style'ページスタイルを持つべしというようにしていれば、どのページがどのページスタイルを持っているか、あなたは知っているでしょう。

Objector 38A
そうでなければ?

Hypothesizer 7
特定のページインデックのページのページスタイルの名前は、以下のように取得できます('l_pageNumber'は、ページ番号です('1'から開始します))。

@Java ソースコード
import com.sun.star.text.XTextViewCursorSupplier;
import com.sun.star.text.XPageCursor;

				int l_pageNumber = 0;
				~
				XTextViewCursorSupplier l_controllerInXTextViewCursorSupplier = (XTextViewCursorSupplier) UnoRuntime.queryInterface (XTextViewCursorSupplier.class, l_unoTextDocumentInXModel.getCurrentController ());
				XPageCursor l_pageCursorInXPageCursor = (XPageCursor) UnoRuntime.queryInterface (XPageCursor.class, l_controllerInXTextViewCursorSupplier.getViewCursor ());
				XPropertySet l_pageCursorInXPropertySet = UnoRuntime.queryInterface (XPropertySet.class, l_pageCursorInXPageCursor);
				boolean l_pageIsValid = l_pageCursorInXPageCursor.jumpToPage ((short) (l_pageNumber));
				l_pageStyleName = (String) l_pageCursorInXPropertySet.getPropertyValue ("PageStyleName");

Objector 38A
...なるほど。


4: ページサイズをページスタイルにセットする


Hypothesizer 7
ページサイズはページスタイルに以下のようにセットできます(サイズはA4横サイズです)。

@Java ソースコード
import com.sun.star.awt.Size;

						Size i_pagesSize = new Size (29700, 21000);
						~
						l_pageStyleInXPropertySet.setPropertyValue ("Size", i_pagesSize);
						l_pageStyleInXPropertySet.setPropertyValue ("IsLandscape", Boolean.valueOf (true));

Objector 38A
...それらの数字は何だ?

Hypothesizer 7
それらは100分の1ミリメートル単位の長さです。

Objector 38A
えーと...

Hypothesizer 7
'29700'は'297.00' mmを意味します。

Objector 38A
ああ。


5: 新たなページスタイルを作成してそれをページに割り当てる


Hypothesizer 7
新たなページスタイルが必要(当該ページスタイルを共有している他のページのサイズを変更したくないがゆえに)なのであれば、それは'.uno:StyleNewByExample'というUNOディスパッチコマンドで作成できます。

Objector 38B
...そのUNOディスパッチコマンドは、Calc用であって、Writer用じゃないんじゃない?

Hypothesizer 7
ああ、仰るとおりです、しかし、実際には、それに相当するUNOディスパッチコマンドが、Writer用に、同一URL、同一引数で存在します。

Objector 38B
実のところ、私はUNOディスパッチコマンドなんて使ったことないのよね...

Hypothesizer 7
プログラミング言語毎に任意のUNOディスパッチコマンドを実行する方法は、以下の記事群(Java編C++編C#編Python編LibreOfficeまたはApache OpenOffice Basic編)に記述されています。

Objector 38B
あっ、そう。

Hypothesizer 7
新たなページスタイルはページに以下のように割り当てることができます('l_newPageStyleName'は新たなページスタイルの名前です)。

@Java ソースコード
						String l_newPageStyleName;
						~
						l_pageCursorInXPropertySet.setPropertyValue ("PageStyleName", l_newPageStyleName);


6: サンプルプログラムを実行する


Hypothesizer 7
実は、ワードプロセッサードキュメントの全ページにあるサイズをセットするドキュメントテーラーを、私が作成しました。

Objector 38A
「ドキュメントテーラー」?

Hypothesizer 7
ある以前の記事のあるサブセクションをご参照ください。

Objector 38A
...それはともかく、全ページに単一サイズなのか?

Hypothesizer 7
実のところ、そうです。もっと精巧なテーラリングをされたいのであれば、ご自身のドキュメントテーラーを作成いただく必要があります。

Objector 38A
...お前のテーラーはどこにある?

Hypothesizer 7
私のテーラークラスは、このZIPファイルに格納されている'unoUtilitiesToBeDisclosed'プロジェクト内にある'theBiasPlanet.unoUtilities.documentsHandling.UnoTextDocumentSetPageStylesTailor'です。

実際には、そのZIPファイルは、ある以前の記事(コンセプトあるJava実装あるC++実装あるC#実装あるPython実装)で紹介されたファイルコンバージョンサンプルプログラム群のものであり、そのプロジェクトをビルドする方法およびプログラム群を実行する方法は、その以前の記事に記述されています。

任意のドキュメントテーラーを使用するための、ファイルコンバージョン群命令CSVファイルの仕様は以下のとおりです。

コンバート元ファイルURL
コンバート先ファイルURL
ドキュメント格納フィルター名
コンバート元ファイルオープンパスワード(オプション)
ドキュメントテーラー名(オプション)
コンバート先ファイルタイトル(オプション)
コンバート先ファイルオープンパスワード(オプション)
コンバート先ファイル編集パスワード(オプション)

Objector 38A
...「テーラー名」というのはクラス名なのか?

Hypothesizer 7
いいえ、それは、'filesConverter'プロジェクト内の'theBiasPlanet.filesConverter.programs.FilesConverterConsoleProgram'クラス内の'l_unoDocumentTailorNameToUnoDocumentTailorMap'マップデータに登録されたクラスインスタンスの名前です。

Objector 38A
「クラスインスタンス」?

Hypothesizer 7
各クラスインスタンスが特定のページサイズに対応します。

Objector 38A
ああ、それでは、新たなサイズが欲しければ、新たなインスタンスを登録すればよいわけだ。


7: 結びとその先


Hypothesizer 7
これで、私たちは、LibreOfficeまたはApache OpenOfficeインスタンスにロードされた任意のワードプロセッサードキュメントの任意のページのサイズを、私たちのプログラムからセットする方法を知りました。

そのワードプロセッサードキュメントは、OpenDocument Textファイルからロードされたものかもしれないし、Microsoft Wordファイルからロードされたものかもしれないし、Writerプログラムがロードできる他の任意のファイルからロードされたものかもしれません。ドキュメントは、Writerプログラムが格納できる任意のファイル、例えば、PDFファイル、に格納できます。

任意のスプレッドシートドキュメントの任意のシートのページサイズを、私たちのプログラムからセットする方法を、次記事にて見ます。


参考資料


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