I spent most of yesterday trying to get the Python UNO interface to OpenOffice to open a document, fill in the TextField blocks in that document, and then export it as PDF. Sort of an automated mail merge, if you will.
The documentation is pretty good, but most of the code examples I was able to find were either in Java or OOBasic, and since I don’t actually speak Python, getting this to work was quite a challenge. There’s a Perl implementation, too, but I couldn’t get that to work at all, and the maintainer was unresponsive. I would love to hear from him, so that I can do this in Perl instead.
So, I thought I’d put the functioning code here, both for my own benefit when I have trouble remembering later, and for the benefit of any other person who might be searching for this information and, like myself, only find examples in other languages.
# Fill in TextFields import uno import unohelper import string # a UNO struct later needed to create a document from com.sun.star.beans import PropertyValue localContext = uno.getComponentContext() resolver = localContext.ServiceManager.createInstanceWithContext( "com.sun.star.bridge.UnoUrlResolver", localContext ) smgr = resolver.resolve( "uno:socket,host=localhost,port=8100;urp;StarOffice.ServiceManager" ) remoteContext = smgr.getPropertyValue( "DefaultContext" ) desktop = smgr.createInstanceWithContext( "com.sun.star.frame.Desktop",remoteContext) # Open the document hidden = PropertyValue( "Hidden" , 0 , True, 0 ), doc = desktop.loadComponentFromURL("file:///home/rbowen/test_doc.odt" ,"_blank", 0, (hidden)) # Find variable fields, and put values into them oTFs = doc.getTextFields() enum = oTFs.createEnumeration() while enum.hasMoreElements(): tf = enum.nextElement() if tf.VariableName == 'firstname': tf.Content = 'Rich' if tf.VariableName == 'lastname': tf.Content = 'Bowen' # Save the document # doc.store() # Save as PDF pdf = PropertyValue() pdf.Name = 'FilterName' pdf.Value = 'writer_pdf_Export' doc.storeToURL( "file:///home/rbowen/test_doc.pdf", (pdf,));
Note also that in order for this to work, you’ll need to have already started up OpenOffice in server mode:
/opt/openoffice.org3/program/soffice -invisible "-accept=socket,host=localhost,port=8100,tcpNoDelay=1;urp;" &