首页 文章

Python UNO(libreoffice):如何为工作表启用自动过滤器

提问于
浏览
1

我有一个程序,可以创建一个CSV文件 .

现在我想使用Python UNO脚本,它将执行以下几项操作:

1.)在电子表格中打开csv文件

2.)为所有列启用自动筛选

3.)创建一个宏并将其添加到文档中

4.)将文件保存为ODS文件

这个问题只涉及2.)

1.)正在工作

对于3.)我可能会创建另一个问题1.)正在工作(与pyoo和unotools)

我到目前为止的步骤:

我手动开始:

libreoffice --accept='socket,host=localhost,port=2202;urp;' --norestore --nologo --nodefault

我的python脚本:

用pyoo

import pyoo
# Step 0) connect to UNO bridge
desktop = pyoo.Desktop('localhost', 2002)

# Step 1) open the doc and get the sheet
# This works only if the field separator is a comma.
# I don't know how for example to specify tab as separator instead
doc = desktop.open_spreadsheet('tst.csv')
# I see the spreadsheet opening
sheet = doc.sheets[0] # I get an object of type Sheet

# Step2) set autofilter for active sheet
# no idea how to do

# Step3) create a macro and add it to the document
# no idea how to do but will create another question as 
# soon as step2 is solved

# Step 4) save the sheet
doc.save("tst_pyoo.ods")

或者用unotools

import unotools
from unotools.component.calc import Calc
from unotools.unohelper import convert_path_to_url

# Step 0) connect to UNO bridge
context = unotools.connect(unotools.Socket('localhost', 2002))

# Step 1) open document
doc = Calc(ctx, convert_path_to_url('tst.csv')
# I see the spreadsheet opening
sheet = doc.get_sheet_by_index(0)
# I get an object of type unotools.component.calc.Spreadsheet

# Step2) set autofilter for active sheet
# no idea how to do

# Step3) create a macro and add it to the document
# no idea how to do but will create another question as 
# soon as step2 is solved

# Step 4)
doc.store_to_url(convert_path_to_url("tst_unotools.ods"))

提前感谢您的任何反馈

1 回答

  • 0

    这是使用直接PyUNO而不是包装器库的代码 . 它改编自http://www.imaccanici.org/en.libreofficeforum.org/node/5413.html .

    import os
    import uno
    
    class UnoObjs:
        "Initializes and stores UNO objects to connect to a document."""
        def __init__(self, filepath=None):
            localContext = uno.getComponentContext()
            resolver = localContext.ServiceManager.createInstanceWithContext(
                "com.sun.star.bridge.UnoUrlResolver", localContext )
            self.ctx = resolver.resolve(
                "uno:socket,host=localhost,port=2002;urp;"
                "StarOffice.ComponentContext")
            self.smgr = self.ctx.ServiceManager
            desktop = self.smgr.createInstanceWithContext(
                "com.sun.star.frame.Desktop", self.ctx)
            if filepath:
                fileUrl = uno.systemPathToFileUrl(os.path.realpath(filepath))
                self.document = desktop.loadComponentFromURL(
                    fileUrl, "_default", 0, ())
            else:
                self.document = desktop.getCurrentComponent()
    
    def add_autofilter(unoObjs):
        """This adds an autofilter by selecting only the filled spreadsheet area. 
        NOTE: If any cell in the header row of the selection is empty this will
        trigger a popup for interactive user action (must click Yes for the
        Autofilter column header message box)
        """
        dispatcher = unoObjs.smgr.createInstanceWithContext(
            "com.sun.star.frame.DispatchHelper", unoObjs.ctx)
        controller = unoObjs.document.getCurrentController()
        sheet = unoObjs.document.getSheets().getByIndex(0)
        # select a sufficiently big "guess" area, hopefully
        guessRange = sheet.getCellRangeByPosition(0, 0, 150, 10000)
        # look up the actual used area within the guess area
        cursor = sheet.createCursorByRange(guessRange)
        cursor.gotoEndOfUsedArea(False)
        lastcol = cursor.RangeAddress.EndColumn
        lastrow = cursor.RangeAddress.EndRow
        # select the filled part of the spreadsheet
        actualRange = sheet.getCellRangeByPosition(0, 0, lastcol, lastrow)
        controller.select(actualRange)
        # add autofilter
        dispatcher.executeDispatch(
            unoObjs.document.getCurrentController(), ".uno:DataFilterAutoFilter",
            "", 0, ())
    
    add_autofilter(UnoObjs("tst.csv"))
    

    诸如 .uno:DataFilterAutoFilter 之类的调度程序调用很难找出参数 . 在大多数情况下,最好使用UNO API调用,例如XTextCursor . 但是,有一些选项可以找出调度程序调用:

    • 使用宏录制器 .

    • 查看类似this one的列表 .

    • 在LibreOffice源代码中查找调用 . 这是最可靠的,但有时仍然难以确定参数 .

    关于调度程序调用,请参阅https://forum.openoffice.org/en/forum/viewtopic.php?f=20&t=61127 .

相关问题