OpenOffice Python API much nicer than Java API

I wrote a small Python program today, to see if a could create a workaround for a problem i have in Java. I’ve written a couple of Java applications that use OpenOffice’s API to create ODF and MS-Word documents. The OpenOffice API that i used in Java is pretty horrible: very verbose, not intuitive. You can’t use intellisense/autocomplete, instead you query interfaces, that you just have to know exist. I documented some examples here: Getting started using openoffice in java, Mailmerge MS-Word template using OpenOffice and Java.

To my surprise, the python api doesn’t require you to use the whole query interface nonsense. Makes you code a lot smaller and more readable.

Here’s an example that replaces database field in a document (similar to the example here: Mailmerge MS-Word template using OpenOffice and Java).

#!/usr/bin/python

import sys
import uno
from os import getcwd
from unohelper import Base, systemPathToFileUrl, absolutize
from com.sun.star.beans import PropertyValue, UnknownPropertyException
from com.sun.star.uno import Exception as UnoException, RuntimeException

localContext = uno.getComponentContext()
resolver = localContext.ServiceManager.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", localContext )
ctx = resolver.resolve( "uno:socket,host=localhost,port=8100;urp;StarOffice.ComponentContext" )
smgr = ctx.ServiceManager
desktop = smgr.createInstanceWithContext("com.sun.star.frame.Desktop", ctx )

inProps = PropertyValue( "Hidden" , 0 , True, 0 ),
fileUrl = absolutize(systemPathToFileUrl( getcwd() ) ,"letter1.ott")
doc = desktop.loadComponentFromURL( fileUrl , "_blank", 0, inProps )

fields = doc.getTextFields().createEnumeration()
while fields.hasMoreElements():
        field = fields.nextElement()
        fieldname = field.getPresentation(0)

        try:
                isDatabaseField = field.getPropertyValue("DataBaseFormat")
        except UnknownPropertyException :
                isDatabaseField = False

        if isDatabaseField:
                try:
# this is incorrect usage of insertString
#                        doc.Text.insertString(field.getAnchor(),"New value for " + fieldname,1)
# this is the correct approach
                        fieldAnchor = field.getAnchor()
                        fieldAnchor.Text.insertString(fieldAnchor,"New value for " + fieldname,1)
                except RuntimeException, e:
                        print "RuntimeException while to replacing field: " + e.Message

# save document
outProps = PropertyValue( "Overwrite" , 0 , True, 0 ),
saveUrl = absolutize(systemPathToFileUrl( getcwd() ) ,"letter1.odt")
doc.storeToURL(saveUrl, outProps)

~~Beware of this code though, it throws a RuntimeException when trying to replace a database field in the header of a document. So, in that sense, Python is no better than Java.~~

Update: a reply on the openoffice forum put me on the right track. My usage of insertString was incorrect. I’ve fixed the code above.

blog comments powered by Disqus