Python 3.x 使用Python使用Uno访问LibreOffice Calc

Python 3.x 使用Python使用Uno访问LibreOffice Calc,python-3.x,libreoffice-calc,uno,Python 3.x,Libreoffice Calc,Uno,我正在尝试编写一个脚本,使用Python 3.7操作Ubuntu Mint_LibreOffice计算表,。由于某种原因,我在尝试导入Uno时出错。我可以从Calc内部运行宏调用此 desktop = XSCRIPTCONTEXT.getDesktop() model = desktop.getCurrentComponent() active_sheet = model.CurrentController.ActiveSheet write 'Hello Wor

我正在尝试编写一个脚本,使用Python 3.7操作Ubuntu Mint_LibreOffice计算表,。由于某种原因,我在尝试导入Uno时出错。我可以从Calc内部运行宏调用此

    desktop = XSCRIPTCONTEXT.getDesktop()
    model = desktop.getCurrentComponent()
    active_sheet = model.CurrentController.ActiveSheet
    write 'Hello World' in A1
    active_sheet.getCellRangeByName("A1").String = "Hello World!
"

但是不能直接从VS_代码IDE与工作表交互。是否有路径需要设置为Uno_


使用LibreOffice 6.4、Python 3.7和APSO。我对LibreOffice感到非常失望,因为它对新手的Python支持似乎很少。

经过大量研究,我已经找到了如何使用Python 3.7、PyCharm和MySQL操作Ubuntu LibreOffice计算表的方法。我对所有这些都是新手,所以请原谅我的编码,我还是个新手学习。我提供了我用来完成这个项目的信息来源的链接

导致我出现问题的主要障碍是不理解在通过套接字连接之前需要启动LibreOffice。之后,我能够使用Uno和其他模块与Calc电子表格交互。我提供了所有Py脚本的副本。希望这能帮助像我这样的新手这个环境

# opens connection to mysql database GVWC
import mysql.connector
import pandas as pd
from gui import validateLogin

def conn_mysql():
    validateLogin #opens input box for username and password
    us, pw=validateLogin() #returns login info
    cnx = mysql.connector.connect(user=us, password=pw ,host='localhost', database= 'GVWC') # connects to DB
    pd.set_option('display.max_columns', None)
    df = pd.read_sql("SELECT * FROM GVWC.2020", cnx) #runs query
    return df, pd #returns data
print("Database connection resolved.")

# connection to libreoffice

import uno
import os
import time

def lo_conn():
    #Open socket to LibraOffice with delay to allow program to wait for connection
    os.popen('/usr/lib/libreoffice/program/soffice --accept="socket,host=localhost,port=2002;urp;StarOffice.ServiceManager"')
    time.sleep(3)  # Sleep for 3 seconds

    #=======================================================================================================================================
    # get the uno component context from the PyUNO runtime
    localContext = uno.getComponentContext()

    # create the UnoUrlResolver
    resolver = localContext.ServiceManager.createInstanceWithContext(
        "com.sun.star.bridge.UnoUrlResolver", localContext)

    # connect to the running office
    ctx = resolver.resolve("uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext")
    smgr = ctx.ServiceManager

# create input box for login info
from tkinter import *
from functools import partial

def validateLogin(username, password):
    #print("username entered :", username.get())
    #print("password entered :", password.get())
    global pw
    pw = password.get()
    global us
    us = username.get()
    return us, pw

#window
tkWindow = Tk()
tkWindow.geometry("500x100+500+300")
tkWindow.title('Tkinter Login Form - pythonexamples.org')

#username label and text entry box
usernameLabel = Label(tkWindow, text="User Name").grid(row=0, column=0)
username = StringVar()
usernameEntry = Entry(tkWindow, textvariable=username).grid(row=0, column=1)

#password label and password entry box
passwordLabel = Label(tkWindow,text="Password").grid(row=1, column=0)
password = StringVar()
passwordEntry = Entry(tkWindow, textvariable=password, show='*').grid(row=1, column=1)

validateLogin = partial(validateLogin, username, password)

#login button
loginButton = Button(tkWindow, text="Login", command=validateLogin).grid(row=4, column=0)

tkWindow.mainloop()


#main program to create spreedsheet and fill with data from mysql

import os
from workingConn3 import conn_mysql
from lo_conn_3 import lo_conn

def main():
    conn_mysql # call mysql def connection
    df,pd=conn_mysql() # pass table data
    lo_conn #connect to Libreoffice

    # open calc and fill spreedsheet
    #=====================================================================================================================================
    writer = pd.ExcelWriter('Test_DF.xlsx',
                                engine='xlsxwriter',
                                datetime_format='mm/dd/yyyy')

    df.to_excel(writer, index=False, sheet_name='TEST',
                   startrow=5, header = 4)

    #Get the xlsxwriter objects from the dataframe writer object.
    workbook  = writer.book
    worksheet = writer.sheets['TEST']



    #Add a header format.
    header_format = workbook.add_format({
        'font_color': 'white',
        'text_wrap': True,
        'font_name': 'Calibri',
        'font_size': 11,
        'fg_color': '#44546a'})

    # Write the column headers with the defined format.
    for col_num, value in enumerate(df.columns.values):
        worksheet.write(5, col_num, value, header_format)

    colwidths = {}

    # Store the defaults.
    for col in range(14):
        colwidths[col] = 15



    # Then set the column widths.
    for col_num, width in colwidths.items():
        worksheet.set_column(col_num, col_num, width)


    #Center text of column
    cell_format = workbook.add_format()
    cell_format.set_align('center')
    worksheet.set_column('E1:E100',15,cell_format)
    worksheet.set_column('F1:F100',15,cell_format)
    worksheet.set_column('M1:M100',15,cell_format)

    #  Freeze pane on the header row.
    #
    worksheet.freeze_panes(6, 0)
    worksheet.autofilter('A6:O6')

    #Button text
    worksheet.write('A3', 'Press the button to say hello.')

    # Add a button tied to a macro in the VBA project.
    worksheet.insert_button('A1', {'macro': 'start',
                                   'caption': 'Press Me',
                                   'width': 80,
                                   'height': 30})

    # Close the Pandas Excel writer and output the Excel file.
    writer.save()
    writer.close()
    #reopen excel file
    os.popen('/usr/lib/libreoffice/program/soffice Test_DF.xlsx  --accept="socket,host=localhost,port=2002;urp;StarOffice.ServiceManager"')


if __name__== "__main__" :
    main()


感谢所有帮助过我的人。

我遇到了同样的问题,我这样解决了它:

  • 在Ubuntu 20中安装libreoffice:
sudo apt更新
sudo apt安装libreoffice--不建议安装
  • 检查uno是否可访问(就我而言,这就是我所做的全部):
python3
Python 3.8.5(默认,2020年7月28日,12:59:40)
linux上的[GCC 9.3.0]
有关详细信息,请键入“帮助”、“版权”、“信用证”或“许可证”。
>>>进口uno
>>>打印(uno.\u文件\u)
/usr/lib/python3/dist包/uno.py
>>>退出()
  • 使用打开的套接字启动libreoffice进程(更多信息-第117页):
/usr/lib/libreoffice/program/soffice.bin--headless--invisible--nocrashreport--nodefault--nofirststartwizard--nologo--norestore--accept='socket,host=localhost,port=2002,tcpNoDelay=1;urp;StarOffice.ComponentContext'
  • 打开另一个终端并进入python3交互模式:
导入uno local_ctx=uno.getComponentContext() smgr_local=local_ctx.ServiceManager resolver=smgr_local.createInstanceWithContext(“com.sun.star.bridge.UnoUrlResolver”,local_ctx) url=“uno:socket,host=localhost,port=2002,tcpNoDalay=1;urp;StarOffice.ComponentContext“
  • 现在尝试连接:
uno\u ctx=resolver.resolve(url)
  • 如果成功,
    uno context
    就是您所需要的全部内容
  • 实例化桌面(所有应用程序的根框架-Calc、Writer、Draw等)
uno\u smgr=uno\u ctx.ServiceManager
desktop=uno\u smgr.createInstanceWithContext(“com.sun.star.frame.desktop”,uno\u ctx)
  • 创建新的计算文档(
    private:factory/scalc
    ):
PropertyValue=uno.getClass('com.sun.star.beans.PropertyValue'))
inProps=PropertyValue(“Hidden”,0,True,0),#这是一个元组
document=desktop.loadComponentFromURL(“private:factory/scalc”,“_blank”,0,inProps)
  • 播放文档:
sheets=document.getSheets()
活页_1=活页[0]
cell_1=sheet_1.getCellByPosition(1,1)
value=cell_1.setString('Hello World!')
  • 保存并检查结果:
#UNO需要绝对路径
导入操作系统
path=os.path.abspath('./testfile.xls')
uno_url=uno.systemPathToFileUrl(路径)
#保存文档时使用的筛选器。
# https://github.com/LibreOffice/core/tree/330df37c7e2af0564bcd2de1f171bed4befcc074/filter/source/config/fragments/filters
filter=uno.createUnonstruct('com.sun.star.beans.PropertyValue')
filter.Name='FilterName'
filter.Value='Calc MS Excel 2007 XML'
过滤器=(过滤器,)
#使用filters=()将文件另存为*.ods
document.storeToURL(uno_url,过滤器)
  • 不要忘记终止该过程:
desktop.terminate()
  • 您可以在这里找到我的实现:
  • 祝你好运

如果我开始使用Python通过UNO对LO进行外部控制,并且在运行过程中遇到问题(到目前为止,我一直使用Java),我可能会仔细看一看,特别是题为“通过LibreOffice Python解释器从IDE进行外部控制”的部分“。谢谢Dave,我一直在玩它,但一定没有正确设置环境。”。我可以从LibreOffice内部运行py脚本,但仍然无法使用IDE从外部连接。我想在这一点上,我将走向另一个方向。不幸的是,我认为LO还没有对python的支持。通常Ubuntu不需要这个,但也许你的系统缺少所需的软件包:谢谢Jim,我已经放弃了让它工作的尝试。当我从LibreOffice内部运行脚本时,我可以让python正常工作,但是一旦我尝试使用IDE,就会出现pyuno错误和Com错误。我遵循了文件中的示例,但运气不佳。所有的信息似乎都有点过时了。我找不到任何一个真正能做到这一点的人。嗨,吉姆,我不能就这样放弃工作。我一直在努力,并找到了答案。看看我的解决方案。任何反馈都将不胜感激。