2017-01-11 175 views
1

我有一個程序,它創建一個CSV文件。Python UNO(libreoffice):如何爲表單啓用自動過濾器

現在,我想用一個Python腳本UNO,這將做幾件事情:

1)在電子表格

2)打開CSV文件,使所有列的自動過濾

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")) 

預先感謝任何反饋

+0

想到你的下一個問題,步驟3中的宏是否會用Basic或Python編寫? –

+0

也可以。偏愛Python,但基本沒問題。這個宏將是一些相當基本的東西。 – gelonida

+0

Obe更多評論。 如果我可以執行第3步然後執行宏,那麼宏可以執行設置自動過濾器。 不是很優雅,但也是一個潛在的解決方案。 – gelonida

回答

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

+0

非常感謝。它工作,如果我做一個小的修改您的腳本: 看來, 'fileUrl = uno.systemPathToFileUrl(文件路徑)' 失敗,如果它獲得了一個相對路徑名傳遞。 如果我添加 '進口os' 在文件的開頭,寫 'fileUrl = uno.systemPathToFileUrl(os.path.realpath(文件路徑))' 你的腳本工作。 有沒有什麼好的方法(文檔頁面)來查看所有可以使用UNO執行的操作? 猜測字符串「.uno:DataFilterAutoFilter」,並猜測它的參數是棘手的,是我的主要問題找到答案, – gelonida

+0

嗯,我確實有'os.path.realpath'在那裏最初,但拿出來使代碼短。顯然它畢竟是必要的。我編輯了包含代碼的答案,並解釋了調度程序調用。 –

+0

完美。再次感謝 – gelonida

相關問題