1

在工作中,我们有一个非常古老但稳定的小程序,它需要两个 excel 电子表格(一个用作模板,另一个用作数据源)。模板由用户在 Excel 中创建,但数据源是在 Web 应用程序中使用 POI 创建的。在小程序中,两个电子表格都通过 Java/COM 桥 (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;
}

从小程序日志和 hs_err_pid 文件中,我知道 JACOB 可以很好地打开模板表,但数据表在 Dispatch.call 上失败。

从 hs_err_pid 文件:

> Java 框架:(J=编译的 Java 代码,j=解释的,Vv=VM 代码)
> 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/对象;+122
> j com.perceptive.ctms.applet.ImpactApplet.doExcelMailMerge(Lcom/perceptive/ctms/applet/MailMergeArgs;Ljava/lang/String;Ljava/lang/String;I)V+234
> j com.perceptive.ctms.applet.ImpactApplet.runOrams(Lcom/perceptive/ctms/applets/MailMergeArgs;)V+320
> j com.perceptive.ctms.applet.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 生成。

4

0 回答 0