创建一个使用外部Python代码的用户定义函数。

huangapple go评论45阅读模式
英文:

Creating an user-defined function that uses external python code

问题

假设我们有一个在单元格 A1:B5 中包含以下数据的电子表格:

ID	Value
5	10
2	20
5	15
2	25

此外,假设我们有一个Python代码,给定一个名为 df 的pandas数据框,计算:

df.groupby('ID').mean()

是否可能使用此Python代码创建一个用户定义的LibreOffice Calc函数,通过使用Basic来调用Python脚本?谢谢!

英文:

Suppose we have a spreadsheet that, in A1:B5, has the following data:

ID	Value
5	10
2	20
5	15
2	25

Additionally, suppose we have a python code that, given a pandas dataframe df, calculates:

df.groupby('ID').mean()

Is it possible to use this python code to create an user-defined LibreOffice Calc function, by using Basic to call the python script? Thanks!

答案1

得分: 1

首先,如果你想使用一个UDF,那么函数需要以数组形式作为参数。所以公式可能看起来像=A2:B5,将一个二维数组传递给函数。

接下来,有一个调用python-UNO函数的示例在https://stackoverflow.com/questions/37336699/calling-a-python-function-from-within-librecalc。在Linux上这将更容易,因为LibreOffice使用系统范围的Python,可以轻松安装pandas。

在Windows上,一些库可以通过get-pip.py添加到捆绑(而不是系统范围的)Python中,它会安装一个可与LibreOffice一起使用的pip版本。你需要进行实验,看看你需要的库是否可以通过这种方式处理。

如果这不起作用,那么不要导入pandas,看看是否可以编写自己的python-UNO代码来进行计算。我以前用lxml的部分来做过这个。

作为最后的手段,也许你可以使用Basic的Shell语句来调用使用系统范围的Python解释器的脚本。

Shell("python",, "C:/Users/YourUsername/Desktop/yourscript.py")

在执行命令之前,使用Basic将输入写入文件。然后脚本可以处理文件并将输出写入不同的文件。在Basic函数中,等待直到输出文件出现,然后读取文件并从函数返回结果。希望你的UDF不是易失性的,因为更改会导致频繁重新计算,可能会锁定UI,直到它完成。

在Basic中处理文件很繁琐。有实际的Basic方法,如https://help.libreoffice.org/latest/en-US/text/sbasic/shared/03020200.html中所示,但通常使用UNO API中的SimpleFileAccess会更好。

最后一个想法:如果你无法使用Python使其工作,可能在Java中更好,因为与LibreOffice的集成方式不同。然而,Java有两个不足之处——它不容易在多个LibreOffice版本上运行,并且所需的代码稍微复杂一些,特别是使用queryInterface获取特定接口。

英文:

First of all, if you want to use a UDF, then the function would need to take an array of values as the argument. So the formula could look like =A2:B5, giving a two-dimensional array to the function.

Next, an example of calling a python-UNO function is at https://stackoverflow.com/questions/37336699/calling-a-python-function-from-within-librecalc. This will be much easier on Linux than other operating systems, because LibreOffice uses the system-wide python where pandas can easily be installed.

On Windows, some libraries can be added to the bundled (not system-wide) python with get-pip.py, which installs a version of pip that can be used with LibreOffice. You would need to experiment to see whether the libraries you need can be handled this way.

If that doesn't work, then instead of importing pandas, see if it wouldn't be too hard to write your own python-UNO code to do the calculation. I've done this before with parts of lxml.

As a last resort, maybe you could use Basic's Shell statement to call a script using the system-wide python interpreter.

Shell("python",, "C:/Users/YourUsername/Desktop/yourscript.py")

Before executing the command, write the input to a file using Basic. Then the script could process the file and write the output to a different file. Back in the Basic function, sleep until the output file appears, then read the file and return the result from the function. Hopefully your UDF isn't volatile, because changes would cause frequent recalculating, potentially locking the UI until it finishes.

File handling in Basic is a pain. There's the actual Basic way like at https://help.libreoffice.org/latest/en-US/text/sbasic/shared/03020200.html, but using SimpleFileAccess from the UNO API is often better.

One final idea: If you can't get this to work with python, it might be better in Java, because the integration with LibreOffice works differently. There are two downsides to Java, however — it isn't as easy to get it to work across multiple versions of LibreOffice, and the code required is a bit more complex, especially obtaining specific interfaces with queryInterface.

huangapple
  • 本文由 发表于 2023年7月24日 18:57:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/76753797.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定