在 Java 中嵌入 Office
我正在尝试使用 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):
线程“main”中出现异常 org.eclipse.swt.SWTException:无法执行操作。结果=-2147352567 在 org.eclipse.swt.ole.win32.OLE.error(来源未知) 在 org.eclipse.swt.ole.win32.OleAutomation.invokeNoReply(来源未知) 在 EmbeddingTest.initOleViewer(EmbeddingTest.java:68) 在 EmbeddingTest.main(EmbeddingTest.java:88)
有谁知道如何解决此问题或在 Java 中嵌入 Office 应用程序的替代解决方案?谢谢!
更新:
单独查询“Open”和“FileName”的 ID 会为“FileName”返回 null,因此它不正确。我也尝试过不使用命名参数,但没有成功:
documents.invokeNoReply(automationIDs[0], arguments);
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);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
为什么不进行任何错误处理、结果检查或断言?请记住,
getIDsOfNames(..)
将默默失败,并为无法识别的名称返回null
值。捕获有问题的异常后,尝试打印
documents.getLastError()
的值。Why aren't you doing any error handling, result checking, or assertions? Remember that
getIDsOfNames(..)
will silently fail and returnnull
values for unrecognized names.Try printing the value of
documents.getLastError()
after catching the offending exception.您需要使用Word.Application,因为Word.Document不会让您使用自动化功能,至少这是我的经验。当我实施自动化和 Ole 时,我分两步完成。
您可以在此处找到如何在 Word.Application 中打开文档的示例。
然后根据我的经验,您应该保存它并在 OLE 中将其打开为 Word.Document。
可以跳过显示 Word.Application。
You need to use Word.Application, because Word.Document will not let you use automation features, this is my experience at least. When I implemented automation and Ole I did it in 2 steps.
Here you find example of how to open document in Word.Application.
Then according to my experience you should save it and open in OLE as Word.Document.
Showing Word.Application can be skipped.
我已更新代码以使用 OleClientSite 而不是 OleControlSite,它对我有用。
I have updated the code to use OleClientSite instead of OleControlSite and it works for me.