自动化的“公式”在Libreoffice通过Uno在Python
我经常从外部来源(通过Google文档)收到电子表格,必须转换为本地(专有)格式。为此,我编写了一个可以将电子表格作为ODS文件转换为所需格式(非ods)的脚本。 该脚本需要与许多高级业务特定的PHP东西进行交互,因此我将phpspreadsheet用于此目的( https://github.com/phpoffice/phpspreadsheet/ )。
从理论上讲,这个PHP库可以完成我需要的所有内容,但是它无法处理过度复杂的电子表格,而无需花费大量时间处理所有交叉引用公式。为了加快脚本中的处理,我通过将所有公式转换为值(选择所需纸张中的所有单元格,然后触发[data]> [计算]> [公式]将所有公式手动准备ODS文件))))在所需的床单中。然后,我删除所有不需要的床单(否则仅包含替换配方的源数据)。结果文件小得多,不包含任何公式。通过简化的电子表格文件,PHP脚本的执行在几秒钟内完成,而原始电子表格文件很长一段时间后将其耗尽。
我现在寻求使用新的Python脚本将所有公式转换为值的过程自动化(这需要在Linux服务器上发生,因此我最好的选择是通过Python的UNO插座控制的无头libreoffice,正确吗?)。 到目前为止Star/Sheet/Module-ix.html“ RER =“ Nofollow Noreferrer”> https://www.openoffice.org/api/pi/docs/common/common/ref/ref/ref/sun/sun/sun/sun/sun/sheet/sheet/mmodule-module-ix.html )。 我目前的大问题是:
如何通过python中的uno api立即访问表格上的所有单元格上的ui- 函数?
我尝试过在搜索旧的OpenOffice API文档中为此暂时,但是到目前为止,我还找不到我想要的东西。
目前,Python脚本(本质上)看起来像这样:
import uno
localContext = uno.getComponentContext()
resolver = localContext.ServiceManager.createInstanceWithContext(
"com.sun.star.bridge.UnoUrlResolver",
localContext
)
context = resolver.resolve("uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext")
serviceManager = context.ServiceManager
desktop = serviceManager.createInstanceWithContext("com.sun.star.frame.Desktop", context)
# com.sun.star.lang.XComponent / com.sun.star.sheet.SpreadsheetDocument
document = desktop.getCurrentComponent()
# com.sun.star.sheet.XSpreadsheets / XNameAccess
sheets = document.getSheets()
# com.sun.star.sheet.XSpreadsheet
# https://www.openoffice.org/api/docs/common/ref/com/sun/star/sheet/XSpreadsheet.html
sheet = sheets.getByName('OneOfTheSheets')
#print(sheet.getCellRangeByName("A1:AP1000"))
# WAY TOO SLOW AND DESTRUCTIVE:
for row in range(0, 1000):
for column in range(0, 42):
cell = sheet.getCellByPosition(column, row)
cell.setFormula(cell.getString())
谢谢您提供的任何帮助。
I am regularly receiving a spreadsheet from an external source (via google docs) that I have to convert into a local (kinda proprietary) format. To do that, I have written a script that can convert the spreadsheet as an ODS file into the needed format (non-ODS).
This script needs to interact with a lot of higher-level business-specific PHP stuff, so I use PhpSpreadsheet for this purpose (https://github.com/PHPOffice/PhpSpreadsheet/).
This PHP library does theoretically everything I need, but it cannot deal with overly complex spreadsheets without taking an gigantic amount of time dealing with all the cross-referencing formulas. To speed up the processing in the script, I manually prepare the ODS file by hand by converting all formulas to values (Select all Cells in the needed Sheets, then trigger [Data] > [Calculate] > [Formula to Value]) in the needed sheets. Then I delete all the unneeded sheets (which otherwise only contain source-data for the replaced formulas). The resulting file is a lot smaller and does not contain any formulas. The execution of the PHP script finishes within a few seconds with the simplified spreadsheet file, while it runs out of memory after a long while with the original spreadsheet file.
I now seek to automate this process of converting all the formulas to values using a new python script (This needs to happen on a linux server, so my best bet would be a headless libreoffice controlled via an UNO socket in python, correct?).
So far I have managed to connect to the libreoffice UNO socket and manipulate the cells via the old OpenOffice-API (https://www.openoffice.org/api/docs/common/ref/com/sun/star/sheet/module-ix.html).
My current big question is:
How do I access the UI-Formula to Value
-functionality on all cells of a sheet at once via the UNO API in Python?
I have tried searching the old OpenOffice API documentation for this for a while, but so far I cannot find what I am looking for.
Currently the python script looks (in essence) like this:
import uno
localContext = uno.getComponentContext()
resolver = localContext.ServiceManager.createInstanceWithContext(
"com.sun.star.bridge.UnoUrlResolver",
localContext
)
context = resolver.resolve("uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext")
serviceManager = context.ServiceManager
desktop = serviceManager.createInstanceWithContext("com.sun.star.frame.Desktop", context)
# com.sun.star.lang.XComponent / com.sun.star.sheet.SpreadsheetDocument
document = desktop.getCurrentComponent()
# com.sun.star.sheet.XSpreadsheets / XNameAccess
sheets = document.getSheets()
# com.sun.star.sheet.XSpreadsheet
# https://www.openoffice.org/api/docs/common/ref/com/sun/star/sheet/XSpreadsheet.html
sheet = sheets.getByName('OneOfTheSheets')
#print(sheet.getCellRangeByName("A1:AP1000"))
# WAY TOO SLOW AND DESTRUCTIVE:
for row in range(0, 1000):
for column in range(0, 42):
cell = sheet.getCellByPosition(column, row)
cell.setFormula(cell.getString())
Thank you for any help you can provide.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论