Python UNO (libreoffice):如何为 sheet 启用自动过滤器
Python UNO (libreoffice): How to enable auto filters for a sheet
我有一个创建 CSV 文件的程序。
现在我想使用 Python UNO 脚本,它可以做几件事:
1.) 展开 csv 文件 sheet
2.) 为所有列启用自动筛选
3.) 创建宏并将其添加到文档中
4.) 将文件保存为ODS文件
这个问题只涉及 2.)
1.) 正在工作
for 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"))
提前感谢您的任何反馈
这里是直接使用 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"))
Dispatcher 调用如.uno:DataFilterAutoFilter
很难搞清楚参数。在大多数情况下,最好改用 UNO API 调用,例如 XTextCursor。然而,有几个选项可以找出调度程序调用:
- 使用宏录制器。
- 查看列表,例如 this one。
- 在 LibreOffice 源代码中查找调用。这是最可靠的,但有时仍然难以确定参数。
关于调度程序调用,请参阅 https://forum.openoffice.org/en/forum/viewtopic.php?f=20&t=61127。
是否可以将.ods文件中直接包含的content.xml
修改为python?
我的目标也是在 Windows 10 上在 LibreOffice 中应用自动过滤器。
我找不到任何文档。
但是我发现如果你解压一个.ods文件,在content.xml文件中有下面几行xml
<table:database-ranges>
<table:database-range table:name="__Anonymous_Sheet_DB__0" table:target-range-address="Sheet1.A1:Sheet1.B3" table:display-filter-buttons="true"/>
</table:database-ranges>
有没有办法使用 python 的 lxml 模块读取和修改 content.xml 并以此方式在 LibreOffice 中应用自动过滤器?
我有一个创建 CSV 文件的程序。
现在我想使用 Python UNO 脚本,它可以做几件事:
1.) 展开 csv 文件 sheet
2.) 为所有列启用自动筛选
3.) 创建宏并将其添加到文档中
4.) 将文件保存为ODS文件
这个问题只涉及 2.)
1.) 正在工作
for 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"))
提前感谢您的任何反馈
这里是直接使用 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"))
Dispatcher 调用如.uno:DataFilterAutoFilter
很难搞清楚参数。在大多数情况下,最好改用 UNO API 调用,例如 XTextCursor。然而,有几个选项可以找出调度程序调用:
- 使用宏录制器。
- 查看列表,例如 this one。
- 在 LibreOffice 源代码中查找调用。这是最可靠的,但有时仍然难以确定参数。
关于调度程序调用,请参阅 https://forum.openoffice.org/en/forum/viewtopic.php?f=20&t=61127。
是否可以将.ods文件中直接包含的content.xml
修改为python?
我的目标也是在 Windows 10 上在 LibreOffice 中应用自动过滤器。 我找不到任何文档。
但是我发现如果你解压一个.ods文件,在content.xml文件中有下面几行xml
<table:database-ranges>
<table:database-range table:name="__Anonymous_Sheet_DB__0" table:target-range-address="Sheet1.A1:Sheet1.B3" table:display-filter-buttons="true"/>
</table:database-ranges>
有没有办法使用 python 的 lxml 模块读取和修改 content.xml 并以此方式在 LibreOffice 中应用自动过滤器?