当前位置: 首页 > news >正文

libreoffice表格python宏教程 一

一、安装python宏扩展

LibreOffice自带了一个宏编辑器,但是只能用basic语言,无法用Python。
所以,我们必须在单独的编辑器中编写Python代码。

需要安装apso扩展,此扩展可以创建删除管理python宏文件,同时还能设置偏好编辑器
下面是扩展下载地址
https://extensions.libreoffice.org/en/extensions/show/apso-alternative-script-organizer-for-python

二、创建宏

1、python宏位置

有三个位置,每个位置都叫做容器:
(1)我的宏

  • 「Windows」:%APPDATA%\LibreOffice\4\user\Scripts\python。
  • 「Linux」与「macOS」:$HOME/.config/libreoffice/4/user/Scripts/python。

(2)应用程序宏

  • 「Windows」: {Installation}\share\Scripts\python。
  • 「Linux」 与「macOS」: {Installation}/share/Scripts/python。

(3)嵌在文档中的宏
文档宏嵌入在文档中,仅在文档处于打开状态时可访问。

Python宏有三级组织:库、模块、宏
库是文件夹。要创建一个库,先在目标容器中新建文件夹。库的名称就是文件夹的名称。
模块是单个python文件。创建模块就是新建文件。
宏是模块中的单个函数。

2、创建宏

选择菜单“工具-宏-organize python scripts”调出对话框
选择任何一个容器
点击“menu-create module”,输入文件名,创建python文件

三、编写宏

右击上面创建的python文件,点击edit
之后就会使用默认编辑器打开python文件。
我用的是vscode,所以会自动使用vscode打开python文件。
宏就是函数,所以必须先定义函数,这样在运行python宏时,才能找到它并运行。

参考教程
https://help.libreoffice.org/latest/zh-CN/text/sbasic/python/main0000.html?&DbPAR=BASIC&System=UNIX
https://wiki.documentfoundation.org/Documentation/DevGuide
https://wiki.documentfoundation.org/Documentation/DevGuide/Professional_UNO

四、运行宏

编写完函数之后,就可以运行了
选择「工具 - 宏 - 运行宏 」调出对话框,选择相应的Python宏并运行

五、常用api

libreoffice提供给python的api,主要是uno.py。
但为了方便,还提供了一个全局对象XSCRIPTCONTEXT,可从XSCRIPTCONTEXT单对象推断出所有UNO对象。
当然也可以不使用全局对象,而是直接使用uno.py里面的函数,不过不如使用XSCRIPTCONTEXT方便。

先说一个约定,api中所有函数首字母小写,所有数据成员首字母大写。

(一)基本

获取libreoffice应用程序
odesktop = XSCRIPTCONTEXT.getDesktop()
获取上下文
ctx = XSCRIPTCONTEXT.getComponentContext()
或者
import uno
ctx = uno.getComponentContext()
创建服务的实例
smgr = ctx.getServiceManager()
obj = smgr.createInstanceWithContext( 'com.sun.star.frame.Desktop', ctx)
创建结构体对象
from com.sun.star.beans import PropertyValue
p=PropertyValue()
p.Name='FilterName'
p.Value='calc_pdf_Export'
或者
struct = uno.createUnoStruct('com.sun.star.beans.PropertyValue')
struct.Name = 'ToPoint'
struct.Value = 'Sheet1.A1'

文件的路径
由于libreOffice是一种与平台无关的应用程序,因此,它使用Internet Standard RFC 1738中的URL表示法。
此表示法以前缀file:///开头,后跟本地路径。如果文件名包含子目录,则使用/分隔这些子目录。
以下路径表示C:的doc目录中的test.odt文件。
file:///C:/doc/test.odt
文件名中ascii字符只允许使用 0-9a-zA-Z 字符。其他ascii字符必须使用转义编码。转义编码是ascii码的十六进制值,并在前面加上百分号。例如,本地文件名中的空格为%20。

返回文件的系统路径。
uno.fileUrlToSystemPath()
例子
uno.fileUrlToSystemPath("file:///C:/doc/test.ods") #(under Windows) c:\doc\test.ods

返回指定系统路径的文件URL。
uno.systemPathToFileUrl()
例子
uno.systemPathToFileUrl("C:\doc\test.ods") #file:///C:/doc/test.ods

从指定url返回文件的绝对url。
uno.absolutize()

(二)文档

1、获取文档

获取当前文档
odoc = XSCRIPTCONTEXT.getDocument()
当前文档路径
odoc.URL

例子

import os, uno
odoc = XSCRIPTCONTEXT.getDocument()
if os.name == "nt":directory = os.path.dirname(uno.fileUrlToSystemPath(odoc.URL))
else:directory = os.path.dirname(odoc.URL)[7:]

2、打开文档

Desktop的loadComponentFromURL方法,负责创建、打开文档。
loadComponentFromURL( [in] string URL, [in] string TargetFrameName, [in] long SearchFlags, [in] sequence<com::sun::star::beans::PropertyValue> Arguments )
第一个参数是文件的URL。
第二个参数是框架的名称。一般就是 “_blank”
第三个是如何查找指定框架名称的标志。一般就是0
第四个指定了参数列表。是com::sun::star::beans::PropertyValue结构体的元组。一般就是()

例子

odesktop = XSCRIPTCONTEXT.getDesktop()
Url = "file:///C:/test.ods"
odoc = odesktop.loadComponentFromURL(Url, "_blank", 0, ())

3、创建文档

创建文档也是使用loadComponentFromURL方法,只不过第一个参数改成"private:factory/scalc"
例子

odesktop = XSCRIPTCONTEXT.getDesktop()
odoc = odesktop.loadComponentFromURL("private:factory/scalc", "_blank", 0, ())

4、保存文档

(1)使用store
odoc = XSCRIPTCONTEXT.getDocument()
odoc.store()
(2)新文档需要使用 storeAsURL 方法。

这个方法就是另存为。
storeAsURL ([in] string sURL, [in] sequence< com::sun::star::beans::PropertyValue > lArguments)
第一个参数是文件url
第二个参数是参数列表。一般就是()。是com::sun::star::beans::PropertyValue结构体的元组。PropertyValue结构体有以下属性
https://api.libreoffice.org/docs/idl/ref/servicecom_1_1sun_1_1star_1_1document_1_1MediaDescriptor.html

例子

odesktop = XSCRIPTCONTEXT.getDesktop()
odoc = odesktop.loadComponentFromURL("private:factory/scalc", "_blank", 0, ())
Url = "file:///C:/test3.ods"
odoc.storeAsURL(Url, ())

文档还提供了一些方法,这些方法在保存文档时非常有用。这些方法是:
hasLocation() 是否已经为文档指定了URL。
isReadonly() 文档是否具有只读保护。
isModified() 在上次保存后是否修改了文档。

例子

if odoc.isModified():if odoc.hasLocation() and (not odoc.isReadOnly()):odoc.store()elseodoc.storeAsURL(Url, ())

本示例首先检查在上次保存后是否修改了相关文档。只有修改过,它才会继续执行保存过程。如果已经为文档指定了URL并且文档不是只读文档,则在现有URL下保存该文档。如果文档没有URL或以只读状态打开文档,则在新URL下保存文档。

使用第二个参数的例子

from com.sun.star.beans import PropertyValue
odoc = XSCRIPTCONTEXT.getDocument()
properties=[]
p=PropertyValue()
p.Name='Overwrite'
p.Value=True
properties.append(p)
Url = "file:///c:/test3.ods"
odoc.storeAsURL(Url, tuple(properties))

如果已存在同名文件,就覆盖保存。

(3)使用storeToURL

这个方法就是导出。
storeToURL ([in] string sURL, [in] sequence< com::sun::star::beans::PropertyValue > lArguments)

例子
导出为pdf

from com.sun.star.beans import PropertyValue
odoc = XSCRIPTCONTEXT.getDocument()
properties=[]
p=PropertyValue()
p.Name='FilterName'
p.Value='calc_pdf_Export'
properties.append(p)
odoc.storeToURL('file:///tmp/test.pdf',tuple(properties))

给文档设置密码:

from com.sun.star.beans import PropertyValue
odoc = XSCRIPTCONTEXT.getDocument()
properties=[]
p=PropertyValue()
p.Name='Password'
p.Value='123456'
properties.append(p)
odoc.storeToURL('file:///tmp/test.ods',tuple(properties))

5、关闭文档

odoc.dispose()

(三)工作表

每个文档可能包含几张表格,简称工作表。
文档的Sheets表示所有工作表。

1、获取工作表

(1)通过编号获取(编号从0开始)
odoc = XSCRIPTCONTEXT.getDocument()
Sheet =odoc.Sheets.getByIndex(0)
或者
Sheet =odoc.Sheets[0]
(2)通过名称获取
odoc = XSCRIPTCONTEXT.getDocument()
Sheet =odoc.Sheets.getByName("Sheet 1")

2、设置工作表为当前工作表

odoc = XSCRIPTCONTEXT.getDocument()
osheet =odoc.Sheets.getByName("Sheet 1")
odoc.getCurrentController.setActiveSheet(osheet)

3、创建工作表

使用odoc.createInstance("com.sun.star.sheet.Spreadsheet")创建工作表
使用sheets.insertByName方法将其插入工作表列表中

例子

odoc = XSCRIPTCONTEXT.getDocument()
Sheet =odoc.Sheets.getByIndex(0)
if odoc.Sheets.hasByName('MySheet'):Sheet = odoc.Sheets.getByName('MySheet')
else:Sheet = odoc.createInstance("com.sun.star.sheet.Spreadsheet")odoc.Sheets.insertByName("MySheet", Sheet)

除了上面的方法还有一个方法
sheets.insertNewByName ([in] string aName, [in] short nPosition)

4、删除工作表

使用sheets.removeByName([in] string aName)

5、移动工作表

使用sheets.moveByName ([in] string aName, [in] short nDestination)

6、复制工作表

使用sheets.copyByName ([in] string aName, [in] string aCopy, [in] short nDestination)

7、设置密码

sheet.protect(password)
sheet.unprotect(password)
sheet.isProtected()

(四)行列

1、获取工作表的行和列

通过工作表的Rows和Columns获得。
以下示例获取工作表的第一行和第一列,编号从0开始。

odoc = XSCRIPTCONTEXT.getDocument()
Sheet =odoc.Sheets.getByName("Sheet 1")
FirstCol = Sheet.Columns[0]
FirstRow = Sheet.Rows[0]
获取总行数和总列数
Sheet.Rows.getCount() 
Sheet.Columns.getCount() 
设置列为最佳宽度
col.OptimalWidth = True
设置行为最佳高度
row.OptimalHeight = True

以下示例把工作表中的前五行设置为最佳高度。

odoc = XSCRIPTCONTEXT.getDocument()
Sheet =odoc.Sheets.getByName("Sheet 1")
for i in range(5):row = Sheet.Rows[i]row.OptimalHeight = True

2、增加行列

使用insertByIndex方法插入行或列
Sheet.Rows.insertByIndex(3, 1)
第1个参数是插入的位置,第二个参数是插入的行数
示例

odoc = XSCRIPTCONTEXT.getDocument()
Sheet =odoc.Sheets.getByIndex(0)
Sheet.Columns.insertByIndex(3, 1)
Sheet.Rows.insertByIndex(3, 1)

在第四列的位置插入了一个新列(索引为3,编号从0开始),第二个参数指定要插入的列数。

3、删除行列

使用removeByIndex方法删除行或列
sheet.getRows().removeByIndex(start_row,nb_rows)
例子

odoc = XSCRIPTCONTEXT.getDocument()
Sheet =odoc.Sheets.getByIndex(0)
Sheet.Columns.removeByIndex(5, 1)
Sheet.Rows.removeByIndex(5, 1)

删除了第六列(索引为5),第二个参数指定要删除的列数。

(五)单元格

单元格英文叫cell

1、获取单元格

(1)使用坐标获取单元格

左上角单元格位置为(0,0),x坐标向右,y坐标向下。
以下示例获取左上角单元格:

odoc = XSCRIPTCONTEXT.getDocument()
Sheet =odoc.Sheets.getByIndex(0)
Cell = Sheet.getCellByPosition(0, 0)
(2)使用名称获取单元格

除了坐标以外,每个单元格都有名称,例如,左上角的单元格 (0,0) 称为A1。字母A表示列,数字1表示行。切勿将单元格的名称和坐标混淆,因为名称的行计数从1开始,而坐标计数从0开始。

odoc = XSCRIPTCONTEXT.getDocument()
Sheet =odoc.Sheets.getByIndex(0)
Sheet.getCellRangeByName("C4")
获取单元格的行号和列号
cell.getCellAddress().Column
cell.getCellAddress().Row
获取单元格所在的工作表
cell.getCellAddress().Sheet

2、操作单元格

获取单元格之后,我们就可以操作单元格了

(1)读取单元格

单元格内容由单元格类型决定
类型有四种TEXT, EMPTY, VALUE, FORMULA(from com.sun.star.table.CellContentType import TEXT, EMPTY, VALUE, FORMULA)
使用如下函数获得类型
cell.getType()
或者直接使用
cell.Type

读取内容时,不同类型要读取不同的属性
当类型是VALUE时,使用cell.getValue() or cell.Value
当类型是TEXT时,使用cell.getString() or cell.String
当类型是FORMULA时,使用cell.getFormula() or cell.Formula

例子

from com.sun.star.table.CellContentType import EMPTY, VALUE, TEXT, FORMULA
odoc = XSCRIPTCONTEXT.getDocument()
Sheet =odoc.Sheets.getByIndex(0)
Cell = Sheet.getCellByPosition(1,1)
if Cell.Type == EMPTY:rlt = None
elif Cell.Type == VALUE:rlt = cell.Value
elif Cell.Type == TEXT:rlt = cell.String
elif Cell.Type == FORMULA:rlt = cell.Formula
(2)写入单元格

同样要根据类型设置相应的属性

cell.setValue(value) or cell.Value=value
cell.setString(string) or cell.String=string
cell.setFormula(formula) or cell.Formula=formula

例子

odoc = XSCRIPTCONTEXT.getDocument()
Sheet =odoc.Sheets.getByIndex(0)
Cell = Sheet.getCellByPosition(0, 0)
Cell.Value = 100
Cell = Sheet.getCellByPosition(0, 1)
Cell.String = "Test"
Cell = Sheet.getCellByPosition(0, 2)
Cell.Formula = "=A1"

本示例在单元格A1至A3中分别插入了一个数字、一段文本、一个公式。

使用String属性的单元格,其中的内容视为文本,即使该内容为数字也是如此。数字在单元格中左对齐,而不是右对齐。
在使用公式时,也要注意文本和数字的区别:

odoc = XSCRIPTCONTEXT.getDocument()
Sheet =odoc.Sheets.getByIndex(0)
Cell = Sheet.getCellByPosition(0, 0)
Cell.Value = 100
Cell = Sheet.getCellByPosition(0, 1)
Cell.String = 1000
Cell = Sheet.getCellByPosition(0, 2)
Cell.Formula = "=A1+A2"

虽然单元格A1包含值100,单元格A2包含值1000,但公式A1+A2返回值100。这是因为单元格A2使用是String属性,而不是Value。

(3)设置单元格背景色
cell.CellBackColor=-1 (no color)
cell.CellBackColor=0 (black)
cell.CellBackColor=255 (blue)
cell.CellBackColor=0xFF0000 (red)

3、插入、删除、复制、移动单元格

同单元格区域

(六)单元格区域

单元格区域英文叫cellrange

1、获取单元格区域

(1)通过坐标获取单元格区域
odoc = XSCRIPTCONTEXT.getDocument()
Sheet =odoc.Sheets.getByIndex(0)
CellRange = Sheet.getCellRangeByPosition(0,0,2,14)

四个参数分别表示左、上、右、下

(2)通过名称获取单元格区域

使用冒号(:)来指定单元格区域。

例如,A1:C15表示A、B、C列中1至15行的所有单元格。

odoc = XSCRIPTCONTEXT.getDocument()
Sheet =odoc.Sheets.getByIndex(0)
CellRange = Sheet.getCellRangeByName("A1:C15")

还可以继续获取单元格区域中的单元格
以下示例获取单元格C3。

odoc = XSCRIPTCONTEXT.getDocument()
Sheet =odoc.Sheets.getByIndex(0)
CellRange = Sheet.getCellRangeByName("B2:D4")
Cell = CellRange.GetCellByPosition(1, 1)
获取单元格区域的坐标范围
cellrange.getRangeAddress().StartRow
cellrange.getRangeAddress().StartColumn
cellrange.getRangeAddress().EndRow
cellrange.getRangeAddress().EndColumn
(3)获取使用区域
cursor = sheet.createCursor()
cursor.gotoStartOfUsedArea(False)
cursor.gotoEndOfUsedArea(True)
cellrangeaddress = cursor.getRangeAddress()

2、操作单元格区域

(1)读取单元格区域

将单元格区域内容读取为数组
cellrange.getDataArray()

(2)清除单元格区域内容

clearContents(flags) 方法简化了删除单元格区域内容的过程,因为它从单元格区域中删除一种特定类型的内容。
flags是com.sun.star.sheet.CellFlags中的常量。有以下值:
VALUE 未设置为日期或时间格式的数字值
DATETIME 设置为日期或时间格式的数字值
STRING 字符串
ANNOTATION 链接到单元格的注释
FORMULA 公式
HARDATTR 单元格的直接格式
STYLES 间接格式
OBJECTS 连接到单元格的绘图对象
EDITATTR 仅适用于部分单元格的字符格式
也可以将常量相加

以下示例从B2:C3区域中删除所有字符串和直接格式信息。

from com.sun.star.sheet.CellFlags import STRING, HARDATTR
odoc = XSCRIPTCONTEXT.getDocument()
Sheet =odoc.Sheets.getByIndex(0)
CellRange = Sheet.getCellRangeByName("B2:C3")
Flags = STRING + HARDATTR
CellRange.clearContents(Flags)
(3)计算单元格区域的值

使用computeFunction(func) 方法计算单元格区域的值。
func是 com.sun.star.sheet.GeneralFunction枚举,表示要使用的数学函数。
可以使用以下值:
SUM 所有数字值的总和
COUNT 所有值的总数(包括非数字值)
COUNTNUMS 所有数字值的总数
AVERAGE 所有数字值的平均值
MAX 最大数字值
MIN 最小数字值
PRODUCT 所有数字值的乘积
STDEV 标准偏差
VAR 方差
STDEVP 基于总体的标准偏差
VARP 基于总体的方差
以下示例计算A1:C3区域的平均值:

from com.sun.star.sheet.GeneralFunction import AVERAGE
odoc = XSCRIPTCONTEXT.getDocument()
Sheet =odoc.Sheets.getByIndex(0)
CellRange = Sheet.getCellRangeByName("A1:C3")
rlt = CellRange.computeFunction(AVERAGE)
(4)搜索和替换单元格内容

使用replaceAll(ReplaceDescriptor)替换全部搜索到的内容
ReplaceDescriptor是用于搜索和替换的描述符对象。
示例:

odoc = XSCRIPTCONTEXT.getDocument()
Sheet =odoc.Sheets.getByIndex(0)
ReplaceDescriptor = Sheet.createReplaceDescriptor()
ReplaceDescriptor.SearchString = "is"
ReplaceDescriptor.ReplaceString = "was"
for i in range(odoc.Sheets.getCount()):Sheet = odoc.Sheets[i]Sheet.replaceAll(ReplaceDescriptor)

此示例使用文档的第一个工作表创建一个ReplaceDescriptor,然后通过循环将其应用于所有工作表。

3、插入、删除、复制、移动单元格区域

(1)插入单元格区域

使用insertCells(cellrangeaddress,cellinsertmode)插入单元格区域
第一个参数是com.sun.star.table.CellRangeAddress结构。表示要插入的目标位置。
该结构中包含以下值:
Sheet (short) 工作表编号(编号从0开始)。
StartColumn (long) 单元格区域中的第一列(编号从0开始)。
StartRow (long) 单元格区域中的第一行(编号从0开始)。
EndColumn (long) 单元格区域中的最后一列(编号从0开始)。
EndRow (long) 单元格区域中的最后一行(编号从0开始)。

第二个参数是com.sun.star.sheet.CellInsertMode枚举值,它定义了如何处理位于插入位置的值。
CellInsertMode枚举有以下值:
NONE 当前值保留在目前位置。
DOWN 插入位置及其下面的单元格向下移动。
RIGHT 插入位置及其右侧的单元格向右移动。
ROWS 插入位置之后的行向下移动。
COLUMNS 插入位置之后的列向右移动。

示例

from com.sun.star.table import CellRangeAddress,CellAddress
from com.sun.star.sheet.CellInsertMode import DOWN
odoc = XSCRIPTCONTEXT.getDocument()
Sheet =odoc.Sheets.getByIndex(0)
cellRangeAddress = CellRangeAddress()
cellRangeAddress.Sheet = 0
cellRangeAddress.StartColumn = 1
cellRangeAddress.StartRow = 1
cellRangeAddress.EndColumn = 2
cellRangeAddress.EndRow = 2
Sheet.insertCells(cellRangeAddress, DOWN)

本示例在第一个工作表(编号为0)中的第二列、第二行交叉处(行号和列号均为1)插入了一个大小为两行乘两列的单元格区域。指定单元格区域内的任何现有值都将移到该区域之下。

(2)删除单元格区域

使用removeRange(cellrangeadress, celldeletemode)方法删除单元格区域
第一个参数是CellRangeAddress结构,表示要删除的目标区域。
第二个参数是com.sun.star.sheet.CellDeleteMode枚举,表示删除后其它单元格如何移动。
此枚举有以下值:
NONE 当前值保留在当前位置。
UP 插入位置及其下面的单元格向上移动。
LEFT 插入位置及其右侧的单元格向左移动。
ROWS 插入位置之后的行向上移动。
COLUMNS 插入位置之后的列向左移动。

例子

from com.sun.star.table import CellRangeAddress,CellAddress
from com.sun.star.sheet.CellDeleteMode import UP
odoc = XSCRIPTCONTEXT.getDocument()
Sheet =odoc.Sheets.getByIndex(0)
cellRangeAddress = CellRangeAddress()
cellRangeAddress.Sheet = 0
cellRangeAddress.StartColumn = 1
cellRangeAddress.StartRow = 1
cellRangeAddress.EndColumn = 2
cellRangeAddress.EndRow = 2
Sheet.removeRange(cellRangeAddress, UP)

本示例删除B2:C3单元格区域,然后将下面的单元格向上移动两行。

(3)移动单元格

使用moveRange(celladress, CellRangeAddress)方法移动单元格区域
第一个参数是com.sun.star.table.CellAddress结构,表示要移动到的目标位置。
CellAddress方法提供了以下值:
Sheet (short) 电子表格编号(编号从0开始)。
Column (long) 目标列的编号(编号从0开始)。
Row (long) 目标行的编号(编号从0开始)。
第二个参数是移动的来源单元格区域。
moveRange方法会覆盖目标区域中的单元格内容。

以下示例移动B2:C3区域到A6:

from com.sun.star.table import CellRangeAddress,CellAddress
odoc = XSCRIPTCONTEXT.getDocument()
Sheet =odoc.Sheets.getByIndex(0)
cellRangeAddress = CellRangeAddress()
cellRangeAddress.Sheet = 0
cellRangeAddress.StartColumn = 1
cellRangeAddress.StartRow = 1
cellRangeAddress.EndColumn = 2
cellRangeAddress.EndRow = 2
cellAddress = CellAddress()
cellAddress.Sheet = 0
cellAddress.Column = 0
cellAddress.Row = 5
Sheet.moveRange(cellAddress, cellRangeAddress)
(4)复制单元格

copyRange方法与moveRange方法的工作方式相同,所不同的是copyRange插入单元格区域的副本而不是移动该区域。

以下示例复制第一张工作表的B2:C3区域到第三张工作表的A6:

from com.sun.star.table import CellRangeAddress,CellAddress
odoc = XSCRIPTCONTEXT.getDocument()
Sheet =odoc.Sheets.getByIndex(0)
cellRangeAddress = CellRangeAddress()
cellRangeAddress.Sheet = 0
cellRangeAddress.StartColumn = 1
cellRangeAddress.StartRow = 1
cellRangeAddress.EndColumn = 2
cellRangeAddress.EndRow = 2
cellAddress = CellAddress()
cellAddress.Sheet = 2
cellAddress.Column = 0
cellAddress.Row = 5
Sheet.copyRange(cellAddress, cellRangeAddress)

(七)创建消息框

python的print不显示,想要调试就要使用消息框

1、使用libreoffice自带的api

(1)第一种方法

例子

from com.sun.star.awt.MessageBoxType import MESSAGEBOX, INFOBOX, WARNINGBOX, ERRORBOX, QUERYBOX
from com.sun.star.awt.MessageBoxButtons import BUTTONS_OK, BUTTONS_OK_CANCEL, BUTTONS_YES_NO, BUTTONS_YES_NO_CANCEL, BUTTONS_RETRY_CANCEL, BUTTONS_ABORT_IGNORE_RETRY
from com.sun.star.awt.MessageBoxResults import OK, YES, NO, CANCEL
def pty():result = MessageBox('hello')def MessageBox(MsgText, MsgButtons=BUTTONS_OK):odoc = XSCRIPTCONTEXT.getDocument()parentwin = odoc.CurrentController.Frame.ContainerWindowmyBox = parentwin.getToolkit().createMessageBox(parentwin, MESSAGEBOX, MsgButtons, 'bt', MsgText)return myBox.execute()
(2)第二种方法

注意:这种方法有一些问题,比如消息框位置不对,无法点击x关闭。
例子

from msgbox import MsgBox
def pty():odoc = XSCRIPTCONTEXT.getDocument()MessageBox('hello')
def MessageBox(MsgText):mb = MsgBox(uno.getComponentContext())mb.addButton("Ok")mb.show(MsgText, 0, "bt")

2、使用apso扩展提供的api

apso扩展提供一个模块apso_utils。这个模块中有一个消息框函数
msgbox(message, title='Message', boxtype='message', buttons=1, win=None)
注意:使用这个函数,必须通过“工具-宏-organize python scripts”中的“Execute”来执行宏

例子

from apso_utils import msgbox
def pty():odoc = XSCRIPTCONTEXT.getDocument()msgbox(odoc.Title)

六、使用调度器

import uno
ctx = uno.getComponentContext()
smgr = ctx.getServiceManager()
dispatcher = smgr.createInstanceWithContext( "com.sun.star.frame.DispatchHelper", ctx)
odoc = XSCRIPTCONTEXT.getDocument()
ctlr = odoc.getCurrentController()
# enter a string
struct = uno.createUnoStruct('com.sun.star.beans.PropertyValue')
struct.Name = 'StringName'
struct.Value = 'Hello World!'
dispatcher.executeDispatch(ctlr, ".uno:EnterString", "", 0, tuple([struct]))
# focus / go to cell
struct = uno.createUnoStruct('com.sun.star.beans.PropertyValue')
struct.Name = 'ToPoint'
struct.Value = 'Sheet1.A1'
dispatcher.executeDispatch(ctlr, ".uno:GoToCell", "", 0, tuple([struct]))
# drag and autofill
struct = uno.createUnoStruct('com.sun.star.beans.PropertyValue')
struct.Name = 'EndCell'
struct.Value = 'Sheet1.A10'
dispatcher.executeDispatch(ctlr, ".uno:AutoFill", "", 0, tuple([struct]))
# recalculate
dispatcher.executeDispatch(ctlr, ".uno:Calculate", "", 0, tuple([]))
# unDo
dispatcher.executeDispatch(ctlr, ".uno:Undo", "", 0, ())
# reDo
dispatcher.executeDispatch(ctlr, ".uno:Redo", "", 0, ())
# quit LibreOffice
dispatcher.executeDispatch(ctlr, ".uno:Quit", "", 0, ())
# insert rows
dispatcher.executeDispatch(ctlr, ".uno:InsertRows", "", 0, ())
# delete rows
dispatcher.executeDispatch(ctlr, ".uno:DeleteRows", "", 0, ())
# insert columns
dispatcher.executeDispatch(ctlr, ".uno:InsertColumns", "", 0, ())
# delete columns
dispatcher.executeDispatch(ctlr, ".uno:DeleteColumns", "", 0, ())
# copy, cut, paste
dispatcher.executeDispatch(ctlr, ".uno:Copy", "", 0, ())
dispatcher.executeDispatch(ctlr, ".uno:Cut", "", 0, ())
dispatcher.executeDispatch(ctlr, ".uno:Paste", "", 0, ())
# clear contents of column A
struct = uno.createUnoStruct('com.sun.star.beans.PropertyValue')
struct.Name = 'Flags'
struct.Value = 'A'
dispatcher.executeDispatch(ctlr, ".uno:Delete", "", 0, tuple([struct]))
# saveAs
struct = uno.createUnoStruct('com.sun.star.beans.PropertyValue')
struct.Name = 'URL'
struct.Value = 'file:///Users/christopherbourez/Documents/test_save.ods'
dispatcher.executeDispatch(ctlr, ".uno:SaveAs", "", 0, tuple([struct]))
# open
struct = uno.createUnoStruct('com.sun.star.beans.PropertyValue')
struct.Name = 'URL'
struct.Value = 'file:///Users/christopherbourez/Documents/test.ods'
dispatcher.executeDispatch(ctlr, ".uno:Open", "", 0, tuple([struct]))

查找调度命令
http://wiki.services.openoffice.org/wiki/Framework/Article/OpenOffice.org_3.x_Commands
包含一个命令列表。

相关文章:

libreoffice表格python宏教程 一

一、安装python宏扩展 LibreOffice自带了一个宏编辑器&#xff0c;但是只能用basic语言&#xff0c;无法用Python。 所以&#xff0c;我们必须在单独的编辑器中编写Python代码。 需要安装apso扩展&#xff0c;此扩展可以创建删除管理python宏文件&#xff0c;同时还能设置偏好…...

C/C++语言基础--C++STL库之仿函数、函数对象、bind、function简介

本专栏目的 更新C/C的基础语法&#xff0c;包括C的一些新特性 前言 STL无疑是C史上一个重要的发明&#xff0c;未来我将更新STL有关的知识点&#xff0c;入门绝对够了(看目录就知道了&#x1f440;)这是第二篇&#xff0c;讲仿函数C语言后面也会继续更新知识点&#xff0c;如…...

前端导出PDF的组件及方法

前端导出PDF的组件及方法 在Web应用程序中&#xff0c;导出PDF文件是一项常见的需求。无论是为了打印、分享还是存档&#xff0c;能够将网页内容转换为PDF格式都非常有用。幸运的是&#xff0c;前端开发者有多种方法和组件可以实现这一功能。在本文中&#xff0c;我们将详细介…...

大数据-256 离线数仓 - Atlas 数据仓库元数据管理 正式安装 启动服务访问 Hive血缘关系导入

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; Java篇开始了&#xff01; 目前开始更新 MyBatis&#xff0c;一起深入浅出&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff0…...

水文知识图谱构建-学习+代码

文章目录 水文模型知识图谱构建与应用&#xff08;核心&#xff09;面向水利防汛抢险的知识图谱构建与应用知识图谱在水利工程中的构建与应用代码 水文模型知识图谱构建与应用&#xff08;核心&#xff09; 水文模型知识图谱构建与应用 题目&#xff1a;水文模型知识图谱构建…...

python rabbitmq实现简单/持久/广播/组播/topic/rpc消息异步发送可配置Django

windows首先安装rabbitmq 点击参考安装 1、环境介绍 Python 3.10.16 其他通过pip安装的版本(Django、pika、celery这几个必须要有最好版本一致) amqp 5.3.1 asgiref 3.8.1 async-timeout 5.0.1 billiard 4.2.1 celery 5.4.0 …...

clickhouse优化记录

一、注重使用分区键来加快查询 在大数据量的情况下&#xff0c;如果查询语句中&#xff0c;可以使用分区键来进行查询&#xff0c;可以极大缩小数据的查询范围&#xff0c;加快查询速度。 二、使用order by的列&#xff0c;适用最左前缀匹配原则 比如表的结构是 order by(id…...

RabbitMQ如何构建集群?

大家好&#xff0c;我是锋哥。今天分享关于【RabbitMQ如何构建集群&#xff1f;】面试题。希望对大家有帮助&#xff1b; RabbitMQ如何构建集群&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 在RabbitMQ中&#xff0c;集群&#xff08;Cluster&#x…...

Python解压tar压缩文件

import tarfile import os# 解压文件def untar(self, log_tar_file, destination_dir):# 打开tar文件tar_file_path for tar_file_path in glob.glob(os.path.join(log_tar_file, **/*.tar), recursiveTrue):print(日志压缩文件&#xff1a;,tar_file_path)if ! tar_file_pat…...

Mac升级macOS 15 Sequoia后,无法ssh连接本地虚拟机

现象 macOS 15后&#xff0c;无法ssh连接本地启动的虚拟机&#xff0c;提示错误&#xff1a; No route to host&#xff0c;也ping不通。包括UTM、Parallels Desktop这两个虚拟机软件。之前都是没问题的&#xff0c;通过一些简单排查&#xff0c;目前没发现什么问题。 在虚拟…...

Unity录屏插件-使用Recorder录制视频

目录 1.Recorder的下载 2.Recorder面板 2.1常规录制属性 2.2录制器配置 2.2.1添加录制器 2.2.2配置Input属性 2.2.3配置 Output Format 属性 2.2.4配置 Output File 属性 3.Recorder的使用 3.1录制Game View视频 3.1.1Recorder配置与场景搭建 3.1.2开始录制 3.1.3…...

[ESP]从零开始的Arduino IDE安装与ESP环境配置教程

一、前言 最近也是在比赛方面比较忙&#xff0c;没有更多的时间和精力去更新长文章了。这几周都更倾向于环境搭建的教程&#xff0c;这类教程写起来确实方便&#xff0c;也不怎么费时间&#xff0c;一个下午基本可以搞定&#xff0c;哈哈&#xff0c;我保证不是在为自己想摆烂找…...

重拾设计模式--状态模式

文章目录 状态模式&#xff08;State Pattern&#xff09;概述状态模式UML图作用&#xff1a;状态模式的结构环境&#xff08;Context&#xff09;类&#xff1a;抽象状态&#xff08;State&#xff09;类&#xff1a;具体状态&#xff08;Concrete State&#xff09;类&#x…...

2024年全球办公键盘行业总体规模、主要企业国内外市场占有率及排名

根据QYResearch研究团队调研统计&#xff0c;2023年全球办公键盘市场销售额达到了 亿元&#xff0c;预计2030年将达到 亿元&#xff0c;年复合增长率&#xff08;CAGR&#xff09;为 %&#xff08;2024-2030&#xff09;。中国市场在过去几年变化较快&#xff0c;2023年市场规模…...

ThreadLocal用法详解

ThreadLocal 是 Java 中的一个类&#xff0c;它提供了线程局部变量的功能。线程局部变量是线程隔离的&#xff0c;每个使用该变量的线程都有其自己的变量副本&#xff0c;因此每个线程可以操作自己的线程局部变量&#xff0c;而不会和其他线程冲突。 以下是 ThreadLocal 的一些…...

linux中docker命令大全

基本命令 docker pull 拉取镜像 docker pull docker push 推送镜像到DockerRegistry docker push docker images 查看本地镜像 docker images docker rmi 删除本地镜像 docker rmi docker run 创建并运行容器&#xff08;不能重复创建&#xff09; docker run d…...

linux-----常用指令

文件和目录操作指令 ls&#xff08;list&#xff09;指令 功能&#xff1a;用于列出目录的内容&#xff0c;包括文件和子目录。示例&#xff1a; ls&#xff1a;列出当前目录下的所有非隐藏文件和目录。例如&#xff0c;在一个包含文件file1.txt、file2.txt和目录dir1的目录中&…...

1.gitlab 服务器搭建流程

前提条件&#xff1a; 一、服务器硬件水平 搭建gitlab服务器最低配置要求2核4G,低于这个配置的服务器运行效果很差。 gitlab官网&#xff1a;https://about.gitlab.com/ 下载地址&#xff1a;gitlab/gitlab-ce - Packages packages.gitlab.com 本机ubuntu 二、安装依赖 su…...

C 语言基础运算:输入两个整数并计算和、差、积

一、C 语言编程世界初窥 在当今数字化浪潮汹涌澎湃的时代,编程已成为一项极具影响力的技能,它犹如一把神奇的钥匙,能够开启无数创新与可能的大门。而在众多编程语言中,C 语言无疑是一颗最为璀璨耀眼的恒星,长久以来在编程的浩瀚星空中熠熠生辉,散发着独特而迷人的魅力。…...

PC寄存器(Program Counter Register) jvm

在JVM&#xff08;Java虚拟机&#xff09;中&#xff0c;PC寄存器&#xff08;Program Counter Register&#xff09;扮演着至关重要的角色&#xff0c;它是JVM执行引擎的核心组成部分之一。以下是PC寄存器在JVM中的具体角色和职责&#xff1a; 指令执行指针&#xff1a; PC寄存…...

CPU概述随堂测试

1. [单选题] 下列部件不属于控制器的是( )。 A. 指令寄存器 B. 程序计数器 C. 程序状态字寄存器 D. 时序电路 正确答案&#xff1a;C 控制器的主要组成部分包括指令寄存器&#xff08;IR&#xff09;、程序计数器&#xff08;PC&#xff09;&#xff0c;以及用于控制…...

centos7下docker 容器实现redis主从同步

1.下载redis 镜像 docker pull bitnami/redis2. 文件夹授权 此文件夹是 你自己映射到宿主机上的挂载目录 chmod 777 /app/rd13.创建docker网络 docker network create mynet4.运行docker 镜像 安装redis的master -e 是设置环境变量值 docker run -d -p 6379:6379 \ -v /a…...

【数据安全】如何保证其安全

数据安全风险 数字经济时代&#xff0c;数据已成为重要的生产要素。智慧城市、智慧政务的建设&#xff0c;正以数据为核心&#xff0c;推动城市管理的智能化和公共服务的优化。然而&#xff0c;公共数据开放共享与隐私保护之间的矛盾日益凸显&#xff0c;如何在确保数据安全的…...

GTID详解

概念和组成 1&#xff0c;全局事务表示&#xff1a;global transaction identifiers 2, GTID和事务一一对应&#xff0c;并且全局唯一 3&#xff0c;一个GTID在一个服务器上只执行一次 4&#xff0c;mysql 5.6.5开始支持 组成 GTID server_uuid:transaction_id 如&#xf…...

【bodgeito】攻防实战记录

也许有一天我们再相逢&#xff0c;睁开眼睛看清楚&#xff0c;我才是英雄。 进入网站整体浏览网页 点击页面评分进入关卡 一般搭建之后这里都是红色的&#xff0c;黄色是代表接近&#xff0c;绿色代表过关 首先来到搜索处本着见框就插的原则 构造payload输入 <script>…...

【基础篇】1. JasperSoft Studio编辑器与报表属性介绍

编辑器介绍 Jaspersoft Studio有一个多选项卡编辑器&#xff0c;其中包括三个标签&#xff1a;设计&#xff0c;源代码和预览。 Design&#xff1a;报表设计页面&#xff0c;可以图形化拖拉组件设计报表&#xff0c;打开报表文件的主页面Source&#xff1a;源代码页码&#xff…...

SpringBoot+Vue3实现阿里云视频点播 实现教育网站 在上面上传对应的视频,用户开会员以后才能查看视频

要使用阿里云视频点播&#xff08;VOD&#xff09;实现一个教育网站&#xff0c;其中用户需要成为会员后才能查看视频&#xff0c;这个过程包括上传视频、设置权限控制、构建前端播放页面以及确保只有付费会员可以访问视频内容。 1. 视频上传与管理 创建阿里云账号&#xff…...

在VBA中结合正则表达式和查找功能给文档添加交叉连接

在VBA中搜索文本有两种方式可用&#xff0c;一种是利用Range.Find对象&#xff08;更常见的形式可能是Selection.Find&#xff0c;Selection是Range的子类&#xff0c;Selection.Find其实就是特殊的Range.Find&#xff09;&#xff0c;另一种方法是利用正则表达式&#xff0c;但…...

spring\strust\springboot\isp前后端那些事儿

后端 一. 插入\更新一条数据&#xff08;老&#xff09; Map<String, Object> parameterMap MybatisUtil.initParameterSave("Send_ProjectFrozenLog", sendProjectFrozenLog); commonMapper.insert(parameterMap);parameterMap MybatisUtil.initParameter…...

Redis——缓存预热+缓存雪崩+缓存击穿+缓存穿透

文章目录 1、 缓存预热2、 缓存雪崩3、 缓存击穿4、 缓存穿透总结 1、 缓存预热 什么是预热&#xff1a; mysql加入新增100条记录&#xff0c;一般默认以mysql为准作为底单数据&#xff0c;如何同步给redis&#xff08;布隆过滤器&#xff09;这100条新数据。 为什么需要预热…...

【Java计算机毕业设计】基于Springboot小药店销售管理系统【源代码+数据库+LW文档+开题报告+答辩稿+部署教程+代码讲解】

源代码数据库LW文档&#xff08;1万字以上&#xff09;开题报告答辩稿 部署教程代码讲解代码时间修改教程 一、开发工具、运行环境、开发技术 开发工具 1、操作系统&#xff1a;Window操作系统 2、开发工具&#xff1a;IntelliJ IDEA或者Eclipse 3、数据库存储&#xff1a…...

AIGC与现代教育技术

目录 引言 一、AIGC在教育技术中的基本概念 1.1 什么是AIGC&#xff1f; 1.2 传统教育技术和AIGC的对比 二、实现过程&#xff1a;AIGC在现代教育中的实现 2.1 自动生成课件内容 2.1.1 代码示例&#xff1a;使用GPT生成教学文案 2.1.2 完善自动生成资料 2.1.3 多模态内…...

【活动邀请·深圳】深圳COC社区 深圳 AWS UG 2024 re:Invent re:Cap

re:Invent 是全球云计算领域的顶级盛会&#xff0c;每年都会吸引来自世界各地的技术领袖、创新者和实践者汇聚一堂&#xff0c;分享最新的技术成果和创新实践&#xff0c;深圳 UG 作为亚马逊云科技技术社区的重要组成部分&#xff0c;将借助 re:Invent 的东风&#xff0c;举办此…...

Java中的LIst

在Java中&#xff0c;List接口是集合框架&#xff08;Collections Framework&#xff09;的一部分&#xff0c;用于表示有序的集合&#xff08;也称为序列&#xff09;。List允许存储重复的元素&#xff0c;并且可以通过索引访问元素。以下是对Java中List的详细介绍&#xff1a…...

源码分析之Openlayers中MousePosition鼠标位置控件

概述 本文主要介绍 Openlayers 中的MousePosition鼠标位置控件&#xff0c;该控件会创建一个元素在页面的右上方用来实时显示鼠标光标的位置坐标。该控件在实际应用很有效&#xff0c;可以实时获取鼠标位置&#xff0c;但是一般控件元素都会自定义。 源码分析 MousePosition…...

List深拷贝后,数据还是被串改

List深拷贝后数据还是被串改 List newList new ArrayList<>(oldList)newList.pushAll(oldList)你甚至想到了java8streamAPI以上还不行 List newList new ArrayList<>(oldList) 这是采用构造参数做到的深拷贝&#xff0c;是没问题的 newList.pushAll(oldList) …...

一级路由器与二级路由器网络互通配置,实现父网络访问子网络

一级路由器与二级路由器网络互通配置&#xff0c;实现父网络访问子网络 从图看a路由器是b的父路由。默认配置情况下b路由下的PC设备可以访问a路由器下的PC设备&#xff0c;但是a路由下的设备无法访问b路由下设备。 为了实现互通&#xff0c;需要配置静态路由表。 我的a路由器是…...

linux作 samba 服务端,linux windows文件互传,免账号密码

一 ubuntu 安装 sudo apt install samba二 修改samba 配置文件 1 路径 ls -l /etc/samba/smb.conf2 修改文件 a&#xff1a;配置成 匿名用户&#xff0c;无需输入账号 b&#xff1a;注意配置可读写且文件可创建可删除 [global] workgroup SAMBA security user passdb back…...

使用C#调用SAP的WebService接口

URL 是一个 WSDL 地址&#xff0c;这意味着你可以使用 SOAP Web Service 来调用ZRFC_WEB_MES_MM_015 接口。我们将使用 C# 中的 System.Web.Services.Protocols.SoapHttpClientProtocol 或 System.ServiceModel 命名空间来实现这一点。这里我们使用 System.ServiceModel 命名空…...

线程知识总结(二)

本篇文章以线程同步的相关内容为主。线程的同步机制主要用来解决线程安全问题&#xff0c;主要方式有同步代码块、同步方法等。首先来了解何为线程安全问题。 1、线程安全问题 卖票示例&#xff0c;4 个窗口卖 100 张票&#xff1a; class Ticket implements Runnable {priv…...

HarmonyOS(72)事件拦截处理详解

事件拦截 1、参考资料2、HitTestMode3、onTouchIntercept、onTouch、onClick事件执行顺序3.1、系统默认事件传递顺序3.2、子组件拦截事件1、参考资料 HarmonyOS(71) 自定义事件分发之TouchTestStrategy使用说明HarmonyOS(70) ArkUI 事件分发拦截,事件冲突解决方案HitTestModea…...

Leetcode-208. 实现Trie(前缀树)

前缀树是一个由“路径”和“节点”组成多叉树结构。由根节点出发&#xff0c;按照存储字符串的每个字符&#xff0c;创建对应字符路径&#xff0c;以此实现快速查找单词或是否为前缀的功能。 此题要求简单&#xff0c;只需实现下面几种功能&#xff1a; Trie() 初始化前缀树对…...

网络安全系列 之 SQL注入学习总结

1. sql注入概述 程序里面如果使用了未经校验的外部输入来构造SQL语句&#xff0c;就很可能会引入SQL注入漏洞。 注入攻击 对于字符串输入&#xff0c;如果这个字符串将被解释为某种指令&#xff0c;那么需要特别注意防止注入攻击。sql注入、os命令注入、xml注入是典型的攻击类…...

JVM中的方法绑定机制

JVM中的方法绑定机制主要分为静态绑定&#xff08;Static Binding&#xff09;和动态绑定&#xff08;Dynamic Binding&#xff09;两种。以下是关于这两种绑定机制的详细解释&#xff1a; 一、静态绑定&#xff08;Static Binding&#xff09; 定义&#xff1a;静态绑定是指在…...

tomato靶场攻略

前提&#xff1a;kali和tomato的连接方式都为net模式 tomato的默认网络连接方式为桥接模式&#xff0c;导入前注意修改&#xff0c;将tomato.ova的镜像导入虚拟机中 出现此页面则表示导入成功&#xff0c;打开kali虚拟机终端&#xff0c;切换为root权限 arp-scan -l 浏览器访…...

移动魔百盒中的 OpenWrt作为旁路由 安装Tailscale并配置子网路由实现在外面通过家里的局域网ip访问内网设备

移动魔百盒中的 OpenWrt作为旁路由 安装Tailscale并配置子网路由实现在外面通过家里的局域网ip访问内网设备 一、前提条件 确保路由器硬件支持&#xff1a; OpenWrt 路由器需要足够的存储空间和 CPU 性能来运行 Tailscale。确保设备架构支持 Tailscale 二进制文件&#xff0c;例…...

wxWidgets使用wxStyledTextCtrl(Scintilla编辑器)的正确姿势

开发CuteMySQL/CuteSqlite开源客户端的时候&#xff0c;需要使用Scintilla编辑器&#xff0c;来高亮显示SQL语句&#xff0c;作为C/C领域最成熟稳定又小巧的开源编辑器&#xff0c;Scintilla提供了强大的功能&#xff0c;wxWidgets对Scintilla进行包装后的是控件类&#xff1a;…...

Spring Boot中Bean的 构造器注入、字段注入和方法注入

在Spring中&#xff0c;依赖注入&#xff08;DI&#xff09;是实现控制反转&#xff08;IoC&#xff09;的一种方式&#xff0c;Spring提供了多种注入方式来将依赖关系注入到Bean中&#xff0c;常见的方式有构造器注入、字段注入和方法注入。下面将详细介绍这三种注入方式。 1…...

深入浅出支持向量机(SVM)

1. 引言 支持向量机&#xff08;SVM, Support Vector Machine&#xff09;是一种常见的监督学习算法&#xff0c;广泛应用于分类、回归和异常检测等任务。自1990年代初期由Vapnik等人提出以来&#xff0c;SVM已成为机器学习领域的核心方法之一&#xff0c;尤其在模式识别、文本…...

梯度下降的数学原理:用泰勒公式剖析梯度下降

梯度下降&#xff08;Gradient Descent&#xff09;是机器学习中非常核心的优化算法&#xff0c;通过不断调整模型参数&#xff0c;让损失函数&#xff08;Loss Function&#xff09;逐渐变小&#xff0c;从而提高模型的性能。损失函数是一个用来衡量预测值与真实值差距的函数&…...