XLL4J
Excel Addin Framework for Java
About
XLL4J is a framework for developing Microsoft Excel addins (XLLs) in Java. It provides a mechanism for implementing Excel functions in Java and has the following features:
  • Easy Java VM management via INI file (refer to table below for details).
  • Two APIs; one low-level and one reflection based for easy implementation.
  • Built-in CSV addin for accessing CSV from filesystem or network.
XLL4J is currently alpha quality and has the following limitations:
  • Only one instance of the same Java VM version can be run at one time. This is a Sun VM limitation. A workaround is currently being worked on.
  • There are lots of bugs...
ExcelAddin4J is licensed under the Common Public License (CPL).

This project is on hold due to the VM limitation described above. For an alternative you could try XLLoop
Download
The latest download is available from the Project Page.
Usage
The steps for implementing an addin are as follows:
  1. Copy XLL4J.xll to MyAddin.xll
  2. Create MyAddin.ini and customize using options below.
  3. Implement org.excel4.Addin interface (or use ReflectAddin base class).
  4. You will then be able to load the xll in excel. Note that for there will be a builtin function called MyAddin_GetLastError that provides some diagnostics.
The INI file accepts the following settings:
KeyDescription
addin.class This is the java addin class that implements org.excel4j.Addin
working.directory This will be the current directory for the app. It can be relative to your addin.
classpath.1, classpath.2, ..., classpath.n Classpath entries. These will be relative to the working directory above. They can be wildcards (eg. *.jar)
vmarg.1, vmarg.2, ..., vmarg.n Java VM args. These will be passed on to the VM.
vm.version.max The maximum allowed version (1.0, 1.1, 1.2, 1.3, 1.4, 1.5).
vm.version.min The minimum allowed version (1.0, 1.1, 1.2, 1.3, 1.4, 1.5).
vm.version Specify an exact version to use (eg. 1.5.0_07).
vm.location Specify the location of the JVM dll you want to use. This is useful when you package your own JRE with your app.
vm.heapsize.max.percent Specify a proportion of the available physical memory to use (ie. relates to -Xmx arg). For example, vm.heapsize.max.percent=75. Note that this will use the maximum memory possible.
vm.heapsize.min.percent Specify a proportion of the available physical memory to use as the minimum starting heap size (ie. relates to -Xms arg).
vm.heapsize.preferred Specify a preferred amount (in MB) for the heap size (ie. relates to -Xmx arg). If this amount is not available it will use the maximum amount possible given the physical memory available.
log Standard out and error streams will be redirected to this file (including launcher messages).
log.level Specify the logging level. One of "info", "warning", "error", "none". Default is "error".
JNI Library
The javadoc for the JNI library can be found here.
Example - Hello World
The library provides a convenient (reflection-based) wrapper for an addin. So a basic hello world addin would look like:
package org.excel4j.test;

import org.excel4j.reflect.ReflectAddin;


/**
 * A very basic excel addin.
 */
public class Example1 extends ReflectAddin 
{
    public String MyFunc() {
        return "Hello World!";
    }
}
The corresponding INI file would look like:
classpath.1=Example1.jar
addin.class=org.excel4j.test.Example1
The excel sheet would then look like this:
Example - Working With Arrays
The reflection framework can perform conversion from references to arrays:
package org.excel4j.test;

import org.excel4j.reflect.ReflectAddin;

/**
 * An example using arrays.
 */
public class Example2 extends ReflectAddin
{
    public double MyExampleSum(double[][] vals) {
        double result = 0;

        for(int i = 0; i < vals.length; i++) {
            for(int j = 0; j < vals[i].length; j++) {
                result += vals[i][j];
            }
        }

        return result;
    }
}
The excel sheet would then look like this:
Example - Working With Objects
The reflection framework allows you to pass around Java objects to and from functions. This is achieved via ID references (strings) and a cache. An example of this is:
package org.excel4j.test;

import org.excel4j.reflect.ReflectAddin;

/**
 * An example using objects.
 */
public class Example3 extends ReflectAddin 
{
    public static class Test {
        String a, b;
    }
    
    public Test CreateTest() {
        Test a = new Test();
        a.a = "Hello";
        a.b = "World!";
        return a;
    }
    
    public String[][] DumpTest(Test t) {
        return new String[][] {
                { "A", t.a },
                { "B", t.b }};
    }
}
The excel sheet would then look like this:
Change History
V0.0.2 V0.0.1