Django and OpenOffice.org uno reports
Openoffice.org’s python uno library is great for report writing in a web application. I wanted to create a report template system where users can create templates with a word processor of their choice. I created a simple template model which consists of a CharField and FileField. Users can upload templates here in .doc, .odt, or any format OpenOffice.org supports.
Next I created some generic template report functions.
from django.http import HttpResponse
from django.core.servers.basehttp import FileWrapper
import uno
import os
import string
import tempfile
`def findandreplace(document, search, find, replace): “”“This function searches and replaces. Create search, call function findFirst, and finally replace what we found.”“”
What to search for
search.SearchString = unicode(find)
search.SearchCaseSensitive = True
search.SearchWords = True
found = document.findFirst( search ) if found: print ‘Found %s’ % find while found: found.String = string.replace( found.String, unicode(find),unicode(replace)) found = document.findNext( found.End, search) def replace_report(infile, outfile, data): “”“Replace words in a file use like this data={} data[‘$TEST’]=’worked yay’ returns a django HttpResponse of the file”“”
Boring uno stuff
local = uno.getComponentContext() resolver = local.ServiceManager.createInstanceWithContext(“com.sun.star.bridge.UnoUrlResolver”, local) context = resolver.resolve(“uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext”) desktop = context.ServiceManager.createInstanceWithContext(“com.sun.star.frame.Desktop”, context)
open document
document = desktop.loadComponentFromURL(“file://” + str(infile) ,”_blank”, 0, ())
cursor = document.Text.createTextCursor()search = document.createSearchDescriptor()
Do a loop of the data and replace the content.
for find,replace in data.items(): findandreplace(document,search,unicode(find),unicode(replace)) print find,replace`
`# create temporariy file to store document in tmp = tempfile.NamedTemporaryFile() document.storeToURL(“file://” + str(tmp.name), ()) document.dispose()
create http response out of temporariy file.
wrapper = FileWrapper(file(tmp.name))
response = HttpResponse(wrapper, content_type=’application/odt’)
response[‘Content-Length’] = os.path.getsize(tmp.name)
response[‘Content-Disposition’] = ‘attachment; filename=’ + outfilereturn responseIn this example I'm replacing text in a file. The result is returned as a http response. I can use it like thistemplate = Template.objects.get_or_create(name=”My Selected Template”)[0]
data={}
data[‘$date’] = str(date.today())
return replace_report(template.file.path, “file.odt”, data)`
In this case I am taking out my template and replacing all instances of the word “$date” with the current date. I choose to use $ to mark it as a variable but it could really be anything. Now when a user wants to change a font they can do it themselves.