- What will version 2 hold?
- Is OO.o getting more and more important?
- How good is the interface
- Some useful files
- Simple OO.o text doc ("hello world")
- Scripting OO.o
- How to save file as PDF/PPT/Word, etc
- Document model
- Extensibility
- Web services
- Bibliographic project
- Links
Great news: a new book about OO.o file formats,
OpenOffice.org XML Essentials by
J. David Eisenberg ("The content is currently licensed under a Creative Commons License. The result of this work will be freely available on the World Wide Web under the Free Software Foundation’s GNU Free Documentation License.") This will make our lives much easier. The book is in progress and there seems to be a lot of stuff online already.
OpenOffice.org is an open source office suite. Noteworthy things about OO.o are that it has native XML file formats and that it is fully scriptable. I've been looking into how to exploit this functionality. I have written some PythonLanguage code to generate OO.o presentations. (I would like to document how I did that publicly. I had posed
questions about how to do so on my blog and finally did figure out some basic elements.)
What will version 2 hold?
I'm looking forward to version 2 of OpenOffice.org based on what I've seen in the following presentations/discussions:
Is OO.o getting more and more important?
-
http://www.groklaw.net/article.php?story=20050130002908154 -- EU and open documents
How good is the interface
Sun's StarOffice still can't rival Microsoft says Walter Mossberg. Contrast Mossberg's position to
OpenOffice.org Writer isn't a replacement for anything; it's simply a better piece of software.
Some useful files
-
OpenOffice: the XML format for the masses: Is a commenter right that OpenOfficeOrg file format is missing the point -- not extensible enough?
-
Thinking XML: The open office file format A nice tutorial by UcheOgbuji
It'll be interesting to see how the XmlSpec implementation in OO.o compares to that of MicrosoftOffice2003.
Simple OO.o text doc ("hello world")
Just content.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE office:document-content PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "office.dtd">
<office:document-content xmlns:office="http://openoffice.org/2000/office" xmlns:style="http://openoffice.org/2000/style" xmlns:text="http://openoffice.org/2000/text" xmlns:table="http://openoffice.org/2000/table" xmlns:draw="http://openoffice.org/2000/drawing" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:number="http://openoffice.org/2000/datastyle" xmlns:svg="http://www.w3.org/2000/svg" xmlns:chart="http://openoffice.org/2000/chart" xmlns:dr3d="http://openoffice.org/2000/dr3d" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:form="http://openoffice.org/2000/form" xmlns:script="http://openoffice.org/2000/script" office:class="text" office:version="1.0">
<office:body>
<text:p>Hello World</text:p>
</office:body>
</office:document-content>
Scripting OO.o
via Win32 COM
I've previously played with scripting OO.o via Win32-COM. For example, I have also come up with some basic PythonLanguage
code to fire up the Writer and create add some text to the document. Let me just drop the code here:
import win32com.client
objServiceManager = win32com.client.Dispatch("com.sun.star.ServiceManager")
objServiceManager._FlagAsMethod("CreateInstance")
objDesktop = objServiceManager.CreateInstance("com.sun.star.frame.Desktop")
objDesktop._FlagAsMethod("loadComponentFromURL")
args = []
objDocument = objDesktop.loadComponentFromURL("private:factory/swriter", "_blank", 0, args)
objDocument._FlagAsMethod("GetText")
objText = objDocument.GetText()
objText._FlagAsMethod("createTextCursor","insertString")
objCursor = objText.createTextCursor()
objText.insertString(objCursor, "The first line in the newly created text document.\n", 0)
Note that this technique works only on Win32 and requires a recent version of
win32all. The above code works on my Win2K Python 2.3.2, Win32all (build 157),
OpenOffice.org v1.10.
Via Py-UNO
One of the downsides that I found with this little program is that it didn't provide me enough guidance about the entire API set of OO.o. I've gotten the sense that the more general way forward is to look at the
UNO (Universal Network Objects), which is
-
the interface-based component model of OpenOffice.org. UNO offers interoperability between different programming languages, different object models, different machine architectures and different processes; either in a local network or even via the internet. UNO components can be implemented in and accessed from any programming language for which a UNO language binding exists.
-
C
-
C++ (compiler dependent, please see http://porting.openoffice.org for a list of supported platforms)
-
Java
-
Python
-
OpenOffice.org Basic
-
Object Linking and Embedding (OLE) Automation
-
Common Language Infrastructure (CLI). Note: The Microsoft .NET framework is an implementation of this standard. The language binding does NOT have the status "final" yet. Therefore do NOT use it (and programs based on it) in a production environment.
Currently there are complete UNO language bindings for:
I'm starting to look at the
Python-UNO bridge -- which is installed by default with OO.o version 1.1.0 now. So when I uninstalled old versions of OO.o and installed OO.o v 1.1.0, copied the
following code:
import uno
# get the uno component context from the PyUNO runtime
localContext = uno.getComponentContext()
# create the UnoUrlResolver
resolver = localContext.ServiceManager.createInstanceWithContext(
"com.sun.star.bridge.UnoUrlResolver", localContext )
# connect to the running office
ctx = resolver.resolve( "uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext" )
smgr = ctx.ServiceManager
# get the central desktop object
desktop = smgr.createInstanceWithContext( "com.sun.star.frame.Desktop",ctx)
# access the current writer document
model = desktop.getCurrentComponent()
# access the document's text property
text = model.Text
# create a cursor
cursor = text.createTextCursor()
# insert the text into the document
text.insertString( cursor, "Hello World", 0 )
# Do a nasty thing before exiting the python process. In case the
# last call is a oneway call (e.g. see idl-spec of insertString),
# it must be forced out of the remote-bridge caches before python
# exits the process. Otherwise, the oneway call may or may not reach
# the target object.
# I do this here by calling a cheap synchronous call (getPropertyValue).
ctx.ServiceManager
into helloWorld.py in C:\Program Files\OpenOffice.org1.1.0\program.
I then started OO.o (with a setting for it to listen on port ) with c:\Program Files\OpenOffice1.1\program> soffice "-accept=socket,host=localhost,port=2002;urp;"
and then ran the python program: c:\Program Files\OpenOffice1.1\program> .\python helloWorld.py
There is an important caveat. "You must use the script/batch file in the program directory to start python, simply starting the python executable in the runtime directory (or from python installation installed somewhere else on your machine) will not work."
Now why is that? There are some unix specific reasons but for my purposes (running on Win32), the issue seems to be more the fact that shipping the bulk of a core Python distribution around with OO.o simplifies the issue of getting files in the right directory. I was curious whether helloWorld.py would run if invoked in the context of another Python distribution. So, after adding C:\Program Files\OpenOffice.org1.1.0\program to the PYTHONPATH of my Python 2.2.2 and 2.3.2 setups, I found out that helloWorld.py works in Python 2.2.2 but not Python 2.3.2, which gave the error ImportError: Module use of python22.dll conflicts with this version of Python. on the import pyuno statement.
There is some discussion around
How to use the system default Python.
How to save file as PDF/PPT/Word, etc
Some of the best hints I've found comes from a
Michael Dannenhofer (
google English translation. Based on that code and what I've learned from a
OO.o Ruby tutorial, I came up with the following Python code snippet that reads in a OO.o Impress/Presentation file and outputs it as PowerPoint:
import win32com.client
def createStruct(strTypeName):
return serviceManager.Bridge_GetStruct(strTypeName)
serviceManager = win32com.client.Dispatch("com.sun.star.ServiceManager")
serviceManager._FlagAsMethod("Bridge_GetStruct")
desktop = serviceManager.createInstance("com.sun.star.frame.Desktop")
url = "file:///d|/collection_data.sxi"
#http://api.openoffice.org/docs/common/ref/com/sun/star/frame/XComponentLoader.html
present = desktop.loadComponentFromURL(url, "_blank", 0, [])
# save as ppt
# filter name: MS PowerPoint 97
#http://www.openoffice.org/files/documents/25/111/filter_description.html#anchor_impress
saveProperty = createStruct("com.sun.star.beans.PropertyValue")
saveProperty.Name = "FilterName"
saveProperty.Value = "MS PowerPoint 97"
present.storeAsUrl("file:///d|/collection_data.ppt",[saveProperty])
Document model
I'm trying to understand the data model for OO.o Drawings/Presentations. I'm currently working through
Drawing Documents and Presentation Documents
Extensibility
I'm really impressed with the work of Danny Brewer who has written
Draw powertools that embed a lot of new functionality (e.g., something to create nice little drawings) as macros inside a draw document. My question is whether/how I can write such extensions in Python.
What I think is happening: Danny Brewer wrote his macros in OO.o Basic. Where's a good place to learn about OO.o Basic. The built-in help and
OpenOffice.org Basic and Dialogs seem like good places.
Web services
I've been wondering how to incorporate WebServices into OpenOfficeOrg.
UNO Web Service Proxy might be a good place to start my reading.
