OpenOffice Python (UNO) interface

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;" &