2017-01-11 2 views
1

У меня есть программа, которая создает файл CSV.Python UNO (libreoffice): Как включить авто фильтры для листа

Теперь я хотел бы использовать Python UNO сценарий, который должен сделать несколько вещей:

1.) открыть файл CSV в электронной таблице

2.) включить автоматический фильтр для всех столбцов

3.) создать макрос и добавить его в документ

4.) сохраните файл как файл ODS

Этот вопрос касается только 2.)

1.) работает

за 3.) я, наверное, создать еще один вопрос 1.) работает (с pyoo и с unotools)

Мои шаги:

I запуск вручную:

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

Мой питон скрипт:

С 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, но Basic в порядке. Макрос будет довольно простым. – 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 трудно выяснить параметры. В большинстве случаев лучше использовать вызовы API UNO, такие как 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

Смежные вопросы