【问题标题】:Embedding Office in Java在 Java 中嵌入 Office
【发布时间】:2011-03-17 18:03:43
【问题描述】:

我正在尝试使用以下代码使用 SWT 将 Office 2007/2010 应用程序嵌入到 Java 应用程序中:

import java.awt.Canvas;
import javax.swing.JFrame;

import org.eclipse.swt.SWT;
import org.eclipse.swt.awt.SWT_AWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.ole.win32.*;
import org.eclipse.swt.widgets.*;

public class EmbeddingTest extends Canvas {
    private void initOleViewer(String target) {
        Display display = new Display();
        Shell shell = SWT_AWT.new_Shell(display, this);
        shell.setLayout(new FillLayout());

        OleFrame oleFrame = new OleFrame(shell, SWT.NONE);

        OleControlSite oleControlSite = new OleControlSite(oleFrame, SWT.NONE, "Word.Document");
        oleControlSite.doVerb(OLE.OLEIVERB_INPLACEACTIVATE);

        OleAutomation word = new OleAutomation(oleControlSite);

        int[] applicationId = word.getIDsOfNames(new String[]{"Application"});
        Variant property = word.getProperty(applicationId[0]);
        OleAutomation application = property.getAutomation();

        int[] documentId = application.getIDsOfNames(new String[]{"Documents"});            
        property = application.getProperty(documentId[0]);
        OleAutomation documents = property.getAutomation();

        shell.open();
        Variant[] arguments = new Variant[] { new Variant(target) };
        int[] automationIDs = documents.getIDsOfNames(new String[]{"Open", "FileName"});
        documents.invokeNoReply(automationIDs[0], arguments, new int[]{automationIDs[1]});

        while (!shell.isDisposed()) {
            if (!display.readAndDispatch()) {
                display.sleep();
            }
        }
    }

    public static void main(String[] args) {
        JFrame jFrame = new JFrame("Embedding Test");
        jFrame.setVisible(true);

        EmbeddingTest viewer = new EmbeddingTest();
        jFrame.add(viewer);
        jFrame.setSize(600, 600);

        viewer.initOleViewer(args[0]);
    }
}

当我不尝试在文档对象上调用“打开”时,Word 成功嵌入到应用程序中,但整个文件菜单被禁用。当我调用“打开”时,应用程序崩溃并出现以下错误 (DISP_E_EXCEPTION):

Exception in thread "main" org.eclipse.swt.SWTException: Action can not be performed. result = -2147352567
 at org.eclipse.swt.ole.win32.OLE.error(Unknown Source)
 at org.eclipse.swt.ole.win32.OleAutomation.invokeNoReply(Unknown Source)
 at EmbeddingTest.initOleViewer(EmbeddingTest.java:68)
 at EmbeddingTest.main(EmbeddingTest.java:88)

有谁知道如何解决此问题或在 Java 中嵌入 Office 应用程序的替代解决方案?谢谢!



更新:

查询“打开”和“文件名”的 ID 分别为“文件名”返回 null,因此它不正确。我也试过没有命名参数但没有任何成功:

documents.invokeNoReply(automationIDs[0], arguments);

【问题讨论】:

  • 看起来赏金即将到期。抱歉,我帮不上什么忙。
  • @Gunslinger47 无论如何谢谢!至少你有三倍的人来看它。 :)

标签: java ms-office swt embed


【解决方案1】:

您为什么不进行任何错误处理、结果检查或断言?请记住,getIDsOfNames(..) 将静默失败并为无法识别的名称返回 null 值。

在捕获违规异常后尝试打印documents.getLastError() 的值。

【讨论】:

  • 'FileName' 似乎是个问题,因为它返回的 ID 为 0。但 documents.getLastError() 只返回 null。
  • @Luke:文档说它应该是null,以防出现错误,所以文件名 ID 仍然可能是正确的。也许表明它是第 0 个参数?说到文档,你有Word.Document 规范的链接吗?
  • 这是我一直在查看的文档:msdn.microsoft.com/en-us/library/bb216319(office.12).aspx
  • 我想知道为什么Format 在有未使用的代码示例时被列为“必需”?无论如何,@Luke,您使用的是绝对路径还是相对路径?它可能很简单,例如找不到文件,甚至可能是不受支持的文件类型或损坏的文件。
【解决方案2】:

你需要使用 Word.Application,因为 Word.Document 不会让你使用自动化功能,至少这是我的经验。当我实现自动化和 Ole 时,我分两步完成。

  1. 以自动化模式 (Word.Application) 打开 word 文档,完成一些自动化任务并关闭
  2. 以 Word.Document 格式打开 Word 文档。自动化任务不起作用,但它是一个 OLE 对象。用户可以编辑文档,但保存选项被禁用。但是,您可以添加额外的菜单并执行 Ole.Save 之类的操作。然后可以进一步处理捕获的文档。

在这里您可以找到如何在 Word.Application 中打开文档的示例。 然后根据我的经验,您应该将其保存并在 OLE 中以 Word.Document 的形式打开。 显示 Word.Application 可以跳过。

import java.awt.Canvas;
import javax.swing.JFrame;

import org.eclipse.swt.SWT;
import org.eclipse.swt.ole.win32.*;
import org.eclipse.swt.widgets.*;

public class EmbeddingTest extends Canvas {

    private void initOleViewer(String target) {
        Display display = new Display();
        Shell shell = new Shell(display);
        OleFrame oleFrame = new OleFrame(shell, SWT.NONE);
        OleClientSite oleClientSite = new OleClientSite(oleFrame, SWT.NONE, "Word.Application");
        OleAutomation word = new OleAutomation(oleClientSite);



    Variant[] arguments;


    //open the file
    int[] id1 = word.getIDsOfNames(new String[]{"Documents"});
    Variant pVarResult = word.getProperty(id1[0]);
    OleAutomation resultDocuments = pVarResult.getAutomation();

    int[] id2 = resultDocuments.getIDsOfNames(new String[]{"Open"});

    arguments = new Variant[1];
    arguments[0] = new Variant(target);
    Variant invokeResult = resultDocuments.invoke(id2[0], arguments);

    resultDocuments.getIDsOfNames(new String[]{"ActiveDocument"});


     //show the word app, not necessary        
    arguments=new Variant[1];
    arguments[0] = new Variant(true);
    int[] id3 = word.getIDsOfNames(new String[]{"Visible"});
    word.setProperty(id3[0], arguments); 


        while (!shell.isDisposed()) {
            if (!display.readAndDispatch()) {
                display.sleep();
            }
        }
    }

    public static void main(String[] args) {
        JFrame jFrame = new JFrame("Embedding Test");
        jFrame.setVisible(true);

        EmbeddingTest viewer = new EmbeddingTest();
        jFrame.add(viewer);
        jFrame.setSize(600, 600);

        viewer.initOleViewer("d:\\aaa.doc");
    }
}

【讨论】:

    【解决方案3】:

    我已更新代码以使用 OleClientSite 而不是 OleControlSite,它适用于我。

    package com.test.swt;
    
    import java.awt.Canvas;
    import java.io.File;
    
    import javax.swing.JFrame;
    
    import org.eclipse.swt.SWT;
    import org.eclipse.swt.awt.SWT_AWT;
    import org.eclipse.swt.layout.FillLayout;
    import org.eclipse.swt.ole.win32.OLE;
    import org.eclipse.swt.ole.win32.OleClientSite;
    import org.eclipse.swt.ole.win32.OleFrame;
    import org.eclipse.swt.widgets.Display;
    import org.eclipse.swt.widgets.Shell;
    
    public class EmbeddingTest extends Canvas {
    private static final long serialVersionUID = 1L;
    
    public void initOleViewer(String target) {
        Display display = new Display();
        Shell shell = SWT_AWT.new_Shell(display, this);
        shell.setLayout(new FillLayout());
    
        OleFrame oleFrame = new OleFrame(shell, SWT.NONE);
    
        OleClientSite oleControlSite = new OleClientSite(oleFrame, SWT.NONE, "Word.Document", new File(target));
        oleControlSite.doVerb(OLE.OLEIVERB_INPLACEACTIVATE);
        shell.setSize(800, 600);
        shell.open();
        while (!shell.isDisposed()) {
            if (!display.readAndDispatch()) {
                display.sleep();
            }
        }
    }
    
    public static void main(String[] args) {
        JFrame jFrame = new JFrame("Embedding Test");
        jFrame.setVisible(true);
    
        EmbeddingTest viewer = new EmbeddingTest();
        jFrame.add(viewer);
        jFrame.setSize(600, 600);
    
        viewer.initOleViewer("C:\\Users\\test.docx");
    }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-12-13
      • 2015-09-17
      • 1970-01-01
      • 1970-01-01
      • 2010-12-06
      • 2016-08-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多