Exported sections, images quality, watermark, tagging, form fields format, whether bookmarks or comments, encrypting, restrictions, signing, etc.
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
- Orientation
- Main Body
- 1: The Mechanism
- 2: The Document-Storing Property to Be Set
- 3: The Conclusion and Beyond
Starting Context
- The reader has a basic knowledge on one of the UNO-supported programming languages (Java, C++, the Microsoft .NET Framework programming languages (C# and Visual Basic.NET, in most cases), Python, LibreOffice or Apache OpenOffice Basic, BeanShell, and JavaScript).
- The reader has a knowledge on what UNO is and how it is related to LibreOffice or Apache OpenOffice.
- The reader has a knowledge on the basic elements of UNO and the terminology used for them in this series.
- The reader has a knowledge on how to get a UNO objects context to any LibreOffice or Apache OpenOffice instance (there are some articles on how to do it for any external console Java, C++, C#, and Python programs; there is an article on how to do it for any external GUI Java program; some articles on how to do it for any external GUI C++, C#, and Python programs will come later).
- The reader has a knowledge on how to access the intended document and how to store the document into a file, using UNO (the article on how to use LibreOffice or Apache OpenOffice as a files converter (the concept, a Java implementation, a C++ implementation, a C# implementation, a Python implementation, and a LibreOffice or Apache OpenOffice Basic implementation) contains a major part of the information).
Target Context
- The reader will know how to export any Office (word processor, spread sheets, or presentation) document into a PDF file as per detailed specifications (exported sections, images quality, watermark, tagging, exporting form fields in a specific format, exporting bookmarks, exporting comments, encrypting, setting restrictions, signing, etc.) from his or her program, using LibreOffice or Apache OpenOffice and UNO.
Here are Hypothesizer 7, Objector 43A, and Objector 43B in front of a computer.
Orientation
Hypothesizer 7
In this article, we will know how to export any Office document into a PDF file as per detailed specifications from his or her program, using LibreOffice or Apache OpenOffice and UNO.
Objector 43A
Is it really "any Office document"?
Hypothesizer 7
Sir, actually, it is any LibreOffice or Apache OpenOffice Writer, Calc, or Impress document, regardless of the format or even the existence of the file associated with the document.
Objector 43A
Huh? "regardless of" what?
Hypothesizer 7
We export a document that has been loaded into LibreOffice or Apache OpenOffice Writer, Calc, or Impress; the format of the file from which the document has been loaded does not matter, even if there is such a file.
Objector 43A
There may be not such a file?
Hypothesizer 7
Right: if the document is a new document that is not stored yet, there is no such a file.
Objector 43A
Ah. Of course. So, the file can be a Microsoft Word file, a Microsoft Excel file, a plain text file, a CSV file, or whatever?
Hypothesizer 7
Whatever LibreOffice or Apache OpenOffice can load as a Writer, Calc, or Impress document, yes.
Objector 43B
What detailed specifications can I specify?
Hypothesizer 7
Madam, that is what you can know in this article, but in short words, all the specifications you can specify in the LibreOffice or Apache OpenOffice GUI.
Objector 43B
So, can I even sign the PDF file?
Hypothesizer 7
Yes, you can.
Main Body
1: The Mechanism
Hypothesizer 7
The mechanism for exporting any document into a PDF file is exactly what is described in a previous article (the concept, a Java implementation, a C++ implementation, a C# implementation, a Python implementation, and a LibreOffice or Apache OpenOffice Basic implementation), and I will not repeat it here.
The theme of this article is the document-storing property to be set for detailed PDF specifications.
2: The Document-Storing Property to Be Set
Hypothesizer 7
The document-storing property to be set is 'FilterData', which takes a 'sequence' of '::com::sun::star::beans::PropertyValue's.
Objector 43B
What is "'sequence'", exactly?
Hypothesizer 7
By 'sequence', I mean a UNO datum type, not 'sequence in general' (which is why I have quoted the term).
Objector 43B
So, is there a specific class that represents the datum type?
Hypothesizer 7
For C++, yes; for Java and C#, it is mapped to array; for Python, it is mapped to 'List'.
Objector 43B
Whatever.
Hypothesizer 7
These are the properties that can be included in the 'sequence', where the types except "any" are UNO datum types ('any' is not any datum type, but means that any UNO datum is accepted).
Name | Type | Value |
---|---|---|
PageRange | string | the pages range: '' -> all the pages, '1-2,4', etc. |
Selection | any | the exported sections: the selection gotten by 'XSelectionSupplier.getSelection ()' of the controller of the document, or an arbitrary object (for example, a cells range) |
UseLosslessCompression | boolean | lossless compression is used: 'false' -> a JPEG compression is used |
Quality | short | the JPEG quality in % |
ReduceImageResolution | boolean | the image resolutions are reduced |
MaxImageResolution | short | the maximum image resolution in DPI: 75, 150, 300, 600, or 1200 |
Watermark | string | the watermark string |
IsAddStream | boolean | the original document is embedded |
SelectPdfVersion | short | the PDF version: '0' -> PDF 1.4, '1' -> PDF/A-1 |
UseTaggedPDF | boolean | the tagged PDF is used |
ExportFormFields | boolean | the form fields are exported |
FormsType | short | the forms type: '0' -> FDF, '1' -> PDF, '2' -> HTML, '3' -> XML |
AllowDuplicateFieldNames | boolean | some duplicate field names are allowed |
ExportBookmarks | boolean | the bookmarks are exported |
ExportPlaceholders | boolean | the placeholders are exported |
ExportNotes | boolean | the comments are exported |
IsSkipEmptyPages | boolean | the automatically inserted empty pages are skipped |
UseReferenceXObject | boolean | the Form XObjects are used |
ViewPDFAfterExport | boolean | the target file is shown after the exporting has been completed |
InitialView | short | for the after-the-exporting-showing of the target file, the initial view style: '0' -> pages only, '1' -> bookmarks and pages, '2' -> thumbnails and pages |
InitialPage | short | for the after-the-exporting-showing of the target file, the initial page number |
Magnification | short | for the after-the-exporting-showing of the target file, the initial magnification: '0' -> default, '1' -> the whole page is fitted into the window, '2' -> the page width is fitted into the window, '3' -> the page contents are supposed to be fitted into the window, but not necessarily are so |
Zoom | short | for the after-the-exporting-showing of the target file, the initial zooming factor in % |
PageLayout | short | for the after-the-exporting-showing of the target file, the initial page layout style: '0' -> default, '1' -> single page, '2' -> continuous, '3' -> each 2 facing pages are shown abreast and those pairs are shown continuously connected vertically |
FirstPageOnLeft | boolean | for the after-the-exporting-showing of the target file, the first page is on left: valid only when 'PageLayout' is '3' |
ResizeWindowToInitialPage | boolean | for the after-the-exporting-showing of the target file, the window is resized to the initial page |
CenterWindow | boolean | for the after-the-exporting-showing of the target file, the window is centered on the screen |
OpenInFullScreenMode | boolean | for the after-the-exporting-showing of the target file, the window is opened in the full screen mode |
DisplayPDFDocumentTitle | boolean | for the after-the-exporting-showing of the target file, the document title is shown |
UseTransitionEffects | boolean | for the after-the-exporting-showing of the target file, the transition effects are used |
HideViewerMenubar | boolean | for the after-the-exporting-showing of the target file, the menubar is hidden |
HideViewerToolbar | boolean | for the after-the-exporting-showing of the target file, the toolbar is hidden |
HideViewerWindowControls | boolean | for the after-the-exporting-showing of the target file, the window controls are hidden |
OpenBookmarkLevels | short | for the after-the-exporting-showing of the target file, the opened bookmark levels: '-1' -> all |
ExportBookmarksToPDFDestination | boolean | the bookmarks are exported as named destinations |
ConvertOOoTargetToPDFTarget | boolean | the document links are converted to PDF targets |
ExportLinksRelativeFsys | boolean | the relative file links are exported |
PDFViewSelection | short | the cross documents links viewer: '0' -> the default viewer, '1' -> a PDF reader application, '2' -> an internet browser |
EncryptFile | boolean | the file is encrypted |
DocumentOpenPassword | string | the opening password |
RestrictPermissions | boolean | some actions are restricted |
PermissionPassword | string | the restricted actions password |
Printing | short | the printing restriction: '0' -> not permitted, '1' -> only in a low resolution (150 DPI), '2' -> also in high resolutions |
Changes | short | the changing restriction: '0' -> not permitted, '1' -> inserting, deleting, and rotating pages, '2' -> filling in form fields, '3' -> commenting and filling in form fields, '4' -> any except extracting pages |
EnableCopyingOfContent | boolean | copying of contents is allowed |
EnableTextAccessForAccessibilityTools | boolean | text access for accessibility tools is allowed |
SignPDF | boolean | the file is signed |
SignatureCertificate | ::com::sun::star::security::XCertificate | the signature certificate |
SignaturePassword | string | the signature certificate password |
SignatureLocation | string | the signature location |
SignatureReason | string | the signature reason |
SignatureContactInfo | string | the signature contact information |
SignatureTSA | string | the signature time stamp authority URL |
Objector 43B
Um? Hmm . . .
Hypothesizer 7
The properties correspond to the settings in the PDF exporting dialog, as you will be able to easily see.
Objector 43B
I can see it, certainly, but I don't understand some settings in the dialog.
Hypothesizer 7
Ah.
Objector 43B
For example, what does "Fit in window" mean? I mean, "Fit width" seems to mean that the page width is fitted into the window; in "Fit in window", what is fitted into the window?
Hypothesizer 7
That expression is inarticulate because it is missing the issue: anyway, something is fitted into the window (in fact, where else can it be fitted?) and the issue is 'what' is fitted there, but "Fit in window" is not stating 'what' at all. . . . An understandable expression will be 'fit the whole page (into the window)'.
Objector 43B
And what, the hell, does "fit visible" mean? . . . Is "visible" fitted into the window? "visible" what? . . . That expression seems nonsensical because nothing is "visible" until the magnification has been determined, so, the magnification cannot be determined by fitting "visible" into the window because, you know, "visible" doesn't exist yet. . . . How am I supposed to understand such an expression?
Hypothesizer 7
Ah, in fact, that is not any fault of LibreOffice or Apache OpenOffice, but a fault of Adobe Acrobat Reader, from which the expression has come.
Objector 43B
Oh . . ., I see, but anyway, what does that mean?
Hypothesizer 7
In fact, "visible" seems to mean 'the contents'.
Objector 43B
Huh?
Hypothesizer 7
For example the characters on the page are the contents.
Objector 43B
. . . I think, I can see also the margins as white spaces.
Hypothesizer 7
In their terminology, they seem to be called 'invisible'.
Objector 43B
. . . So?
Hypothesizer 7
So, basically, "Fit visible" seems to mean 'the area that contains the contents is fitted into the window'.
Objector 43B
"basically"?
Hypothesizer 7
In fact, I do not understand the exact intention: as far as I try, it is not that the minimum square that contains the whole page contents is snugly fitted into the window.
Objector 43B
. . . Also "continuous facing" seems inarticulate, although I can guess what is supposed to mean.
Hypothesizer 7
That means that each 2 facing pages are shown abreast and those pairs are shown continuously connected vertically.
Objector 43A
How can I get the certificate object of the type, '::com::sun::star::security::XCertificate'?
Hypothesizer 7
Preliminarily, you have to have registered a Network Security Services database into LibreOffice or Apache OpenOffice.
Objector 43A
"Network Security Services"? . . . Anyway, how can I register the database into LibreOffice?
Hypothesizer 7
On the LibreOffice or Apache OpenOffice menu, you can click 'Tools' -> 'Options...'; on the appeared dialog, in the left pane, you can select 'LibreOffice' -> 'Security'; in the right pane, you can click 'Certificate...'; on the appeared dialog, you can click 'Add...'; on the appeared dialog, you can select the database directory and click 'OK'; you can click 'OK' two more times.
Objector 43A
Hmm . . ., and?
Hypothesizer 7
This is a piece of Java code that creates the certificate object of a certificate in the database, where 'a_certificateIssuerName' and 'a_certificateSerialNumber' are the certificate issuer name and the serial number, respectively, like 'CN=Tanichida,C=JP' and '{(byte) 0x00, (byte) 0xAA, (byte) 0xDD, (byte) 0xDF, (byte) 0xBF}', respectively, and 'getServiceInstance' is a function that gets a global UNO service instance.
@Java Source Code
~
import com.sun.star.security.XCertificate;
import com.sun.star.xml.crypto.XSEInitializer;
import com.sun.star.xml.crypto.XSecurityEnvironment;
import com.sun.star.xml.crypto.XXMLSecurityContext;
~
public class UnoObjectsContext implements XComponentContext {
~
private XSecurityEnvironment i_networkSecurityServicesSecurityEnvironmentInXSecurityEnvironment;
~
public Object getServiceInstance (String a_serviceName, Class a_targetClass, List <Object> a_arguments) throws com.sun.star.uno.Exception {
~
}
~
public XCertificate getNetworkSecurityServicesCertificateInXCertificate (String a_certificateIssuerName, byte [] a_certificateSerialNumber) throws Exception {
if (i_networkSecurityServicesSecurityEnvironmentInXSecurityEnvironment == null) {
XSEInitializer l_networkSecurityServicesSecurityEnvironmentInitializerInXSEInitializer = (XSEInitializer) getServiceInstance ("com.sun.star.xml.crypto.SEInitializer", XSEInitializer.class, null);
XXMLSecurityContext l_networkSecurityServicesSecurityContextInXXMLSecurityContext = l_networkSecurityServicesSecurityEnvironmentInitializerInXSEInitializer.createSecurityContext ("NetworkSecurityServices");
if (l_networkSecurityServicesSecurityContextInXXMLSecurityContext.getSecurityEnvironmentNumber () > 0) {
i_networkSecurityServicesSecurityEnvironmentInXSecurityEnvironment = l_networkSecurityServicesSecurityContextInXXMLSecurityContext.getSecurityEnvironmentByIndex (0);
}
}
if (i_networkSecurityServicesSecurityEnvironmentInXSecurityEnvironment != null) {
XCertificate [] l_networkSecurityServicesCertificatesArrayInXCertificate = i_networkSecurityServicesSecurityEnvironmentInXSecurityEnvironment.getPersonalCertificates ();
return selectCertificateFromCertificatesArray (l_networkSecurityServicesCertificatesArrayInXCertificate, a_certificateIssuerName, a_certificateSerialNumber);
}
return null;
}
~
private XCertificate selectCertificateFromCertificatesArray (XCertificate [] a_certificatesArrayInXCertificate, String a_certificateIssuerName, byte [] a_certificateSerialNumber) {
if (a_certificatesArrayInXCertificate != null) {
for (XCertificate l_certificateInXCertificate: a_certificatesArrayInXCertificate) {
if (a_certificateIssuerName.equals (l_certificateInXCertificate.getIssuerName ())) {
if (a_certificateSerialNumber == null) {
return l_certificateInXCertificate;
}
else {
byte [] l_certificateSerialNumber = l_certificateInXCertificate.getSerialNumber ();
if (a_certificateSerialNumber.length == l_certificateSerialNumber.length) {
int l_certificateSerialNumberByteIndex = 0;
for (byte l_certificateSerialNumberByte: l_certificateSerialNumber) {
if (a_certificateSerialNumber [l_certificateSerialNumberByteIndex] != l_certificateSerialNumberByte) {
break;
}
l_certificateSerialNumberByteIndex ++;
}
if (l_certificateSerialNumberByteIndex == l_certificateSerialNumber.length) {
return l_certificateInXCertificate;
}
}
}
}
}
}
return null;
}
}
Objector 43A
. . . How can I know "the serial number"?
Hypothesizer 7
You can see it from the LibreOffice or Apache OpenOffice PDF exporting dialog (select the 'Digital Signatures' tab; in the appeared dialog, click 'Select...'; select the certificate; click 'View Certificate...'; in the appeared dialog, select the 'Details' tab).
Objector 43A
Hmm.
Hypothesizer 7
Note that if the database has a password, the LibreOffice or Apache OpenOffice instance require the password once.
Objector 43A
"once"?
Hypothesizer 7
I mean, after the instance is up, when the above code is first called, the instance shows a dialog that requires the password.
Objector 43A
But the instance is in the headless mode!
Hypothesizer 7
Then, it will have to be in a non-headless mode.
Objector 43A
. . . That is inconvenient.
Hypothesizer 7
I know, but unfortunately, I do not know how to set the password programmatically.
Objector 43A
. . . Isn't that 'SignaturePassword' the one to be used?.
Hypothesizer 7
That is the password of the certificate, not of the database.
Objector 43A
Hmm . . .
Hypothesizer 7
An option would be to eliminate the password from the database, if that is permissible.
Objector 43A
Well . . .
Hypothesizer 7
I think that setting a password is not the only way to protect the database: for example, you can limit the access to the database files to only a single operating system user 'operating system file permissions'-wise.
3: The Conclusion and Beyond
Hypothesizer 7
Now, we know how to export any Office (word processor, spread sheets, or presentation) document into a PDF file as per detailed specifications from his or her program, using LibreOffice or Apache OpenOffice and UNO.
The basis of that technique is the way of converting any file directly using UNO (the concept, a Java implementation, a C++ implementation, a C# implementation, a Python implementation, and a LibreOffice or Apache OpenOffice Basic implementation). Once we have adopted the way, we can have many benefits efficiency-wise and functionality-wise.
What cannot be controlled by only specifying document-storing properties will be able to be controlled by tweaking the document in many ways that have been introduced or will be introduced in this series.
References
- Apache OpenOffice Wiki. (2014/01/02). Apache OpenOffice Developer's Guide. Retrieved from https://wiki.openoffice.org/wiki/Documentation/DevGuide/OpenOffice.org_Developers_Guide