微软Excel宏运行Java程序

12

我已经学会使用Jxl和POI API编写Java程序读写Excel文件。是否可以使用宏来帮助运行Java程序?


2
请查看此链接 - [https://dev59.com/RlXTa4cB1Zd3GeqPzTE1][1] - Sree
所有这些讨论都表明这是不可能的。 - Nimit_ZZ
这个怎么样?http://stackoverflow.com/questions/10879757/vba-shell-java-call-errors - JimmyPena
是的,它是使用Jinx实现的 - https://exceljava.com。您可以使用Java编写Excel函数(UDFs)、宏和菜单。 - Tony Roberts
4个回答

24
是的,这是可能的。
实际上有很多种方法,希望您会喜欢我的例子。
为了演示这一点,我创建了一个程序,其中一些文本作为参数发送,程序将以修改后的版本响应。我制作了一个可运行的jar文件。第一个例子从args中读取参数,另一个从标准输入中读取参数。
文件Hello.java和H1.jar:
public class Hello {
    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder("Hello");
        
        if (args.length > 0) 
            sb.append(' ').append(args[0]);
        System.out.println(sb.append('.').toString());
    }
}

文件 Hello2.javaH2.jar:

import java.util.Scanner;

public class Hello2 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        StringBuilder sb = new StringBuilder("Hello");
        
        sb.append(' ').append(sc.nextLine());
        System.out.println(sb.append('.').toString());
    }
}

你可以将它们保存在一个JAR文件中,但是这样你需要创建并使用清单(这有点过头了)。

现在在Excel中,我添加一个模块和对Windows脚本主机对象的引用。如果你不喜欢sleep,那么你可以用DoEvents替换它:

'add a reference to Windows Script Host Object Model
'for example : Tools-References
Option Explicit
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

Private Sub RunSleep( _
    exec As WshExec, _
    Optional timeSegment As Long = 20 _
)
    Do While exec.Status = WshRunning
        Sleep timeSegment
    Loop
End Sub

Private Function RunProgram( _
    program As String, _
    Optional command As String = "" _
) As WshExec
    Dim wsh As New WshShell
    Dim exec As WshExec

    Set exec = wsh.exec(program)
    Call exec.StdIn.WriteLine(command)
    Call RunSleep(exec)
    Set RunProgram = exec
End Function

为了测试它,我将文件保存到 c:\ 驱动器并使用以下代码:

Public Sub Run()
    Dim program As WshExec
    Set program = RunProgram("java -jar ""C:\\H1.jar"" Margus")
    Debug.Print "STDOUT: " & program.StdOut.ReadAll

    Set program = RunProgram("java -jar ""C:\\H2.jar", "Margus")
    Debug.Print "STDOUT: " & program.StdOut.ReadAll
End Sub

在我的情况下,我得到了以下的回应:

STDOUT: 你好 Margus。

STDOUT: 你好 Margus。


1
请注意,变量program保存了额外有用的信息,如错误流和返回代码。 - Margus
1
@sreehari 我的疑问是,我已经编写了一个程序,可以从现有的Excel文件中读取单元格数据并进行处理,然后将其放回到同一文件中。我对Java并不陌生,但对于Excel宏确实是新手。我需要编写宏吗?我对此一无所知,而且教程也没有提供任何信息。那么该怎么做呢? - Nimit_ZZ
1
要在Excel中打开VBA环境,您可以使用“alt + f11”。另一种方法是使用开发人员选项卡中的Visual Basic按钮。Excel为每个工作表都有代码页,但模块就像共享空间。请注意,我可以使用命令java -jar "C:\H1.jar" Margus在CMD中运行程序 - 需要编写的代码非常少。 - Margus
好的。我认为我没有表达清楚我的疑问。我编写Java文件并将其保存在一个特定的位置。我打开Excel表格,在单元格中输入一些内容,然后我想获取这些单元格中的内容,进行处理,并将其放回到同一Excel表格中,而这个数据处理过程必须由Java程序完成。这是否可以通过Excel宏实现?我尝试了__ikvm__,但是它导致了更多的死胡同。 - Nimit_ZZ

3
我已经使用过它了。请注意,使用javaw,否则会弹出一个黑色窗口。
Dim result As String
Dim commandstr As String

commandstr = "javaw -jar somejar someparameter"


' try with or without cast to string
result = CStr( shellRun(commandstr) )


'somewhere from SO but forget.. sorry for missing credits

Public Function ShellRun(sCmd As String) As String

    'Run a shell command, returning the output as a string'

    Dim oShell As Object
    Set oShell = CreateObject("WScript.Shell")

    'run command'
    Dim oExec As Object
    Dim oOutput As Object
    Set oExec = oShell.exec(sCmd)
    Set oOutput = oExec.StdOut

    'handle the results as they are written to and read from the StdOut object'
    Dim s As String
    Dim sLine As String
    While Not oOutput.AtEndOfStream
        sLine = oOutput.ReadLine
        If sLine <> "" Then s = s & sLine & vbCrLf
    Wend

    ShellRun = s

End Function

问题是编写一个Java程序。 - user7294900
1
谢谢您的评论,但问题是“是否可以通过宏来运行Java程序?”这个解决方案不需要使用sleep方法,并且我指向了javaw而不是java。 - mschwehl

3

您的VBA可以将输出写入文件,Java可以定期轮询文件修改并从文件中读取数据。然后通过另一个文件将数据写回VBA。除非您只想通过System.execute(...)从shell中启动Java程序,否则实现VBA-Java集成几乎不可能。


不是真的。VBA-Java集成并不是不可能的。一段时间以前,甚至还有过好老的Sun Java ActiveX Bridge,但不幸的是,它已经被Oracle停止了(仍然可用于Java 1.4:http://docs.oracle.com/javase/1.4.2/docs/guide/beans/axbridge/developerguide/)。但仍然有可用的技术。Obba http://www.obba.info可以从VBA中使用。还可以使用xlloop。 - Christian Fries

0
比其他建议的解决方案更好的方法是使用 Jinx(https://exceljava.com)在 Java 中创建 Excel Add-In。
有关如何在 Java 中编写 Excel 宏的详细信息,请参见 https://exceljava.com/docs/macros.html
除了宏之外,还可以编写用户定义的函数和菜单。
实际上,您可以使用 Java 作为 VBA 的完全替代品!请参见 https://github.com/exceljava/jinx-com4j,了解如何调用 Excel 对象模型,以允许您从 Java 中执行与 VBA 相同的所有操作。

这个工具有两个缺点——它是收费的,而且不支持MacOS(只支持Windows)。 - lagivan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接