Click here to Skip to main content
13,090,730 members (42,399 online)
Click here to Skip to main content
Add your own
alternative version

Tagged as


5 bookmarked
Posted 2 Dec 2010

A Simple Way to Create Word Documents by Template in Java under Windows Platform

, 2 Dec 2010
Rate this:
Please Sign up or sign in to vote.
Using JNI and COM technology generate Word documents in Java under Windows platform


There are some open source projects which can create Word documents in Java, like Apache poi, itext, etc. But using COM is a simple way to create Word documents in Java under Windows platform. So I will show you how to use JNI technology to call Windows COM in this article.

Setup Development Environment

  1. Download the latest version of Eclipse from, and extract compressed file into C:\Eclipse.
  2. Download the latest version of Code::Blocks from, and install it into C:\CodeBlocks.
  3. Download the latest version of vole from, which is a neat C++ COM/Automation driver, we can use it to create Word documents easily. And vole depends on the STLSoft libraries, so we need download STLSoft -, too.
  4. Extract file into C:\vole-0.7.2, and copy directory “vole” into C:\CodeBlocks\MinGW\include in C:\vole-0.7.2\include.
  5. Extract file into C:\stlsoft-1.9.100-hdrs, and copy all directories into C:\CodeBlocks\MinGW\include in C:\stlsoft-1.9.100-hdrs\include.

Program Development

  1. Create a new Java project zzutils in Eclipse, and create a new class named Utils, package name is org.zerozone.util. We will define a native method named generateWordDocument, which holds 5 parameters. The method definition is listed below:
    public static native void generateWordDocument(String fileName,
      String[] bookmarkNames, int bookmarkCount, String[] values,
      int valueCount);

    The parameters description:

    • fileName, the file which saves process result
    • bookmarkNames, an array which hold bookmarks what you want to insert into
    • bookmarkCount, a number which indicates how many bookmarks will be processed
    • values, an array which holds values that will be inserted into the right bookmark
    • valueCount, a number which indicates how many values will be inserted
  2. Generate C++ header file with javah which is a tool in jdk. Create a batch file named generate_header.bat, the contents of which are listed below:
    "C:\Program Files\Java\jdk1.6.0_10\bin\javah" 
    -classpath .;./bin org.zerozone.util.Utils

    Run this bat file, then we can get a C++ header file named org_zerozone_util_Utils.h under zztuils project directory.

  3. Create a new dynamic library project named zzutils in Code::Blocks.
    First, copy header file org_zerozone_util_Utils.h into project directory, and add this header file into project, then create a new CPP file named utils.cpp, the contents of which are listed below:
    #include <windows.h>
    #include "org_zerozone_utils_Utils.h"
    #include "cn_net_ynst_kjjl_util_Utils.h"
    #include <vole/vole.hpp>
    #include <comstl/util/initialisers.hpp>
    using vole::object;
    using vole::collection;
    char* jstringToWindows(JNIEnv *env, jstring jstr)
        int length = env->GetStringLength(jstr);
        const jchar* jcstr = env->GetStringChars(jstr, 0);
        char* rtn = (char*)malloc(length*2+1);
        int size = 0;
        size = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)jcstr, length, 
    			rtn,(length*2+1), NULL, NULL);
        if(size <= 0)
            rtn = NULL;
            return NULL;
        env->ReleaseStringChars(jstr, jcstr);
        rtn[size] = 0;
        return rtn;
    jstring windowsToJstring(JNIEnv* env, char* str)
        jstring rtn = 0;
        int slen = strlen(str);
        unsigned short* buffer = 0;
        if(slen == 0)
           rtn = env->NewStringUTF(str);
            int length = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)str, slen, NULL, 0);
            buffer = (unsigned short*)malloc(length*2 + 1);
            if( MultiByteToWideChar(CP_ACP, 0, (LPCSTR)str, 
    			slen, (LPWSTR)buffer, length ) > 0)
              rtn = env->NewString((jchar*)buffer, length);
              buffer = NULL;
            return rtn;
    JNIEXPORT void JNICALL Java_cn_net_ynst_kjjl_util_Utils_generateWordDocument
        (JNIEnv *env, jclass clazz, jstring fileName, jobjectArray bookmarkNames,
         jint bookmarkCount, jobjectArray values, jint valueCount)
        if(bookmarkCount != valueCount)
        int len = 0;
        char* _fileName = jstringToWindows(env, fileName);
        len = MultiByteToWideChar(CP_ACP, 0, 
    	(LPCSTR)_fileName, strlen(_fileName) + 1, NULL, 0);
        wchar_t* _w_fileName = new wchar_t[len];
        MultiByteToWideChar(CP_ACP, 0, (LPCSTR)_fileName, -1, _w_fileName, len);
        comstl::com_init init;
        object word = object::create("Word.Application", CLSCTX_LOCAL_SERVER,
        word.put_property(L"Visible", false);
        collection documents = word.get_property<collection>(L"Documents");
        object document = documents.invoke_method<object>
    			(L"Open", (LPCWSTR)_w_fileName);
        collection bookmarks = document.get_property<collection>(L"Bookmarks");
        int count = bookmarks.get_property<int>(L"Count");
        for(int i = 1; i <= count; i++)
            object bookmark = bookmarks.invoke_method<object>(L"Item", i);
            std::string name = bookmark.get_property<std::string>(L"Name");
            for(int j = 0; j < bookmarkCount; j++)
                jstring bookmarkName = 
    		(jstring)env->GetObjectArrayElement(bookmarkNames, j);
                const char* _bookmarkName = env->GetStringUTFChars(bookmarkName, 0);
                if(strcmp(name.c_str(), _bookmarkName) == 0)
                    jstring value = (jstring)env->GetObjectArrayElement(values, j);
                    char* _value = jstringToWindows(env, value);
                    len = MultiByteToWideChar(CP_ACP, 0, 
    			(LPCSTR)_value, strlen(_value) + 1, NULL, 0);
                    wchar_t* _w_value = new wchar_t[len];
                    MultiByteToWideChar(CP_ACP, 0, (LPCSTR)_value, -1, _w_value, len);
                    object range = bookmark.get_property<object>(L"Range");
                    range.invoke_method_v(L"InsertAfter", (LPCWSTR)_w_value);
                    _value = NULL;
                    _w_value = NULL;
                    env->ReleaseStringUTFChars(bookmarkName, _bookmarkName);
                env->ReleaseStringUTFChars(bookmarkName, _bookmarkName);
        document.invoke_method_v(L"Close", false);
  4. Create a new Word document in Word, and insert two bookmarks named title and year, save it and name it as 1.doc, path is C:\. We will use it as a template file.

When all the above steps have been completed, we can compile it in Code::Blocks, and get a file named zztuils.dll, please copy this file into project zzutils which is created by eclipse. Then we could run main method in class Utils.

Advantages & Shortcomings


  1. We can use features of COM technology to create Word document easily.
  2. We can code less than what projects which use apache poi or something else do.


  1. This program can run under Windows platform only.
  2. Deploy it into tomcat and it could be crashed when called 5-6 times. I will try web service way to avoid this problem.


  • 2nd December, 2010: Initial post


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Software Developer none
China China
To be, or not to be, this is question. That's are all depend on your decision. What do you think?

You may also be interested in...


Comments and Discussions

-- There are no messages in this forum --
Permalink | Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.170813.1 | Last Updated 2 Dec 2010
Article Copyright 2010 by jackyxinli
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid