如何让 LibreOffice 无头 Calc 计算以保存 uno 的新值?

Posted

技术标签:

【中文标题】如何让 LibreOffice 无头 Calc 计算以保存 uno 的新值?【英文标题】:How to get LibreOffice headless Calc calculate to save new values from uno? 【发布时间】:2019-11-20 14:43:55 【问题描述】:

我正在尝试从 python 打开一个 excel 文件,让它重新计算,然后用新计算的值保存它。 电子表格很大,可以在带有 GUI 的 LibreOffice 中正常打开,并且最初显示旧值。如果我然后执行 Data->Calculate->Recalculate Hard 我会看到正确的值,我当然可以保存,一切看起来都很好。 但是,我想要使用多个大型电子表格,所以我不想使用 GUI,而是想使用 Python。以下所有内容似乎都可以创建一个新的电子表格,但它没有新值(除非我再次手动重新计算)

我在 Linux 上运行。首先我这样做:

soffice  --headless --nologo --nofirststartwizard --accept="socket,host=0.0.0.0,port=8100,tcpNoDelay=1;urp"

然后,这里是示例 python 代码:

import uno

local = uno.getComponentContext()
resolver = local.ServiceManager.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", local)
context = resolver.resolve("uno:socket,host=localhost,port=8100;urp;StarOffice.ServiceManager")
remoteContext = context.getPropertyValue("DefaultContext")
desktop = context.createInstanceWithContext("com.sun.star.frame.Desktop", remoteContext)
document = desktop.getCurrentComponent()


file_url="file://foo.xlsx"
document = desktop.loadComponentFromURL(file_url, "_blank", 0, ())

controller=document.getCurrentController()

sheet=document.getSheets().getByIndex(0)
controller.setActiveSheet(sheet)
document.calculateAll()

file__out_url="file://foo_out.xlsx"
from com.sun.star.beans import PropertyValue
pv_filtername = PropertyValue()                                             
pv_filtername.Name = "FilterName"                                           
pv_filtername.Value = "Calc MS Excel 2007 XML"                                             

document.storeAsURL(file__out_url, (pv_filtername,))
document.dispose()

运行上述代码并打开 foo_out.xlsx 后,它会显示“旧”值,而不是重新计算的值。我知道 calculateAll() 需要一点时间,因为我希望它会重新计算。但是,新值似乎并没有真正得到保存。 如果我在 Excel 中打开它,它会自动重新计算并显示正确的值,如果我在 LibreOffice 中打开并重新计算,它会显示正确的值。但是,我需要从上面的 python 中保存它,以便它已经包含重新计算的值。

有什么办法吗?

基本上,我想从 python 做的是: 打开,重新计算,另存为

【问题讨论】:

AOO 论坛中建议的一种方法是使用CopyPaste Special 将公式替换为计算值。当然,您必须计算出 UNO 的详细信息。 |Solved| Replace formula with value calculated 这似乎是摆脱公式的解决方案。我不想那样做。我只想存储当前值,这样我就不必重新计算。而且,电子表格可以用 pandas 读取。目前,pandas 只读取“旧”值。 【参考方案1】:

这似乎是旧版 LibreOffice 的问题。我在 Linux 上使用的是 5.0.6.2,即使我在重新计算,当我直接提取单元格值时,新值甚至都没有出现。 但是,我升级到 6.2,问题就消失了,使用相同的代码和相同的输入文件。 我决定只回答我自己的问题,而不是删除它,因为这会导致我很沮丧,直到我解决它。

【讨论】:

以上是关于如何让 LibreOffice 无头 Calc 计算以保存 uno 的新值?的主要内容,如果未能解决你的问题,请参考以下文章

LibreOffice Calc / OpenOffice Calc / Excel:如何显示负持续时间?

如何通过 LibreOffice 的 Calc 中的正则表达式语句捕获公司名称

LibreOffice Calc 单元格文本

如何在 LibreOffice Calc 中交换两个单元格

LibreOffice (Calc) VBA 单元格总和(按索引)

如何将引用另一列的函数添加到 libreoffice-calc?