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=' + outfile
return response
In this example I’m replacing text in a file. The result is returned as a http response. I can use it like this
template = 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.
1 comment