Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Embedding Office in Java

I'm trying to get Office 2007/2010 application embedded inside a Java application using SWT using the following code:

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]);
    }
}

When I don't try to call 'Open' on the document object Word embeds successfully inside the application but the whole file menu is disabled. When I call 'Open' the application crashes with the following error (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)

Does anyone know how to fix this problem or an alternative solution to embed Office apps in Java? Thanks!



Update:

Querying the IDs for 'Open' and 'FileName' separately returns null for 'FileName' so its incorrect. I've also tried without the named parameter without any success:

documents.invokeNoReply(automationIDs[0], arguments);
like image 791
Luke Quinane Avatar asked Jul 19 '10 04:07

Luke Quinane


1 Answers

Why aren't you doing any error handling, result checking, or assertions? Remember that getIDsOfNames(..) will silently fail and return null values for unrecognized names.

Try printing the value ofdocuments.getLastError() after catching the offending exception.

like image 161
Gunslinger47 Avatar answered Oct 23 '22 16:10

Gunslinger47