libreoffice api
libreOffice API是用于访问libreOffice的编程接口。可以使用libreOffice API创建、打开、修改和打印libreOffice文档。
LibreOffice API支持Basic、Java、C/C++、Javascript、Python语言。
这是通过一种称为通用网络对象 (Universal Network Objects, UNO) 的技术实现的,该技术可以为各种编程语言提供接口。
https://api.libreoffice.org/docs/idl/ref/index.html
一、uno概念
(一)类型
uno类型使用一种称为UNOIDL(UNO接口定义语言)的语言定义,这种语言与CORBA IDL或MIDL类似。
1.简单类型
UNO类型 | 说明 |
---|---|
void | 空类型,仅在any中用作方法返回类型。 |
boolean | 可以是true或false。 |
byte | 有符号的8位整数类型(范围从 -128到127,包括上下限)。 |
short | 有符号的16位整数类型(范围从 -32768到32767,包括上下限)。 |
unsigned short | 无符号的16位整数类型(已不再使用)。 |
long | 有符号的32位整数类型(范围从 -2147483648到2147483647,包括上下限)。 |
unsigned long | 无符号的32位整数类型(已不再使用)。 |
hyper | 有符号的64位整数类型(范围从 -9223372036854775808到9223372036854775807,包括上下限)。 |
unsigned hyper | 无符号的64位整数类型(已不再使用)。 |
float | IEC 60559单精度浮点类型。 |
double | IEC 60559双精度浮点类型。 |
char | 表示单个的Unicode字符(更确切地说是单个的UTF-16代码单元)。 |
string | 表示Unicode字符串(更确切地说是Unicode标量值的字符串)。 |
type | 说明所有UNO类型的元类型。 |
any | 能够表示其他所有类型值的特殊类型。 |
2.struct 类型
结构体包括一堆数据成员,但不能包括方法。
结构体支持单继承。
struct EventObject{
com::sun::star::uno::XInterface Source;
};
struct PropertyChangeEvent : com::sun::star::lang::EventObject {
string PropertyName;
boolean Further;
long PropertyHandle;
any OldValue;
any NewValue;
};
3.sequence
序列就是一个动态数组。就像c++的vector
sequence< com::sun::star::uno::XInterface >
sequence< string > getNamesOfIndex( sequence< long > indexes );
4.interface类型
接口就是个抽象类。接口是一系列方法的声明,一个接口只有方法的声明没有方法的实现,因此这些方法可以在不同的类实现,而这些实现可以是不同的行为。
严格说来,UNO服务不支持方法,方法只在接口中,而服务继承了接口。
因为不同的服务会继承相同接口,所以如果您熟悉某个接口,便可以迅速了解不同服务。
按照约定,所有接口名称都以字母X开头,以将接口类型与其他类型区分开来。所有接口类型最终都必须继承com.sun.star.uno.XInterface根接口
interface XInterface {
any queryInterface( [in] type aType );
[oneway] void acquire();
[oneway] void release();
};
interface XInputStream: com::sun::star::uno::XInterface {
long readBytes( [out] sequence<byte> aData, [in] long nBytesToRead )
raises( com::sun::star::io::NotConnectedException, com::sun::star::io::BufferSizeExceededException, com::sun::star::io::IOException);
...
};
方法
就是接口的成员函数
Document.Save()
5.service
接口定义了方法;结构定义了数据;服务将它们组合在一起。
服务相当于类,不知道为啥非得叫服务。
通过服务,可以创建对象实例。
com.sun.star.frame.Desktop类似于一种对象类型,但在UNO术语中,将其称为“服务”而不是“类型”。按照UNO术语,Obj是支持com.sun.star.frame.Desktop服务的对象。因此,libreOffice Basic中使用的“服务”术语与其他编程语言中使用的“类型”和“类”术语相对应。
但存在一个主要区别:uno可以同时支持多种服务。例如,上面提到的obj对象不仅支持com.sun.star.frame.Desktop服务,还可以包括用于加载文档和结束程序的其他服务。
服务包括新式服务和旧式服务。
新式服务是通过仅支持一个多继承接口,该多继承接口再继承其他接口实现的
旧式服务是直接支持多个单继承接口实现的
新式服务
service SomeService: XSomeInterface;
interface XSomeInterface
{
interface XInterface1;
interface XInterface2;
interface XInterface3;
...
};
旧式服务
service SomeService{
interface XInterface1;
interface XInterface2;
interface XInterface3;
...
};
旧式服务可以包括其他旧式服务。如下例
service Paragraph
{
service com::sun::star::text::TextContent;
[optional] service com::sun::star::text::TextTable;
[optional] service com::sun::star::style::ParagraphProperties;
[optional] service com::sun::star::style::CharacterProperties;
[optional] service com::sun::star::style::CharacterPropertiesAsian;
[optional] service com::sun::star::style::CharacterPropertiesComplex;
...
};
如果上面示例中的所有旧式服务都使用多继承接口类型代替,则结构类似:
service Paragraph: XParagraph;
interface XParagraph
{
interface XTextContent;
[optional] interface XTextTable;
...
};
从用户的角度来看,无论对象提供一项服务或者多项服务,是新式还是旧式服务,由于方法仅由接口提供,因此,用户无需关心如何实现。
属性
属性是服务中的数据
(1)真实属性
就是服务的数据成员
Document.Title = "Basic Programmer's Guide"
Document.Filename = "basguide.odt"
(2)模拟属性
模拟属性就是通过get和set方法模拟的。
所以其实有两种方式访问属性:
通过Position属性直接访问。
通过getPosition和setPosition间接访问
旧式服务可直接列出支持的属性。
下面的旧式服务引用了一个接口和三个可选属性。属性可以是任何类型:
service TextContent{
interface com::sun::star::text::XTextContent;
[optional, property] com::sun::star::text::TextContentAnchorType AnchorType;
[optional, readonly, property] sequence<com::sun::star::text::TextContentAnchorType> AnchorTypes;
[optional, property] com::sun::star::text::WrapTextMode TextWrap;
};
6.预定义值
预定义值有两种不同的数据类型:常数和枚举。
const
const 定义有效UNO IDL类型的命名值。值取决于指定的类型,可以是常值(整数、浮点数或字符)、另一个const类型的标识符或包含以下运算符的算术项:+、-、*、/、~、&、|、%、^、 <<、>>。
由于可以在 const 中广泛选择类型和值,因此,const 有时用于生成对合并的值进行编码的位矢量。
const short ID = 23;
const boolean ERROR = true;
const double PI = 3.1415;
通常情况下,const定义是常数组的一部分。
constants
constants 类型定义的是包含多个 const 值的一个命名组。constants 组中的 const 用组名称加上 const 名称表示。在下面的UNO IDL示例中,ImageAlign.RIGHT 指的是值2:
constants ImageAlign {
const short LEFT = 0;
const short TOP = 1;
const short RIGHT = 2;
const short BOTTOM = 3;
};
enum
enum 类型与C++ 中的枚举类型相当。它包含一个已排序列表,列表中有一个或多个标识符,代表 enum 类型的各个值。默认情况下,值按顺序编号,以0开头,每增加一个新值就增加1。如果给某个 enum 值指定了一个值,则没有预定义值的所有后续 enum 值都以此指定值为基准来获得值。
// com.sun.star.uno.TypeClass
enum TypeClass {
VOID,
CHAR,
BOOLEAN,
BYTE,
SHORT,
...
};
enum Error {
SYSTEM = 10, // value 10
RUNTIME, // value 11
FATAL, // value 12
USER = 30, // value 30
SOFT // value 31
};
7.module
模块是命名空间,与C++ 中的命名空间或Java中的包类似
模块将服务、接口等类型组合在一起。形成良好的组织结构。
所以完整的类型名称由以下部分组成:com.sun.star是共同的模块名称,然后是特定模块名称,最后是实际的类型名称。
例如,服务Desktop的完整名称为:com.sun.star.frame.Desktop
接口XTextContent的完整名称为:com.sun.star.text.XTextContent
模块 com.sun.star.uno 包含接口 XInterface,IDL写法如下:
module com {module sun {module star {module uno {
interface XInterface {
...
};};};};};
(二)对象
广义的对象就是各种类型的实例。
狭义的对象只是服务的实例。
二、libreoffice basic语言绑定
语言绑定就是如何使用某种语言调用uno。
语言绑定有时称为UNO运行时环境 ( URE)。
uno支持c++、java、python、libreoffice basic语言绑定。
我们现在使用libreoffice basic语言,所以下面要讲解libreoffice basic绑定。
主要是下面这些
BasicLibraries | ccess Basic libraries stored in a document. |
CreateObject(obj_type) | Able to create any standard type, more flexible than CreateUnoStruct and CreateUnoService. |
CreateUnoDialog() | Create an existing dialog. |
CreateUnoListener() | Create a listener. |
CreateUnoService() | Create a Universal Network Object Service. |
CreateUnoStruct() | Create a Universal Network Object Structure. |
CreateUnoValue() | Create a Universal Network Object value. |
DialogLibraries | Access dialog libraries stored in a document. |
EqualUNOObjects() | Determine if two UNO objects reference the same instance. |
FindObject() | Find a named object; do not use. |
FindPropertyObject() | Find object property based on name; do not use. |
GetDefaultContext() | Get a copy of the default context. |
GetProcessServiceManager() | Get service manager. |
GlobalScope | Application-level libraries. |
HasUnoInterfaces() | Does an object support specified interfaces? |
IsUnoStruct() | Is this variable a Universal Network Object? |
StarDesktop | Special variable representing the desktop object. |
ThisComponent | Special variable representing the current document. |
(一)类型
Basic和UNO使用不同的类型系统,有必要映射这两种类型系统。
下面讲basic定义和使用各种类型变量
(1)简单类型
UNO | Basic |
---|---|
void | 内部类型 |
boolean | Boolean |
byte | Integer |
short | Integer |
unsigned short | 内部类型 |
long | Long |
unsigned long | 内部类型 |
hyper | 内部类型 |
unsigned hyper | 内部类型 |
float | Single |
double | Double |
char | 内部类型 |
string | String |
type | com.sun.star.reflection.XIdlClass |
any | Variant |
Basic类型系统并不严格。与C++ 和Java不同,Basic不要求声明变量,未声明的变量为Variant。
在未指定类型的情况下,声明的所有变量都为 Variant 类型。可以将任意Basic类型的值指定给类型为 Variant 的变量。
为了方便,尽量使用Variant类型,而且不必声明变量。
因为Basic会自动转换到uno类型。
当Basic不知道目标uno类型时,尤其是类型为any时。在这种情况下,Basic会机械地将Basic类型转换成上表中所示的UNO类型。Basic提供的唯一机制是自动向下转换数值:
Long和Integer值通常转换为尽可能短的整数类型:
- 如果 -128 <= Value <= 127, 转换为byte
- 如果 -32768 <= Value <= 32767, 转换为short
如果Single/Double值不带小数位,则以同样的方式转换为整数。
(2)结构
可以通过Dim As New创建结构实例
' Instantiate a Property struct
Dim aProperty As New com.sun.star.beans.Property
' Instantiate an array of Locale structs
Dim Locales(10) As New com.sun.star.lang.Locale
也可以使用CreateUnoStruct函数创建UNO结构实例
Dim aProp
aProp = CreateUnoStruct("com.sun.star.beans.PropertyValue")
aProp.Name = "FirstName" 'Set the Name property
aProp.Value = "Andrew" 'Set the Value property
函数CreateUnoStruct过去是创建UNO结构的唯一方法。自从引入“Dim As New”语法,它很少使用了。
CreateObject函数比CreateUnoStruct更通用。它能够创建所有类型的实例。这包括用户定义的类型。
Dim aProp
aProp = CreateObject("com.sun.star.beans.PropertyValue")
aProp.Name = "FirstName" 'Set the Name property
aProp.Value = "Paterton" 'Set the Value property
创建用户定义类型实例
Type PersonType
FirstName As String
LastName As String
End Type
Sub ExampleCreateNewType
Dim Person As PersonType
Person.FirstName = "Andrew"
Person.LastName = "Pitonyak"
PrintPerson(Person)
Dim Me As Object
Me = CreateObject("PersonType")
Me.FirstName = "Andy"
Me.LastName = "Pitonyak"
PrintPerson(Me)
End Sub
Sub PrintPerson(x)
Print "Person = " & x.FirstName & " " & x.LastName
End Sub
对于用户定义的类型,“Dim As New”和“Dim As”都可以使用。但是,对于UNO结构, 你必须使用Dim As New
CreateObject与CreateUnoStruct有相同的参数,但它适用于所有支持的类型, 而CreateUnoStruct仅适用于UNO结构。所以尽量使用CreateObject。
可以使用 . 运算符访问结构成员。
结构支持Dbg_Properties属性。不支持属性Dbg_SupportedInterfaces和Dbg_Methods:
' Instantiate a Locale struct
Dim aLocale As New com.sun.star.lang.Locale
' Display properties
MsgBox aLocale.Dbg_Properties
' Access“Language”property
aLocale.Language = "en"
服务实例与结构实例不同。服务实例使用引用传递,而结构实例使用值传递。
在以下示例中,oExample是一个服务实例,具有属性MyObject和MyStruct。
- MyObject是个服务,有一个属性ObjectName。
- MyStruct是个结构,有一个属性StructName。
oExample.MyObject.ObjectName和oExample.MyStruct.StructName都应该修改。
' Accessing the object
Dim oObject
oObject = oExample.MyObject
oObject.ObjectName = “Tim” ' Ok!
' or shorter
oExample.MyObject.ObjectName = “Tim” ' Ok!
' Accessing the struct
Dim aStruct
aStruct = oExample.MyStruct ' aStruct is a copy of oExample.MyStruct!
aStruct.StructName = “Tim” ' Affects only the property of the copy!
' If the code ended here, oExample.MyStruct wouldn't be modified!
oExample.MyStruct = aStruct ' Copy back the complete struct! Now it's ok!
' Here the other variant does NOT work at all, because
' only a temporary copy of the struct is modified!
oExample.MyStruct.StructName = “Tim” ' WRONG! oExample.MyStruct is not modified!
测试对象是否为一个结构
使用IsUnoStruct检查对象是否为UNO结构
Dim aProperty As New com.sun.star.beans.Property
bIsStruct = IsUnoStruct( aProperty )
MsgBox bIsStruct ' Displays True because aProperty is a struct
bIsStruct = IsUnoStruct( 42 )
MsgBox bIsStruct ' Displays False because 42 is NO struct
(3)序列和数组映射
Basic中,与序列相对应的是数组。数组是Basic语言的标准元素。
当UNO需要一个序列时,Basic程序员可以使用一个相应的数组。在以下示例中,oSequenceContainer是一个对象,其具有一个类型为sequence<short> 的属性TheSequence。要将一个长度为10、值为0, 1, 2, ...9的序列指定给该属性,可以使用以下代码:
Dim i%, a%( 9 ) ' Maximum index 9 -> 10 elements
for i% = 0 to 9 ' this loop initializes the array
a%(i%) = i%
next i%
oSequenceContainer.TheSequence = a%()
' If“TheSequence”is based on XPropertySet alternatively
oSequenceContainer.setPropertyValue( “TheSequence”, a%() )
Basic程序员在编程时,需要了解不同的索引语义。在以下示例中,程序员传送包含一个元素的序 列,但实际上传送了两个元素:
' Pass a sequence of length 1 to the TheSequence property:
Dim a%( 1 ) ' WRONG: The array has 2 elements, not only 1!
a%( 0 ) = 3 ' Only Element 0 is initialized,
' Element 1 remains 0 as initialized by Dim
' Now a sequence with two values (3,0) is passed what
' may result in an error or an unexpected behavior!
oSequenceContainer.setPropertyValue( “TheSequence”, a%() )
将Basic数组作为一个整体用于参数或用于属性访问时,在Basic代码中数组后面应始终跟有 '()',否则,某些情况下可能会发生错误。 |
使用一个称为Array()的Basic函数,通过一步就可以创建、初始化数组并将它指定给Variant变量,这非常有用,尤其是对于小型序列:
Dim a ' should be declared as Variant
a = Array( 1, 2, 3 )
' is the same as
Dim a(2)
a( 0 ) = 1
a( 1 ) = 2
a( 2 ) = 3
有时,有必要将空序列传送到UNO接口。在Basic中,可以通过在Dim命令中忽略索引来声明空序列:
Dim a%() ' empty array/sequence of type Integer
Dim b$() ' empty array/sequence of String
UNO返回的序列在Basic中也表示为数组,但不必事先声明这些数组。应该将用于接受序列的变量声明为Variant。要访问UNO返回的数组,需要LBound() 和UBound() 获得元素索引。
函数LBound() 返回下限索引,而UBound() 返回上限索引。以下代码示意了一个循环,该循环将遍历所返回序列的所有元素:
Dim aResultArray ' should be declared as Variant
aResultArray = oSequenceContainer.TheSequence
dim i%, iFrom%, iTo%
iFrom% = LBound( aResultArray() )
iTo% = UBound( aResultArray() )
for i% = iFrom% to iTo% ' this loop displays all array elements
msgbox aResultArray(i%)
next i%
UNO返回序列的索引通常从0开始。一般仅使用UBound(),这时上面的示例可以简化为:
Dim aResultArray ' should be declared as Variant
aResultArray = oSequenceContainer.TheSequence
Dim i%, iTo%
iTo% = UBound( aResultArray() )
For i% = 0 To iTo% ' this loop displays all array elements
MsgBox aResultArray(i%)
Next i%
序列/数组的元素数目非常容易计算:
u% = UBound( aResultArray() )
ElementCount% = u% + 1
对于空数组/序列,UBound返回 -1。这样,随后按如下所示计算元素数目时,UBound的语义就可以保持一致:
ElementCount% = u% + 1' = -1 + 1 = 0
UNO序列与Basic数组之间的映射前提二者都使用一个基于零的索引系统。为了避免出现问题,不要使用语法Dim a ( IndexMin to IndexMin ) 或Basic命令Option Base 1。这二者使所有Basic数组的索引都不是从0开始。 |
UNO还支持包含序列的序列。在Basic中,这对应于包含数组的数组。不要将包含序列的序列与多维数组相混淆。在多维数组中,所有子数组始终具有相同数目的元素,而在包含序列的序列中,每个序列可以具有不同的大小。示例:
Dim aArrayOfArrays ' should be declared as Variant
aArrayOfArrays = oExample.ShortSequences ' returns a sequence of sequences of short
Dim i%, NumberOfSequences%
Dim j%, NumberOfElements%
Dim aElementArray
NumberOfSequences% = UBound( aArrayOfArrays() ) + 1
For i% = 0 to NumberOfSequences% - 1' loop over all sequences
aElementArray = aArrayOfArrays( i% )
NumberOfElements% = UBound( aElementArray() ) + 1
For j% = 0 to NumberOfElements% - 1 ' loop over all elements
MsgBox aElementArray( j% )
Next j%
Next i%
要在Basic中创建一个包含数组的数组,可以将子数组作为主数组的元素::
' Declare master array
Dim aArrayOfArrays( 2 )
' Declare sub arrays
Dim aArray0( 3 )
Dim aArray1( 2 )
Dim aArray2( 0 )
' Initialise sub arrays
aArray0( 0 ) = 0
aArray0( 1 ) = 1
aArray0( 2 ) = 2
aArray0( 3 ) = 3
aArray1( 0 ) = 42
aArray1( 1 ) = 0
aArray1( 2 ) = -42
aArray2( 0 ) = 1
' Assign sub arrays to the master array
aArrayOfArrays( 0 ) = aArray0()
aArrayOfArrays( 1 ) = aArray1()
aArrayOfArrays( 2 ) = aArray2()
' Assign the master array to the array property
oExample.ShortSequences = aArrayOfArrays()
在这种情况下,运行时函数Array() 非常有用。这样,示例代码就可以变得更加简练:
' Declare master array
Dim aArrayOfArrays( 2 )
' Create and assign sub arrays
aArrayOfArrays( 0 ) = Array( 0, 1, 2, 3 )
aArrayOfArrays( 1 ) = Array( 42, 0, -42 )
aArrayOfArrays( 2 ) = Array( 1 )
' Assign the master array to the array property
oExample.ShortSequences = aArrayOfArrays()
如果嵌套使用Array(),就可以编写更简练的代码,但会使得人们难以理解将要生成的数组:
' Declare master array variable as variant
Dim aArrayOfArrays
' Create and assign master array and sub arrays
aArrayOfArrays = Array( Array( 0, 1, 2, 3 ), Array( 42, 0, -42 ), Array( 1 ) )
' Assign the master array to the array property
oExample.ShortSequences = aArrayOfArrays()
对于更高阶次的序列,也可以进行相应处理。
(4)常数和枚举映射
使用符合命名规则的名称对枚举类型的值进行寻址。以下示例假定oExample和oExample2支持 com.sun.star.beans.XPropertySet,并包含一个枚举类型为 com.sun.star.beans.PropertyState 的属性Status:
Dim EnumValue
EnumValue = com.sun.star.beans.PropertyState.DEFAULT_VALUE
MsgBox EnumValue ' displays 1
eExample.Status = com.sun.star.beans.PropertyState.DEFAULT_VALUE
Basic不支持枚举类型。在Basic中,来自UNO的枚举值被转换成Long值。只要Basic知道某个属性或某个接口方法参数是否需要一个枚举类型,就在内部将Long值转换为适当的枚举类型。当接口访问方法需要一个Any:
Dim EnumValue
EnumValue = oExample.Status ' EnumValue is of type Long
' Accessing the property implicitly
oExample2.Status = EnumValue ' Ok! EnumValue is converted to the right enum type
' Accessing the property explicitly using XPropertySet methods
oExample2.setPropertyValue( "Status", EnumValue ) ' WRONG! Will probably fail!
显式访问会失败,因为EnumValue是作为Any类型的参数传递到setPropertyValue(),因此,Basic不知道实际需要一个PropertyState类型的值。还有一个问题,在Basic中,com.sun.star.beans.PropertyState 的类型为Long。此问题在 com.sun.star.beans.XPropertySet 接口的实现中得以解决。对于枚举类型,使用Basic属性语法Object.Property来访问隐式属性优于使用类型Any来调用普通方法。如果仅存在需要Any类型的enum变量的普通接口方法,则没有适用于Basic的解决方案。
常数组用于在IDL中指定一组常数值。在Basic中,可以使用其全限定名称访问这些常数。以下代码显示了 com.sun.star.beans.PropertyConcept 中的一些常数:
MsgBox com.sun.star.beans.PropertyConcept.DANGEROUS ' Displays 1
MsgBox com.sun.star.beans.PropertyConcept.PROPERTYSET ' Displays 2
可以将常数组或枚举指定给对象。如果需要访问多个枚举或常数值,使用此方法可以缩短代码:
Dim oPropConcept
oPropConcept = com.sun.star.beans.PropertyConcept
msgbox oPropConcept.DANGEROUS ' Displays 1
msgbox oPropConcept.PROPERTYSET ' Displays 2
(5)接口
Basic将UNO接口映射成Basic对象方法
在Java和C++中,调用接口中的一个方法之前,需要获取接口。
在Basic中,可以直接调用该对象支持的任何接口的任何方法,而无需提前查询相应的接口。
使用的是 '.' 运算符:
' Basic
oExample = getExampleObjectFromSomewhere()
oExample.doNothing()' Calls method doNothing of XFoo1
oExample.doSomething()' Calls method doSomething of XFoo2
oExample.doSomethingElse(42)' Calls method doSomethingElse of XFoo2
此外,如果UNO对象的get和set方法符合以下模式,则Basic将它们映射为Basic对象属性:
SomeType getSomeProperty()
void setSomeProperty(SomeType aValue)
在此模式中,Basic提供了一个类型为SomeType、名称为SomeProperty的属性。
x = oExample.getIt() ' Calls getIt method of XFoo3
' is the same as
x = oExample.It ' Read property It represented by XFoo3
oExample.setIt( x ) ' Calls setIt method of XFoo3
' is the same as
oExample.It = x ' Modify property It represented by XFoo3
如果只有get方法,而没有set方法,则属性被视为只读。
x = oExample.getMore() ' Calls getMore method of XFoo1
y = oExample.getLess() ' Calls getLess method of XFoo1
' is the same as
x = oExample.More ' Read property More represented by XFoo1
y = oExample.Less ' Read property Less represented by XFoo1
' but
oExample.More = x ' Runtime error "Property is read only"
oExample.Less = y ' Runtime error "Property is read only"
可以直接访问com.sun.star.beans.XPropertySet提供的属性。
也可以使用com.sun.star.beans.XPropertySet中的方法访问属性。
x = oExample2.Value1
y = oExample2.Value2
z = oExample2.Value3
' is the same as
x = oExample2.getPropertyValue( "Value1" )
y = oExample2.getPropertyValue( "Value2" )
z = oExample2.getPropertyValue( "Value3" )
' and
oExample2.Value1 = x
oExample2.Value2 = y
oExample2.Value3 = z
' is the same as
oExample2.setPropertyValue( "Value1", x )
oExample2.setPropertyValue( "Value2", y )
oExample2.setPropertyValue( "Value3", z )
检查接口
尽管Basic不像C++ 和Java那样支持queryInterface概念,但有一个函数HasUnoInterfaces() 用于进行此项检测。
第一个参数HasUnoInterfaces() 需要的是应该接受测试的对象。接着可以将一个或多个全限定的接口名称参数传送到该函数。如果对象支持所有这些接口,则函数返回True,否则返回False。
oSimpleFileAccess = CreateUnoService( "com.sun.star.ucb.SimpleFileAccess" )
IfaceName1$ = "com.sun.star.uno.XInterface"
IfaceName2$ = "com.sun.star.ucb.XSimpleFileAccess2"
IfaceName3$ = "com.sun.star.container.XPropertySet"
bSuccess = HasUnoInterfaces( oSimpleFileAccess, IfaceName1$ )
MsgBox bSuccess ' Displays True because XInterface is supported
bSuccess = HasUnoInterfaces( oSimpleFileAccess, IfaceName1$, IfaceName2$ )
MsgBox bSuccess ' Displays True because XInterface
' and XSimpleFileAccess2 are supported
bSuccess = HasUnoInterfaces( oSimpleFileAccess, IfaceName3$ )
MsgBox bSuccess ' Displays False because XPropertySet is NOT supported
bSuccess = HasUnoInterfaces( oSimpleFileAccess, IfaceName1$, IfaceName2$, IfaceName3$ )
MsgBox bSuccess ' Displays False because XPropertySet is NOT supported
(6)服务
每个UNO对象都是服务的实例化。
uno对象映射为basic的variant类型,而不是object类型,因为object类型为纯粹basic对象。
有两种方法获得对象:
a.创建新对象
服务管理器com.sun.star.lang.ServiceManager,按服务名称实例化服务。
服务管理器的接口com.sun.star.lang.XMultiServiceFactory
它提供三个方法:createInstance()、createInstanceWithArguments() 和getAvailableServiceNames()。
使用GetProcessServiceManager()获取服务管理器
createInstance() 创建一个服务实例
oServiceMgr = GetProcessServiceManager()
oSimpleFileAccess = oServiceMgr.createInstance( "com.sun.star.ucb.SimpleFileAccess" )
createInstanceWithArguments() 使用参数创建一个服务实例。可能有些服务必须使用参数来实例化。
GetProcessServiceManager() 的优势是:使用服务管理器实例化服务时,可以接收附加信息和传入的参数。
Dim args(1)
args(0) = "Important information"
args(1) = "Even more important information"
oService = oServiceMgr.createInstanceWithArguments("com.sun.star.nowhere.ServiceThatNeedsInitialization", args() )
getAvailableServiceNames() 返回支持的所有服务名称。
sServices = GetProcessServiceManager().getAvailableServiceNames()
Print sServices
CreateUnoService函数是创建UNO服务实例的快捷方式,它本质上还是使用服务管理器创建实例。
oSimpleFileAccess = CreateUnoService( "com.sun.star.ucb.SimpleFileAccess" )
此调用实例化 com.sun.star.ucb.SimpleFileAccess 服务。为确保函数成功,可以使用IsNull函数检查返回的对象:
oSimpleFileAccess = CreateUnoService( "com.sun.star.ucb.SimpleFileAccess" )
bError = IsNull( oSimpleFileAccess )' bError is set to False
oNoService = CreateUnoService( "com.sun.star.nowhere.ThisServiceDoesNotExist" )
bError = IsNull( oNoService )' bError is set to True
CreateUnoServiceWithArguments实例化UNO服务,包括补充的可选参数。
dds = CreateUnoServiceWithArguments("com.sun.star.security.DocumentDigitalSignatures", Array("1.2", True))
插入到文档中的对象必须由该文档创建。例如,电子表格文档的绘图对象只能在这种文档中使用。
电子表格创建绘图对象:
RectangleShape = Spreadsheet.createInstance("com.sun.star.drawing.RectangleShape")
文本文档创建段落样式:
Style = Textdocument.createInstance("com.sun.star.style.ParagraphStyle")
b.获得现有对象
上下文是一个名称-值对的集合,您可以使用它来通过名称获取这些对象。默认上下文可通过函数GetDefaultContext获得。
MsgBox Join(GetDefaultContext().getElementNames(), CHR$(10))
libreoffice basic提供了一些全局对象,可以快捷使用
StarDesktop
StarDesktop对象代表LibreOffice应用程序。
Dim doc As Object, docProperties()
docURL = ConvertToURL("C:\My Documents\example.odt")
Rem com.sun.star.frame.Desktop
doc = StarDesktop.LoadComponentFromURL(docURL, "_blank", 0, docProperties)
GlobalScope
To manage personal or shared library containers (Application Macros or My Macros) from within a document, use the GlobalScope specifier.
要从文档中管理个人或共享库容器(应用程序宏或我的宏),请使用GlobalScope
' 调用文档库 Standard 中的 Dialog1
oDlgDesc = DialogLibraries.Standard.Dialog1
' 调用应用程序库 Library1 中的 Dialog2
oDlgDesc = GlobalScope.DialogLibraries.Library1.Dialog2
可以从活动文档中使用以下对象。
BasicLibraries对象
DialogLibraries对象
ThisComponent对象
ThisComponent表示宏中的当前文档。它寻找活动组件,其属性可以读取和设置,并且可以调用其方法。ThisComponent提供的属性和方法取决于文档类型。
ThisDatabaseDocument对象
ThisDatabaseDocument寻找活动的文档,该文档的属性可以读取和设置,并且可以调用其方法。
ThisDatabaseDocument返回一个类型为 com.sun.star.sdb.XOfficeDatabaseDocument 的对象。
使用名字访问下级对象
XNameAccess和XNameContainer接口用于包含下级对象的对象,可以使用名字访问下级对象
XNameAccess访问各个元素;而XNameContainer用于插入、修改和删除元素。
com.sun.star.container.XNameAccess 接口
1)getByName 方法
Sheets = Spreadsheet.Sheets
Sheet = Sheets.getByName("Sheet1")
2)getElementNames 方法
返回所有元素的名称。
Sheets = Spreadsheet.Sheets
SheetNames = Sheets.getElementNames
For I=LBound(SheetNames) To UBound(SheetNames)
MsgBox SheetNames(I)
Next I
3)hasByName 方法
是否存在特定名称的下级对象。
Sheets = Spreadsheet.Sheets
If Sheets.HasByName("Sheet1") Then
MsgBox " Sheet1 available"
Else
MsgBox "Sheet1 not available"
End If
com.sun.star.container.XNameContainer 接口
XNameContainer 接口用于插入、删除和修改对象中的下级对象。负责完成这些操作的函数为insertByName、removeByName、replaceByName。
该示例调用一个文本文档,该文档包含一个 StyleFamilies 对象,该对象包含段落样式 (ParagraphStyles)。
StyleFamilies = Textdoc.StyleFamilies
ParagraphStyles = StyleFamilies.getByName("ParagraphStyles")
ParagraphStyles.insertByName("NewStyle", NewStyle)
ParagraphStyles.replaceByName("ChangingStyle", NewStyle)
ParagraphStyles.removeByName("OldStyle")
insertByName 行在 ParagraphStyles 对象中的插入NewStyle样式。
replaceByName 行将 ChangingStyle对象更改为NewStyle。
removeByName 调用将 OldStyle对象从ParagraphStyles中删除。
使用索引访问下级对象
XIndexAccess和XIndexContainer接口用于包含下级对象并可使用索引访问下级对象的对象。
XIndexAccess提供了用于访问单个对象的方法。XIndexContainer 提供了用于插入和删除对象的方法。
com.sun.star.container.XIndexAccess 接口
XIndexAccess 提供了 getByIndex 和 getCount 方法。getByIndex 通过索引获得对象。getCount 返回对象的数目。
Sheets = Spreadsheet.Sheets
For I = 0 to Sheets.getCount() - 1
Sheet = Sheets.getByIndex(I)
' Editing sheet
Next I
该示例说明了一个循环,此循环遍历获得所有工作表。在使用索引时,请注意 getCount 返回元素的数目。不过,getByIndex 中的元素是从0开始编号的。因此,循环的计数变量是从0到 getCount()-1。
com.sun.star.container.XIndexContainer 接口
XIndexContainer 接口提供了 insertByIndex 和 removeByIndex 函数。这些参数的结构与 XNameContainer 中相应函数的结构相同。
对下级对象的遍历访问
在某些情况下,对象包含一个下级对象列表,但无法通过名称或索引访问这些下级对象。此时,应使用 XEnumeration 和 XenumerationAccess 接口。它们提供了一种机制来遍历某个对象的所有下级元素,而无需进行寻址。
com.sun.star.container.XEnumeration 和com.sun.star.container.XenumerationAccess 接口
对象必须提供 XEnumerationAccess 接口,该接口仅包含 createEnumeration 方法。此方法返回一个辅助对象,而该对象又提供了包含 hasMoreElements 和 nextElement 方法的 XEnumeration 接口。可通过这些方法来访问下级对象。
以下示例将遍历文本的所有段落:
ParagraphEnumeration = Textdoc.Text.createEnumeration
While ParagraphEnumeration.hasMoreElements()
Paragraph = ParagraphEnumeration.nextElement()
Wend
该示例首先创建了一个 ParagraphEnumeration 辅助对象。然后,借助此对象通过循环逐步返回文本的各个段落。在 hasMoreElements 方法返回 False 值(表示已到达文本末尾)时,将会立即终止循环。
检查对象
可以获取UNO对象的信息。
要查明两个对象是否引用同一个UNO对象,可以使用函数EqualUnoObjects()。在Basic中,不能对对象类型的参数应用比较运算符 =,例如If Obj1 = Obj2 Then会导致运行时错误。
oSimpleFileAccess = CreateUnoService( "com.sun.star.ucb.SimpleFileAccess" )
oSimpleFileAccess2 = oSimpleFileAccess
bIdentical = EqualUnoObjects( oSimpleFileAccess, oSimpleFileAccess2 )
MsgBox bIdentical ' Displays True
oSimpleFileAccess3 = CreateUnoService( "com.sun.star.ucb.SimpleFileAccess" )
bIdentical = EqualUnoObjects( oSimpleFileAccess, oSimpleFileAccess3 )
MsgBox bIdentical ' Displays False
Dbg_Properties和Dbg_Methods中使用的表示法是uno类型名称。可以忽略Sbx前缀。其他名称与一般Basic类型表示法对应。SbxEMPTY与Variant的类型相同。
DBG_properties
返回一个字符串,包括对象的所有属性
DBG_methods
返回一个字符串,包括对象的所有方法
DBG_supportedInterfaces
返回一个字符串,包括对象的所有接口
示例
Obj = createUnoService("com.sun.star.frame.Desktop")
MsgBox Obj.DBG_Properties
MsgBox Obj.DBG_methods
MsgBox Obj.DBG_supportedInterfaces
请注意,在使用DBG_properties时,返回理论上可以支持的所有属性。但不保证对象可以使用这些属性。因此,在使用属性之前,必须使用IsEmpty函数检查该属性是否确实可用。
supportsService方法
可以使用supportsService方法来确定对象是否支持特定服务。
例如,TextElement对象是否支持com.sun.star.text.Paragraph服务。
Ok = TextElement.supportsService("com.sun.star.text.Paragraph")
getsupportedservicenames方法
获取所有支持的服务
msgbox join(TextElement.getsupportedservicenames, chr(10))
工具 - 开发工具,能查看对象的服务,接口,方法,属性。
全局方法
CreateUnoDialog函数
创建一个基本Uno对象,该对象表示宏运行时的对话框。
CreateUnoListener函数
创建监听器实例。
CreateUnoValue函数
返回一个对象,该对象表示一个涉及Uno类型系统的精确类型值。
相关文章:
libreoffice api
libreOffice API是用于访问libreOffice的编程接口。可以使用libreOffice API创建、打开、修改和打印libreOffice文档。 LibreOffice API支持Basic、Java、C/C、Javascript、Python语言。 这是通过一种称为通用网络对象 (Universal Network Objects, UNO) 的技术实现的ÿ…...
全网最火,Web自动化测试驱动模型详全,一语点通超实用...
目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 自动化测试模型&a…...
如何写软件测试简历项目经验,靠这个面试都要赶场
一、前言:浅谈面试 面试是我们进入一个公司的门槛,通过了面试才能进入公司,你的面试结果和你的薪资是息息相关的。那如何才能顺利的通过面试,得到公司的认可呢?面试软件测试要注意哪些问题呢?下面和笔者一起来看看吧。这里分享一…...
【Linux】Linux下安装Mysql(图文解说详细版)
文章目录 前言第一步,进到opt文件夹下面,为什么?因为opt文件夹相当于Windows下的D://software第二步,用yum安装第三步,设置mysql的相关配置第四步,设置远程连接。第五步,更改mysql的语言第六步&…...
Cookie和Session的API、登录页面
目录 一、Cookie 和 Session 1、HttpServletRequest 类中的相关方法 2、HttpServletResponse 类中的相关方法 3、HttpSession 类中的相关方法 4、Cookie 类中的相关方法 二、网页登录 1、约定前后端交互接口 2、编写一个简单的登录页面 3、编写一个Servlet 来处理这个…...
C++数据结构:手撕红黑树
目录 一. 红黑树的概念及结构 二. 红黑树节点的定义 三. 红黑树节点的插入 3.1 初步查找插入节点的位置并插入节点 3.2 红黑树结构的调整 3.3 红黑树节点插入完整版代码 四. 红黑树的结构检查 4.1 检查是否为搜索树 4.2 检查节点颜色是否满足要求 附录:红黑…...
Spring IoC 深度学习
Io回顾 IoC 是 Inversion of Control 的简写,译为“控制反转”,它不是一门技术,而是一种设计思想,是一个重要的面向对象编程法则,能够指导我们如何设计出松耦合、更优良的程序。 Spring 通过 IoC 容器来管理所有 Jav…...
C语言从入门到精通第17天(指针和数组联用)
指针和数组联用 不同类型指针变量之间的区别数组的指针指针数组 不同类型指针变量之间的区别 在了解数组和指针联用之前,我们先对指针变量进行补充。我们对比一下int *p1和char *p2的区别? 相同点: 都是指针变量都是用来保存一个内存地址编…...
Android9.0 原生系统SystemUI下拉状态栏和通知栏视图之锁屏通知布局
1.前言 在9.0的系统rom定制化开发中,对于系统原生systemui的锁屏界面的功能也是非常重要的,所以在锁屏页面布局中,也是有通知栏布局的,所以接下来对于息屏亮屏 通知栏布局的相关流程分析,看下亮屏后锁屏页面做了哪些功能 2.原生系统SystemUI下拉状态栏和通知栏视图之锁…...
音视频八股文(10)-- mp4结构
介绍 mp4⽂件格式⼜被称为MPEG-4 Part 14,出⾃MPEG-4标准第14部分 。它是⼀种多媒体格式容器,⼴泛⽤于包装视频和⾳频数据流、海报、字幕和元数据等。(顺便⼀提,⽬前流⾏的视频编码格式AVC/H264 定义在MPEG-4 Part 10)…...
python算法中的深度学习算法之深度信念网络(详解)
目录 学习目标: 学习内容: 深度信念网络 Ⅰ. 预训练 Ⅱ. 微调 学习目标: 一分钟掌握 python算法中的深度学习算法之深度信念网络 入门知识...
SPSS如何绘制常用统计图之案例实训?
文章目录 0.引言1.绘制简单条形图2.绘制分类条形图3.绘制分段条形图4.绘制简单线图5.绘制多重线图6.绘制垂直线图7.绘制简单面积图8.绘制堆积面积图9.绘制饼图10.绘制直方图11.绘制简单散点图12.绘制重叠散点图13.绘制矩阵散点图14.绘制三维散点图15.绘制简单箱图16.绘制分类箱…...
打动人心的故事 | 如何利用文案在Facebook上塑造品牌形象
在当今的数字营销时代,文案已经成为各大平台上不可或缺的元素之一。在Facebook上,一个好的文案能够为品牌带来巨大的曝光率和用户黏性,甚至可以改变用户对品牌的看法。那么,如何利用文案在Facebook上打动人心,塑造品牌…...
什么是模糊控制?
模糊控制设计原理 1、传统控制系统和模糊控制系统 传统控制系统结构: 控制目的:通过控制器调节控制信号u,使输出信号y达到要求 模糊控制系统结构: 与传统控制系统的差异:用模糊控制器FC(Fuzzy Controller&…...
仿抖音开发需要注意的问题
一、版权问题 仿抖音开发需要注意版权问题,包括内容的版权和软件的版权。在开发的过程中,不要直接抄袭他人的作品,应该注重保护知识产权。 二、安全性问题 仿抖音开发需要重视应用的安全性问题,避免应用在使用过程中发生安全漏…...
如何根据期刊缩写查找期刊?
英文论文写作中,经常会插入参考文献。参考文献中的期刊名称,时常需要使用缩写。或者是手头有期刊缩写后的名称,但是有时候,查了半天也查不到期刊期刊全称,费时费力让人崩溃。今天就给各位学者老师总结一些查询期刊缩写…...
数据发送流程
在发送模式下,UART 的串行数据发送电路主要包括一个发送移位寄存器(TSR),TSR 功能是将数据 逐个移位送出。待发数据必须先写到发送缓冲区中。 TXIFx 是发送中断标志位,可配置为发送缓冲区空或TSR 空。 数据的发送支持7bit 、8bit 或9bit 数据…...
堆及其应用
堆是一种基于树结构的数据结构,通常用于实现优先队列。堆分为最大堆和最小堆两种类型,最大堆的每个节点的值都大于等于其子节点的值,最小堆则相反,每个节点的值都小于等于其子节点的值。 基础算法操作包括: 1. 插入元…...
MySQL数据库备份脚本
PS:此脚本简单易懂,根据实际情况修改个别参数测试后即可使用,如有错误请指出! 1.MySQL数据库备份脚本 #!/bin/bashuser pw ip dateYdate "%Y" date2date "%Y%m%d" date3date "%Y%m%d %H:%M" date…...
【2023 · CANN训练营第一季】应用开发深入讲解——第三章应用调试
学习资源 日志参考文档 应用开发FAQ 日志主要用于记录系统的运行过程及异常信息,帮助快速定位系统运行过程中出现的问题以及开发过程中的程序调试问题。 日志分为如下两大类: 系统类日志:系统运行产生的日志。主要包括: Contro…...
黎曼几何与黎曼流形
目录 0.黎曼几何 1. 欧几里得几何与黎曼几何的区别 2.黎曼流形 3.黎曼距离 4.切空间 5.黎曼均值 6. SPD矩阵如何形成黎曼流型 7.切线空间映射 8.同余变换和同余不变 9.黎曼对齐 科普性笔记,做了解,不深入。 0.黎曼几何 黎曼几何是一种基于欧几…...
lua | 运算符与字符串
目录 一、运算符 算数运算符 关系运算符 逻辑运算符 其他运算符 运算符优先级 二、字符串 转义字符 方法与用途 字符串截取 字符串大小转换 字符串查找与反转 字符串格式化 字符与整数的转换 匹配模式 本文章为笔者学习分享 学习网站:Lua 基本语法 | …...
NetBackup 10.2 新功能介绍:PostgreSQL 和 MySQL 自动化恢复达成
NetBackup 10.2 新功能介绍:PostgreSQL 和 MySQL 自动化恢复达成 原文来自:VERITAS 中文社区 2023-04-27 在执行恢复任务时,手动提取、更新数据库和实例并将其附加到 PostgreSQL 和 MySQL 是常规操作。而在最新的 NetBackup 10.2 版本中&am…...
ADRV9002官方例程开发过程中遇到的问题
开发环境:Vivado2021.2 HDL版本:hdl_2021_r2 GitHub - analogdevicesinc/hdl at hdl_2021_r2 no-OS版本:no_OS-2021_R2 GitHub - analogdevicesinc/no-OS at 2021_R2 (PS:也可以用Vivado2019.1开发,…...
Figma转换为sketch,分享这3款工具
在我们的设计工作中,我们经常会遇到各种各样的设计文件相互转换的问题。 你经常为此头疼吗?当你遇到Figma转换Sketch文件的问题时,你是如何解决的?Figma转换Sketch文件有工具吗? 根据众多设计师的经验,本…...
淘宝天猫1688京东商品详情API接口,封装接口可高并发
要提供商品详情数据需要知道具体的商品信息,但通常商品详情数据应包括以下内容: 商品名称:商品的名称,以方便顾客对其进行识别和区分。 商品描述:一段让顾客能够全面认识商品的描述。应能够有效地展示商品的特性、功能…...
虹科荣誉 | 虹科工业物联网产品荣获中国自动化产业年会用户信赖产品奖!
2023 虹科荣获2021年度中国自动化产业年会用户信赖产品奖 近日,2023中国自动化产业年会于北京隆重举行。虹科工业物联网的产品“OPC UA Tunneller软件”凭借其产品优势和市场美誉度,通过层层选拔,在本次大会中荣获2021年度用户信赖产品奖。…...
SwiftUI 如何让文本自动支持查找和替换功能?
概览 有些情况下,我们需要为文本编辑器实现文本的查找和替换功能(find & replace),如果完全靠自已撸码还是比较棘手的。 所幸的是,从 SwiftUI 4.0 (iOS 16)开始,Apple 已经将查…...
SpringCloud全面学习笔记之初尝美妙篇
目录 前言初识微服务单体架构分布式架构微服务架构初见SpringCloud微服务治理分布式服务架构案例 微服务组件及使用Eureka注册中心提供者和消费者Eureka的结构和作用搭建Eureka服务注册服务服务发现Eureka注册服务总结 Ribbon负载均衡原理负载均衡原理负载均衡策略懒加载 Nacos…...
Spring MVC框架
Spring MVC框架 Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。使用 Spring 可插入的 MVC 架构,从而在使用Spring进行WEB开发时,可以选择使用Spring的Spri…...
成都公安网站备案/百度推广渠道户
文章目录前言一、安装axios二、调用后台接口三、主页面四、模拟后台接口第一种方法第二种方法第三种方法五、出现的问题总结前言 学习并练习前端调用后台返回的接口数据,通过postman模拟返回后台接口 一、安装axios 先安装: npm install axios然后&am…...
网站空间要备案吗/真实的优化排名
安装NSI服务器************************************************************************************************* 1. 安装NIS服务器软件包NIS服务器软件包的名称是ypserv,系统默认是没有安装的,位于第1张光盘中。mount /media/cdrom rpm -q port…...
如何做网络营销推广南宁/seo免费优化公司推荐
1、家里可以没有电视机,但一定要有电脑。再大的电视也只是摆设,电脑才是生活之必需。 2、坚决信奉“有问题,百度一下”,无论什么问题,都习惯上网搜索一下,包括不会写的字。 3、电脑里一定有聊天工具。不联…...
共享门店新增实时收款/seo关键词排名优化评价
一、ps命令介绍ps命令是Process Status的缩写,用于查看系统进程状态,ps命令输出值非常多,通常结合管道符使用。二、实例1.我们直接输入ps命令,不加任何参数。可以看到默认输出4列信息PID: 运行着的命令(CMD)的进程编号TTY: 命令所…...
重庆高端网站建设价格/苏州百度推广服务中心
ML Compute 使用CPU和GPU加速神经网络的训练和验证。 教程 使用ML Compute框架来加速跨CPU或一个或多个可用GPU的神经网络训练。 ML Compute利用Accelerate框架为CPU提供的高性能BNNS基元,为GPU提供了Metal Performance Shaders 推荐 基础文章推荐 《SwiftUI是什么&…...
沈阳微营销网站制作/网页设计案例
继上次知识小总结之后很多同学表示学到了很多收藏夹 | Java基础必知必会(一)戳上次题目本次继续给大家带来常用知识点第二弹一起学起来~11. char 型变量中能不能存贮一个中文汉字,为什么?char 类型可以存储一个中文汉字,因为 Java 中使用的编…...