I’m presently working on a little side project that needs to generate a bunch of customisable client reports. One format of interest to our target market is the ubiquitous Word document. Now I know that Word switched to an zipped XML format a while back, so it’s given me a chance to do some researching into what Java libraries might exist for creating and editing the Word xml format.

I’ve played with Apache POI before, but it’s Word support for the latest gear is a little scratchy, so I figured I would hunt around for an nice libraries that people have built for handling the new XML format natively. I didn’t have to hunt far to discover the conveniently named docx4j.

This library gives you everything you need to create/load/edit/write Word docx documents from Java, and comes with a Maven repo, online Javadoc, and nice set of Sample code. What more could you ask for? :-)

But I’m sure you’re just keen to see how to use it in your Grails app, right? Enough talk… First you’ll need to add a couple of entries to your /grails-app/conf/BuildConfig.groovy to make sure you pull in the dependencies. In the extract below, I’ve added a couple of new repos, and the dependency to pull in the docx4j jars:

    repositories {
        grailsPlugins()
        grailsHome()

        // uncomment the below to enable remote dependency resolution
        // from public Maven repositories
        mavenLocal()
        mavenCentral()

        // Details from docx4j Getting Started Guide at http://dev.plutext.org/svn/docx4j/trunk/docx4j/docs/Docx4j_GettingStarted.html
        mavenRepo "http://dev.plutext.org/svn/docx4j/trunk/docx4j/m2"
        mavenRepo "https://webdavclient4j.svn.sourceforge.net/svnroot/webdavclient4j/trunk/m2"
    }
    dependencies {
        compile 'org.docx4j:docx4j:2.5.0'
    }

With all our dependencies in place, we’ll just need to create some controller action that generates our Word document and sends it back to the client. I’m going to show one that queries my Asset class to pull back a set of assets and dump them in a Word doc:


  import org.docx4j.openpackaging.packages.WordprocessingMLPackage

  def exportWord = {
    WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.createPackage()
    def mainPart = wordMLPackage.getMainDocumentPart()

    // create some styled heading...
    mainPart.addStyledParagraphOfText("Title", "Asset Library")
    mainPart.addStyledParagraphOfText("Subtitle", "Generated at " + Calendar.getInstance().getTime().toString())

    // Add our list of assets to the document
    Asset.list().each { asset ->
      mainPart.addParagraphOfText(asset.name)
    }

    // write out our word doc to disk
    File file = File.createTempFile("wordexport-", ".docx")
    wordMLPackage.save file

    // and send it all back to the browser
    response.setHeader("Content-disposition", "attachment; filename=assets.docx");
    response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document")
    response.outputStream << file.readBytes()
    file.delete()

  }

With our document sent, the user can fire it up from their browser window. Here’s a sample of the output from above:

There are tons of things you can do with customising the documents in memory. I’ll be doing some work importing Word templates, customising their fields, then exporting the finished product to the browser. Fun times ahead!

Enjoy your docx generating!