基础知识

Java调用微软com组件

2019-01-18  本文已影响87人  do_young

背景

在一些企业级的JAVA应用开发中,需要对微软的office文档进行处理。比如:

jacob简介

什么是jacob

官方对jacob组件的说明如下:

JACOB is a JAVA-COM Bridge that allows you to call COM Automation components from Java. 
It uses JNI to make native calls into the COM and Win32 libraries. 
The JACOB project started in 1999 and is being actively used by thousands of developers worldwide.
 As an open-source project, it has benefitted from the combined experience of these users, many of whom have made modifications to the code and submitted them back for inclusion in the project.

它把其技术组件的技术实现原理说得比较明白了,我用自己的理解说明一下。微软为office文档的操作提供了com组件,jacob就是通过自己编写的DLL(动态连接库)对office的com组件进行调用,并且提供java组件通过JNI对DLL进行调用,最终使用对office文件的操作。
下面具体说明一下jacob的使用。

运行环境安装

前置条件

要实现jacob组件对office文档的操作,首先需要安装office。也就是说需要在windows环境下运行(注:mac上可以安装office,但一般不会将一些应用部署在mac系统上,所以没有验证过该方式是否可行,也没有验证的意义。_!
网上也有说明可以通过Wine将office安装在Linux系统上,但因为有兼容问题,考虑到使用不稳定的因素,也没有进行尝试。待有需求的时候,再做尝试。)

安装DLL

因为我们是java程序,所以首先得安装JDK或JRE。
安装完成以后,下载jacob组件。将压缩包中的jacob-xxx.dll文件到系统环境变量目录中
一般情况就放在jdk或jre的bin目录下。

搭建开发环境

在工程中导入jacob组件中的java组件包jacob.jar

基于jacob开发

组件初始化

ComThread.InitSTA();
ActiveXComponent activexComponent = new ActiveXComponent("XX.Application");

其中ActiveXComponent类的构造函数中的参数可以是:

执行指令

组件初始化完成以后就可以使用Dispatch.call,将对文件做操作了:

Dispatch.call(activexComponent,......)

比如打开一个project文件:

Dispatch.call(activexComponent, "FileOpen", new Object[] { mpxFilePath });

基本上对office文档的处理都是通过Dispatch.call方法来执行,返回一个句柄对象,再将句柄对象作为参数传给下一个Dispatch.call调用执行。
下面问题来了,我怎么知道我要对文档操作对应的指令是什么呢?比如上面的例子中打开文件的指令是FileOpen呢?办法就是打开office软件录制宏,下面为一段文件另存操作所录制的宏脚本:

Sub Macro11()
' 宏 Macro11
    FileSaveAs Name:="C:\Users\ab053045\Documents\xxxx.mpp", FormatID:="MSProject.MPP"
End Sub

其中的文件另存为的指令为FileSaveAs,指令需要传入两个参数,一个参数Name为文件名称,另一个参数FormatID为文件格式。但其中的参数还有哪些指令,哪些指令又是必填项和可选项呢?
这就需要引入office的参考文档了,开发office宏指令的开发文档

images.png

在文档的标题筛选框中输入指令名称,就可以查看指令的详细说明。

例子

大家都知道有一个组件MPXJ可以对Office的文件进行操作,但因为mpp文件的格式并没有对外公开,所以该组件的运维人员只能根据文件流的规律来封装。这不免无法提供全部的功能,也会对mpp文件的格式兼容性无法满足。比如:如果我的计划是基于最新的Office的Project软件编辑的,而且是mpx格式,那怎么办呢?
这里给出的一种解决方案就是使用Jacob打开这个文件,使用另存为指令,将该文件保存为mpp格式,后面就可以使用mpxj组件来读取该文件了。
下面是将mpx文件另存为mpp文件的代码,可以参照一下:

    /**
     * @param mpxFilePath
     *            mpx文件的文件路径包括文件名和文件后缀 转换执行成功,会在同文件夹下创建同文件名的mpp文件; 如:入参是
     *            C:\project\test-kjdp.mpx 成功转换后会在输出 C:\project\test-kjdp.mpp
     */
    public static boolean convertMpxToMpp(String mpxFilePath) {
        if ((StringUtils.isEmpty(mpxFilePath)) || (mpxFilePath.length() < 5)) {
            return false;
        }
        ActiveXComponent activexComponent = null;
        try {
            ComThread.InitSTA();
            activexComponent = new ActiveXComponent("MsProject.Application");
            Variant localVariant = activexComponent.getProperty("Version");
            activexComponent.setProperty("Visible", new Variant(false));
            activexComponent.setProperty("DisplayAlerts", new Variant(false));
            Dispatch.call(activexComponent, "FileOpen", new Object[] { mpxFilePath });
            Dispatch.call(activexComponent, "FileSaveAs", new Object[] { mpxFilePath.substring(0, mpxFilePath.length() - 4) + ".mpp" });
        } catch (Error error) {
            error.printStackTrace();
        } catch (Exception exception) {
            exception.printStackTrace();
        } finally {
            if (activexComponent != null) {
                Dispatch.call(activexComponent, "Quit", new Object[] { Integer.valueOf(0) });
            }
            ComThread.Release();
        }
        return true;
    }

上一篇下一篇

猜你喜欢

热点阅读