杰瑞科技汇

Java如何通过OLE连接Access数据库?

Of course. Accessing OLE (Object Linking and Embedding) objects from Java is a complex task because OLE is a Microsoft Windows-specific technology deeply integrated into the COM (Component Object Model) framework. Java, by design, is platform-agnostic and doesn't have a built-in, direct way to interact with COM objects.

Java如何通过OLE连接Access数据库?-图1
(图片来源网络,侵删)

Therefore, you need a bridge or a wrapper. The most common and robust solution for this is Jacob (Java-COM Bridge).

This guide will walk you through the process using Jacob, which is the recommended approach for most use cases.


Core Concept: The Bridge

Think of Jacob as a translator. It allows your Java application to:

  1. Create and manipulate Windows COM objects.
  2. Call methods on those objects.
  3. Get and set properties on those objects.
  4. Handle events from those objects.

Jacob works by using a small native DLL (.dll) that acts as the actual COM bridge. Your Java code interacts with a Jacob JAR file, which in turn calls the native DLL.

Java如何通过OLE连接Access数据库?-图2
(图片来源网络,侵删)

Step-by-Step Guide: Accessing an OLE Object with Jacob

Let's use a common example: interacting with Microsoft Excel. Excel exposes its application as an OLE/COM object.

Prerequisites

  1. Java Development Kit (JDK): Version 8 or newer.
  2. Microsoft Excel: The target application must be installed on the machine where the Java code will run. You cannot automate Excel without it.
  3. Jacob Library: Download the latest Jacob release from the official SourceForge page: https://sourceforge.net/projects/jacob-project/
    • You will get a ZIP file containing two key files:
      • jacob.jar: The Java Archive file to include in your project's classpath.
      • jacob-1.20-x64.dll (or jacob-1.20-x86.dll): The native DLL. The version must match your JVM (32-bit or 64-bit).

Step 1: Project Setup

  1. Create a new Java project in your favorite IDE (Eclipse, IntelliJ, VS Code, etc.).

  2. Add the jacob.jar file to your project's libraries. In most IDEs, you can do this by right-clicking the project -> Build Path / Libraries -> Add External JARs.

  3. Crucially, you must tell your application where to find the native DLL. The easiest way during development is to place the DLL in a directory that is on your system's PATH environment variable.

    Java如何通过OLE连接Access数据库?-图3
    (图片来源网络,侵删)
    • On Windows:

      • Copy jacob-1.20-x64.dll (or the 32-bit version) to C:\Windows\System32.
      • Or, add the directory where you unzipped Jacob to your system's PATH variable.
    • Alternative (Programmatic approach): You can also load the DLL directly from your project's resources using System.loadLibrary("jacob"). This makes your application more portable.

Step 2: Write the Java Code

Here is a complete example that creates a new Excel workbook, adds a sheet, writes some data, and saves the file.

import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
public class JacobExcelExample {
    public static void main(String[] args) {
        // 1. Initialize the COM bridge with the Excel application
        // We use try-with-resources to ensure the COM object is released
        try (ActiveXComponent excel = new ActiveXComponent("Excel.Application")) {
            // 2. Make Excel visible (optional, good for debugging)
            Dispatch.put(excel, "Visible", new Variant(true));
            // 3. Get the Workbooks collection from the Excel application
            Dispatch workbooks = Dispatch.get(excel, "Workbooks").toDispatch();
            // 4. Add a new workbook to the collection
            Dispatch workbook = Dispatch.call(workbooks, "Add").toDispatch();
            // 5. Get the active worksheet from the workbook
            // Excel collections are often 1-based, not 0-based
            Dispatch sheets = Dispatch.get(workbook, "Worksheets").toDispatch();
            Dispatch sheet = Dispatch.call(sheets, "Item", new Variant(1)).toDispatch();
            // 6. Get the range of cells A1:C1
            Dispatch range = Dispatch.get(sheet, "Range", new Variant("A1:C1")).toDispatch();
            // 7. Write values to the range
            // The array must be a 2D array, even for a single row
            Object[][] data = {
                {"Product", "Quantity", "Price"}
            };
            Dispatch.call(range, "Value", data);
            // 8. Get a single cell, A2, and write to it
            Dispatch cellA2 = Dispatch.get(sheet, "Range", new Variant("A2")).toDispatch();
            Dispatch.put(cellA2, "Value", "Laptop");
            // 9. Save the workbook
            // Get the FileDialog object to save the file
            Dispatch fileDialog = Dispatch.get(excel, "FileDialog", new Variant(2)).toDispatch(); // 2 = msoFileDialogSaveAs
            Dispatch.put(fileDialog, "Title", "Save Excel File");
            Dispatch.put(fileDialog, "FilterIndex", new Variant(1)); // Excel files
            Dispatch.call(fileDialog, "Show");
            // If the user clicked "Save"
            if (Dispatch.get(fileDialog, "SelectedItems").toDispatch() != null) {
                Dispatch selectedItem = Dispatch.get(fileDialog, "SelectedItems").toDispatch();
                String path = Dispatch.get(selectedItem, "Path").toString();
                Dispatch.call(workbook, "SaveAs", path);
                System.out.println("Workbook saved to: " + path);
            }
            // 10. Quit Excel (optional, as the try-with-resources will handle it)
            // Dispatch.call(excel, "Quit");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Step 3: Run the Code

Run the main method in your Java application. If everything is set up correctly, you should see an Excel instance launch, a new workbook appear, data get written, and a "Save As" dialog box pop up.


Important Considerations and Best Practices

  1. Error Handling is Crucial: COM interop is brittle. A method might fail for many reasons (e.g., the object doesn't exist, a parameter is of the wrong type, the application is busy). Always wrap your Dispatch calls in try-catch blocks.
  2. Memory Management (Garbage Collection): COM objects are not managed by the Java Garbage Collector (GC). You must explicitly release them to avoid memory leaks and "zombie" COM objects.
    • Use try-with-resources: The ActiveXComponent class implements AutoCloseable. Using a try-with-resources block is the best way to ensure excel.release() is called automatically.
    • Release Dispatch Objects: For other Dispatch objects (like workbook, sheet, range), you should release them manually when you are done with them.
      // After you are done with the workbook
      if (workbook != null) {
          Dispatch.call(workbook, "Close");
          workbook.safeRelease();
      }
  3. 32-bit vs. 64-bit: This is the most common source of problems. Your JVM (32-bit or 64-bit), your Jacob DLL (jacob-x86.dll or jacob-x64.dll), and your Office installation (32-bit or 64-bit) must all be the same architecture. Mixing them will result in UnsatisfiedLinkError or other strange errors. Modern systems are almost exclusively 64-bit.
  4. Alternative: Apache POI: For tasks like reading/writing Excel files, Apache POI is almost always a better choice. It's a pure Java library, doesn't require Excel to be installed, and is much more stable and easier to use. Use Jacob only when you need to automate an in-process action that cannot be done with a file-based library (e.g., making Excel perform a complex calculation, refresh a pivot table, or interact with its user interface).
  5. Debugging: To see what's happening under the hood, you can enable Jacob's logging. Set the JVM argument:
    -Djacob.debug=true

    This will print detailed information about the COM calls to the console, which is invaluable for debugging.


Alternative Libraries

While Jacob is the most popular, other options exist:

  • JACOB (Java-COM Bridge): The one we just covered. It's mature, widely used, and relatively easy for simple tasks.
  • JNI (Java Native Interface): You could write your own C++ JNI wrapper around the COM APIs. This is extremely complex, platform-specific, and not recommended unless you have very specialized requirements.
  • JACOB-less solutions: Some libraries use a different approach, like launching the OLE server as a separate process and communicating via Windows messages or sockets. These are often less reliable and harder to control.

Conclusion: For accessing OLE/COM objects from Java, Jacob is the de-facto standard. It provides a necessary bridge between the Java world and the Windows COM world. Just be mindful of the architecture (32/64-bit), manage your resources carefully, and prefer pure Java libraries like Apache POI for simple file manipulations.

分享:
扫描分享到社交APP
上一篇
下一篇