Встраивание Office в Java - PullRequest
10 голосов
/ 19 июля 2010

Я пытаюсь встроить приложение Office 2007/2010 в приложение Java, используя SWT, используя следующий код:

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

Когда я не пытаюсь вызвать 'Open' для объекта документа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)

Кто-нибудь знает, как решить эту проблему или альтернативное решение для встраивания приложений Office в Java?Спасибо!

Обновление:

Запрос идентификаторов для «Open» и «FileName» по отдельности возвращает значение «NULL» для «FileName», поэтому его неверно.Я также пытался без названного параметра без какого-либо успеха:

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

Ответы [ 3 ]

1 голос
/ 19 июля 2010

Почему вы не занимаетесь обработкой ошибок, проверкой результатов или утверждениями?Помните, что getIDsOfNames(..) завершится с ошибкой и вернет значения null для нераспознанных имен.

Попробуйте распечатать значение documents.getLastError() после перехвата исключающего исключения.

0 голосов
/ 22 февраля 2018

Я обновил код для использования 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");
}
}
0 голосов
/ 10 июня 2013

Вам нужно использовать Word.Application, потому что Word.Document не позволит вам использовать функции автоматизации, по крайней мере, это мой опыт.Когда я внедрил автоматизацию и Ole, я сделал это в 2 этапа.

  1. Открытый текстовый документ в режиме автоматизации (Word.Application), некоторые автоматизированные задачи и закрытый
  2. Открытый текстовый документ как Word.DocumentЗадачи автоматизации не работали, но это был объект 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");
    }
}
...