在工作中,我们有一个非常古老但稳定的applet,它带有两个excel电子表格(一个用作模板,另一个用作数据源)。模板由用户在Excel中创建,但数据源是使用Web应用程序中的POI创建的。在applet中,两个电子表格都是通过Java / COM Bridge(JACOB)打开的,使用以下方法:
/**
* Opens an excel workbook
*/
public Object openExcelWorkBook(ActiveXComponent xlActx, MailMergeArgs args, String dataSourceDocName, Object xlObj,
boolean isTemplate) {
final String functionName = "openExcelWorkBook";
Object activeWorkBookOj;
String workbook;
// get the workbooks object
Object wrkBooksObj = Dispatch.get(xlActx, ExcelConstants.APPLICATION_WORKBOOKS).toDispatch();
if ((!args.isTemplateExistsOnHost()) && (isTemplate)) {
debug("Skipping opening template...", functionName);
}
// it is on host
else {
if (isTemplate) {
workbook = getTemplateDocLoc(args);
} else {
if (!this.standaloneApp) {
workbook = TMP_DIR + dataSourceDocName;
} else {
workbook = dataSourceDocName;
}
}
debug("Opening workbook..." + workbook, functionName);
Dispatch.call(wrkBooksObj, ExcelConstants.WORKBOOKS_OLE_OPEN, workbook).toDispatch();
}
debug("Locating workbook...", functionName);
activeWorkBookOj = Dispatch.get(xlActx, ExcelConstants.APPLICATION_ACTIVEWORKBOOK).toDispatch();
debug("End", functionName);
return activeWorkBookOj;
}
从applet日志和hs_err_pid文件我知道模板表由JACOB打开,但数据表在Dispatch.call上失败。
来自hs_err_pid文件:
> Java frames: (J=compiled Java code, j=interpreted, Vv=VM code) > j com.jacob.com.Dispatch.invokev(Ljava/lang/Object;Ljava/lang/String;III[Lcom/jacob/com/Variant;[I)Lcom/jacob/com/Variant;+0 > j com.jacob.com.Dispatch.invokev(Ljava/lang/Object;II[Lcom/jacob/com/Variant;[I)Lcom/jacob/com/Variant;+27 > j com.jacob.com.Dispatch.callN(Ljava/lang/Object;I[Ljava/lang/Object;)Lcom/jacob/com/Variant;+11 > j com.jacob.com.Dispatch.call(Ljava/lang/Object;ILjava/lang/Object;)Lcom/jacob/com/Variant;+10 > j com.perceptive.ctms.applets.ImpactApplet.openExcelWorkBook(Lcom/jacob/activeX/ActiveXComponent;Lcom/perceptive/ctms/applets/MailMergeArgs;Ljava/lang/String;Ljava/lang/Object;Z)Ljava/lang/Object;+122 > j com.perceptive.ctms.applets.ImpactApplet.doExcelMailMerge(Lcom/perceptive/ctms/applets/MailMergeArgs;Ljava/lang/String;Ljava/lang/String;I)V+234 > j com.perceptive.ctms.applets.ImpactApplet.runOrams(Lcom/perceptive/ctms/applets/MailMergeArgs;)V+320 > j com.perceptive.ctms.applets.ImpactApplet.start()V+94 > j sun.plugin2.applet.Plugin2Manager$AppletExecutionRunnable.run()V+1159 > j java.lang.Thread.run()V+11 > v ~StubRoutines::call_stub
自从在Office 2010上进行测试后,我们才遇到此问题。
我们使用的POI 2.5.1和JACOB 1.9在过去几年中都有所改进,我打算尝试升级它们,但我想知道项目和Office 2010是否存在已知问题。虽然POI 3.x支持OOXML我们的代码需要保持向后兼容早期的Office版本,所以我们更愿意坚持使用HSSF生成。