从 Basic 到 Python

目录
索引 🔎︎

# 从 Basic 中调用 Python 脚本

可以从LibreOffice Basic宏调用Python脚本，从而获得一些有用的功能，例如：

- 可以进行ComputerName（计算机名称）识别或OSName（操作系统名称）检测，

- Basic的FileLen()函数和com.sun.star.ucb.SimpleFileAccess。getSize()API函数显示了Python帮助克服的2 GB文件大小上限，

- com.sun.star.util.PathSettings 可以标准化，

- 还有更多。

该库针对 LibreOffice Basic 以及 应用程序编程接口（API）进行了合理地暴露，在执行从Basic到Python、JavaScript或任何其他脚本引擎的跨语言调用之前使用该库是推荐的。

## 检索Python脚本

Python脚本可以是个人的、共享的，也可以嵌入到文档中。为了执行它们，需要为LibreOffice Basic提供Python脚本位置。定位com.sun.star.script.provider.XScript兼容接口的UNO对象允许执行Python脚本：

             Option Explicit

             Public Function GetPythonScript(macro As String, _
                     Optional location As String) As com.sun.star.script.provider.Xscript
                 '''在执行前抓取Python脚本对象
                 ' 参数：
                 '    宏   : 为 "library/module.py$macro" 或者 "module.py$macro"
                 '    位置：作为“文档”、“共享”、“用户”或枚举 ENUM(eration)
                 ' 结果：
                 '    定位到的 com.sun.star.script.provider.XScript UNO 服务'''
                 If IsMissing(location) Then location = "user"
                 Dim mspf As Object ' com.sun.star.script.provider.MasterScriptProviderFactory
                 Dim sp As Object ' 与 com.sun.star.script.provider.XScriptProvider 兼容
                 Dim uri As String
                 If location="document" Then
                     sp = ThisComponent.getScriptProvider()
                 Else
                     mspf = CreateUNOService("com.sun.star.script.provider.MasterScriptProviderFactory")
                     sp = mspf.createScriptProvider("")
                 End If
                 uri = "vnd.sun.star.script:"& macro &"?language=Python&location="& location
                 GetPythonScript = sp.getScript(uri)
             End Function ' GetPythonScript

## 执行Python脚本

LibreOffice 的应用程序编程接口 (API) 脚本框架支持在 Python 和 Basic 之间（或者其他受支持的编程语言之间）的跨语言脚本执行。参数可以互相之间来回传递，仅需要该参数是各个语言都能够识别的基本数据类型、且脚本框架能够对该参数进行适当的类型转换。

### 语法

workstation_name = script.invoke(Array(), Array(), Array())

opSysName = script.invoke(Array(), in_outs, Array()) ' in_out 为一个数组

file_len = script.invoke(Array(systemFilePath), Array(), Array())

normalizedPath = script.invoke(Array(systemFilePath), Array(), Array())

### 嵌入式脚本示例

下面的ComputerName和GetFilelen程序使用前面提到的GetPythonScript函数调用它们对应的Python程序。此处未对异常处理进行详细说明。

             Option Explicit
             Option Compatible ' 支持进行属性的设置

             Private scr As Object ' com.sun.star.script.provider.XScript

             Private Property Get ComputerName As String
                 '''工作站名称'''
                 scr = GetPythonScript("Platform.py$computer_name", "document")
                 ComputerName = scr.invoke(Array(), Array(), Array())
             End Property ' ComputerName

             Private Function GetFilelen(systemFilePath As String) As Currency
                 '''文件大小（字节）'''
                 scr = GetPythonScript("Os/Path.py$get_size", Script.ISEMBEDDED)
                 GetFilelen = scr.invoke(Array(systemFilePath), Array(), Array(),)
             End Function ' GetFilelen

             Private Type _SCRIPT_LOCATION
                 ISEMBEDDED As String ' 文档级的脚本
                 ISPERSONAL As String ' 用户级的脚本
                 ISSHARED As String ' LibreOffice 级别的宏
             End Type ' _SCRIPT_LOCATION

             Public Function Script() As Object ' Text enumeration
                 Static enums As _SCRIPT_LOCATION : With enums
                 If .ISEMBEDDED = "" Then
                     .ISEMBEDDED = "document" '文档级别的脚本
                     .ISPERSONAL = "user" ' 用户级别的脚本
                     .ISSHARED = "share" ' LibreOffice 宏
                 End If : End With ' enums
                 Script = enums
             End Function ' Script

调用了两个不同的Python模块。它们可以嵌入到当前文档中，也可以存储在文件系统中。为清晰起见，此处跳过了参数类型检查：

- Platform.py

             # -*- coding: utf-8 -*-
             from __future__ import unicode_literals

             import platform

             def computer_name() -> str:
                 return platform.node()

             def OSname() -> str:
                 return platform.system()

- Os/Path.py

             # -*- coding: utf-8 -*-
             from __future__ import unicode_literals

             import os.path

             def get_size(systemFilePath: str) -> str:
                 return str(os.path.getsize(systemFilePath))

             def normalyze(systemPath: str) -> str:
                 return os.path.normpath(systemPath)

### 个人或共享脚本示例

个人或共享Python脚本的调用机制与嵌入式脚本的调用机制相同。库名称映射到文件夹。计算LibreOffice用户配置文件和共享模块系统文件路径可以按照获取会话信息中的详细说明执行。在OSName的下面，HelloWorld和NormalizePath例程使用前面提到的GetPythonScript函数调用Python对应程序。异常处理未详细说明。

             Option Explicit
             Option Compatible ' 支持进行属性的设置

             Private scr As Object ' com.sun.star.script.provider.XScript

             Private Property Get OSName As String
                 '''平台名称为“Linux”、“Darwin”或“Windows”'''
                 scr = GetPythonScript("Platform.py$OSname", Script.ISPERSONAL)
                 OSName = scr.invoke(Array(), Array(), Array())
             End Property ' OSName

             Private Sub HelloWorld()
                 '''LibreOffice Python 共享示例'''
                 scr = GetPythonScript("HelloWorld.py$HelloWorldPython", Script.ISSHARED)
                 scr.invoke(Array(), Array(), Array(),)
             End Sub ' HelloWorld

             Public Function NormalizePath(systemFilePath As String) As String
                 '''去除路径中多余的 '\..' '''
                 scr = GetPythonScript("Os/Path.py$normalyze", "user")
                 NormalizePath = scr.invoke(Array(systemFilePath), Array(), Array())
             End Function ' NormalizePath

## Python标准模块

LibreOffice embedded Python包含许多可从中受益的标准库。它们具有丰富的功能集，例如但不限于：

- argparse 用于对命令行选项、参数以及子命令进行解析

- cmath 用于进行复杂计算的数学函数

- csv 对CSV逗号分隔符文件进行读写操作

- datetime 真正的日期和时间数据类型

- json 对JSON数据进行编码和解码

- math 数学函数

- re 正则表达式操作

- socket 低层网络接口

- sys 系统特定参数和功能

- unittest 和 trace 单元测试框架以及Python执行追踪

- xml.etree.ElementTree 元素树 XML API

相关主题

从 Python 中调用 BASIC 宏

LibreOffice Basic 帮助

LibreOffice Python 脚本帮助