2020-02-16

38: Set the Size of Any Page of Word Processor Document with UNO

<The previous article in this series | The table of contents of this series | The next article in this series>

Any word processor document typically associated with an OpenDocument Text/Office Open XML Document/Microsoft Word file, using LibreOffice

Topics


About: UNO (Universal Network Objects)
About: LibreOffice
About: Apache OpenOffice
About: the Java programming language
About: C++
About: Microsoft .NET Framework
About: the Python programming language
About: LibreOffice Basic
About: Apache OpenOffice Basic
About: BeanShell
About: JavaScript

The table of contents of this article


Starting Context



Target Context


  • The reader will know how to set the size of any page of any word processor document that is loaded in a LibreOffice or Apache OpenOffice instance, from his or her program.
Stage Direction
Here are Hypothesizer 7, Objector 38A, and Objector 38B in front of a computer.


Orientation


Hypothesizer 7
In this article, we will know how to set the size of any page of any word processor document that is loaded in a LibreOffice or Apache OpenOffice instance, from our program.

Please note that I said "word processor document", not 'word processor document file'.

Objector 38A
Huh? Are you delirious?

Hypothesizer 7
. . . Sir, I use words very carefully. Any file is a sequence of bits that is stored in a storage (for example, a hard disk); by 'document', I mean an object that represents a chunk of documentary information.

Objector 38A
I'm sure you are delirious.

Hypothesizer 7
. . . When you do 'File' -> 'New' -> 'Text Document' in the LibreOffice menu, a new document is created, but it is not associated with any file at least yet; when you load a document file of a certain format into a LibreOffice instance, it becomes a document in the LibreOffice instance. . . . Anyway, those documents are generic.

Objector 38A
. . . What do you mean by "generic"?

Hypothesizer 7
I mean that any of such documents is not of any specific file format: the file format is only about how the document is serialized when the document is stored in a storage.

Objector 38A
So what?

Hypothesizer 7
I wanted to accurately state what we will do: we will not set the size of a page of a file, but set the size of a page of a document. In which file format you will store the document thereafter or whether you will not store the document at all does not matter at all.

Objector 38A
So, I can use this technique in order to create a PDF file, not a word processor file, for example?

Hypothesizer 7
Yes. The document has to be a word processor document, but the stored file does not have to be any word processor file.

Objector 38A
What if I try to store the document into a plain text file?

Hypothesizer 7
Of course, you can do so, but of course, the page size information will be lost as the plain text format cannot hold such information.

Objector 38B
What have happened to spread sheets documents?

Hypothesizer 7
Madam, do not worry: they will be treated in the next article.


Main Body


1: Undersanding the Mechanism and Its Implications


Hypothesizer 7
In fact, the page size is not set in the page itself, but in the style that is assigned to the page.

Objector 38A
You know, you are delirious.

Hypothesizer 7
. . . The word processor document has some page styles, and one of them is assigned to each page.

Objector 38A
So what?

Hypothesizer 7
What is important is that usually, a page style is assigned to some multiple pages.

Objector 38A
So?

Hypothesizer 7
So, if the page size of the page style is changed, the sizes of all the associated pages will be changed.

Objector 38A
So, I can just happily change a single page style in order to change the sizes of all the pages.

Hypothesizer 7
If you are happy with that behavior, it will be fine, but if you want to change the size of only a single page, you will have to create and setup a new page style and assign the new page style to the single page.

Objector 38A
Is that possible from my program?

Hypothesizer 7
It is certainly possible.

Objector 38A
How?

Hypothesizer 7
We will discuss it in a later section.


2: Getting the Page Styles of the Word Processor Document


Hypothesizer 7
Let us get the page styles contained in the word processor document.

In fact, this is a piece of Java code that does that, where 'a_unoDocumentInXComponent' is the document UNO object.

@Java Source Code
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
. . . Where have the "document UNO object" come from?

Hypothesizer 7
As 'Starting Context' says, you are supposed to know that.

Objector 38A
. . .

Hypothesizer 7
. . . More specifically, that is described here in a previous article.

Objector 38A
. . . Anyway, I don't particularly want all the page styles, but only the page style of a specific page.

Hypothesizer 7
As a preparation to do so, we have gotten all the page styles; we will know how to pick up one of them, in the next section.

Objector 38B
Don't you show a C# version?

Hypothesizer 7
Ah, actually, I have prepared only Java code for this article (probably, I will show code for some other programming languages later). Meanwhile, I hope that you will be able to derive your programming language version from the Java version.

Objector 38B
. . .


3: Getting the Page Style of the Intended Page


Hypothesizer 7
If you a priori know the name of the page style of the intended page, you can get the page style, like this, where 'l_pageStyleName' is the name.

@Java Source Code
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
How am I supposed to know the name a priori?

Hypothesizer 7
If the person who has created the document has planned the page sytle assignments systematically, for example, the first page should have the 'First Page' page style and the other pages should have the 'Default Style' page style, you will know which page has which page style.

Objector 38A
If not?

Hypothesizer 7
You can get the name of the page style of the page of a specific page index, like this, where 'l_pageNumber' is the page number (starting from '1').

@Java Source Code
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
. . . I see.


4: Setting the Page Size to the Page Style


Hypothesizer 7
The page size can be set to the page style, like this, where the size is the A4 landscape size.

@Java Source Code
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
. . . What are those numbers?

Hypothesizer 7
They are the lengths in hundredths of a millimeter.

Objector 38A
Well . . .

Hypothesizer 7
'29700' means '297.00' mm.

Objector 38A
Ah.


5: Creating a New Page Style and Assigning It to the Page


Hypothesizer 7
If a new page style is required (because we do not want to change the sizes of the other pages that share the page style), it can be created with a UNO dispatch command, '.uno:StyleNewByExample'.

Objector 38B
. . . That UNO dispatch command is for Calc, not for Writer, isn't it?

Hypothesizer 7
Ah, you are right, but actually, there is the exact counterpart for the UNO dispatch command for Writer with the same URL and the same arguments.

Objector 38B
Actually, I have never used any UNO dispatch command . . .

Hypothesizer 7
How to execute any UNO dispatch command in a programming language is described in one of these articles (in Java, in C++, in C#, in Python, and in LibreOffice or Apache OpenOffice Basic).

Objector 38B
Ah, so.

Hypothesizer 7
The new page style can be assigned to the page, like this, where 'l_newPageStyleName' is the name of the new page style.

@Java Source Code
						String l_newPageStyleName;
						~
						l_pageCursorInXPropertySet.setPropertyValue ("PageStyleName", l_newPageStyleName);


6: Executing a Sample Program


Hypothesizer 7
In fact, I have created a document tailor that sets a size to all the pages of the word processor document.

Objector 38A
"document tailor?"

Hypothesizer 7
Please refer to a subsection of a previous article.

Objector 38A
. . . Anyway, a single size to all the pages?

Hypothesizer 7
Actually, yes. If you want to do a more sophisticated tailoring, you will have to create your own document tailor.

Objector 38A
. . . Where is your tailor?

Hypothesizer 7
My tailor class is 'theBiasPlanet.unoUtilities.documentsHandling.UnoTextDocumentSetPageStylesTailor' in the 'unoUtilitiesToBeDisclosed' project contained in this ZIP file.

In fact, the ZIP file is of the file conversion sample programs introduced in a previous artcile (the concept, a Java implementation, a C++ implementation, a C# implementation, and a Python implementation), and how to build the project and how to execute the programs are described in the previous article.

The specifications of the file conversions order CSV file for using any document tailor is this.

The converted file URL
The converted-to file URL
The document-storing filter name
The converted file opening password (optional)
The document tailor name (optional)
The converted-to file title (optional)
The converted-to file opening password (optional)
The converted-to file editing password (optional)

Objector 38A
. . . Is "tailor name" the class name?

Hypothesizer 7
No, it is the name of the class instance registered into the 'l_unoDocumentTailorNameToUnoDocumentTailorMap' map datum in the 'theBiasPlanet.filesConverter.programs.FilesConverterConsoleProgram' class in the 'filesConverter' project.

Objector 38A
"class instance"?

Hypothesizer 7
Each class instance corresponds to a specific page size.

Objector 38A
Ah, so, I can register a new instance if I want another size.


7: The Conclusion and Beyond


Hypothesizer 7
Now, we know how to set the size of any page of any word processor document that is loaded in a LibreOffice or Apache OpenOffice instance, from our program.

The word processor document may have been loaded from a OpenDocument Text file, a Microsoft Word file, or whatever file that the Writer program can load, and the document can be stored into any file that the Writer program can store into, for example, a PDF file.

We will see how to set the page size of any sheet of any spread sheets document from our program, in the next article.


References


<The previous article in this series | The table of contents of this series | The next article in this series>