You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用uno创建实例触发段错误,如何用uno打开Calc表格?

问题

需要处理包含多个工作表的Calc表格,按照文档基金会Wiki的Python指南操作,已安装libreoffice-script-provider-python包,可正常导入uno库,但调用create_instance函数时Python解释器会因段错误崩溃。

示例代码:

import uno

CTX = uno.getComponentContext()
SM = CTX.getServiceManager()

def create_instance(name, with_context=False):
    if with_context:
        instance = SM.createInstanceWithContext(name, CTX)
    else:
        instance = SM.createInstance(name)
    return instance

path = uno.systemPathToFileUrl('/home/user/temp/test.ods')
desktop = create_instance('com.sun.star.frame.Desktop', True)
doc = desktop.loadComponentFromURL(path, '_default', 0, ())

环境配置:

  • 操作系统:Ubuntu 22.04
  • Python版本:3.10.12
  • LibreOffice版本:7.3.7

更新:简化测试后的日志,提前启动Calc仍出现段错误:

$ soffice --calc --accept="socket,host=localhost,port=2002;urp;StarOffice.ServiceManager"
$ python3
Python 3.10.12 (main, Jun 11 2023, 05:26:28) [GCC 11.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import uno
>>> CTX = uno.getComponentContext()
>>> SM = CTX.getServiceManager()
>>> name='com.sun.star.frame.Desktop'
>>> instance = SM.createInstanceWithContext(name, CTX)

Segmentation fault (core dumped)

解决方案

段错误源于直接使用本地uno.getComponentContext()获取的上下文,无法正确与LibreOffice服务管理器交互。正确做法是通过socket连接到已启动的LibreOffice实例,获取远程服务上下文。

步骤1:启动带监听的LibreOffice

在终端启动Calc并开启socket监听:

soffice --calc --accept="socket,host=localhost,port=2002;urp;StarOffice.ServiceManager" --headless

加上--headless可后台运行(无GUI);需要可视化界面则移除该参数。

步骤2:修改Python代码连接远程服务

替换原有代码,改为通过socket连接到LibreOffice实例:

import uno

# 建立本地上下文并获取解析器
local_context = uno.getComponentContext()
resolver = local_context.ServiceManager.createInstanceWithContext(
    "com.sun.star.bridge.UnoUrlResolver", local_context
)
# 连接到LibreOffice实例的服务上下文
CTX = resolver.resolve(
    "uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext"
)
SM = CTX.getServiceManager()

def create_instance(name, with_context=False):
    if with_context:
        instance = SM.createInstanceWithContext(name, CTX)
    else:
        instance = SM.createInstance(name)
    return instance

# 转换本地路径为LibreOffice可识别的URL
path = uno.systemPathToFileUrl('/home/user/temp/test.ods')
# 获取Desktop服务并加载文档
desktop = create_instance('com.sun.star.frame.Desktop', True)
doc = desktop.loadComponentFromURL(path, '_default', 0, ())

# 示例:获取第一个工作表并打印名称
sheets = doc.getSheets()
first_sheet = sheets.getByIndex(0)
print(f"第一个工作表名称:{first_sheet.getName()}")

# 操作完成后关闭文档(可选)
doc.close(True)

额外排查点

  1. 端口占用检查:若2002端口被占用,更换为其他端口(如2003),同时修改代码中的端口号。
  2. 重新安装Python绑定:Ubuntu下的libreoffice-script-provider-python可能存在版本匹配问题,执行以下命令重装:
    sudo apt remove --purge libreoffice-script-provider-python
    sudo apt install libreoffice-script-provider-python
    
  3. Python版本兼容:LibreOffice 7.3.x默认适配Python 3.8,若问题仍存在,尝试用Python 3.8运行代码。

内容的提问来源于stack exchange,提问作者Luís de Sousa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 22:41:29