Updated 2011-01-22 02:49:17 by RLE

WJG (15th May, 2005) A number of recent postings have appeared on the Wiki and the NG about using Tcl to drive OpenOffice so I though it time to chuck-in something of my own. As an commited user of both resources I have custom-written applications that enable me to work on text created in TclTk which I then transfer to OpenOffice Writer for final presentation printing. Here's a simple package setting up OO and the creation of some sample text and a table. Whilst it would be possible to hack around with UNO, I felt it better to wrap the code into something less prone to being forgotten.
 ############################################ 
 # TclOO.tcl
 # ------------------------
 # Written by: William J Giddings
 # 15th October, 2005
 ############################################ 
 # Description:
 # -----------
 # Render text pages within OpenOffice Writer under 
 # the control of a Tcl Script.
 #
 # Proceedures:
 # -----------
 # TclOO::begin                       - startup OpenOffice
 # TclOO::writer                      - create writer document
 # TclOO::text:Insert {str}           - insert text
 # TclOO::print                       - print document to default printer
 # TclOO::table {rows cols}           - create table
 # TclOO::table:SetCel {cel str}      - set cel value
 # TclOO::table:SetFormula {cel frm}  - set cel cel formula
 # TclOO::goto {keyword {spc {}} }    - reposition insert cursor
 #
 # Note:
 # ----
 # 
 # 
 # References:
 # ----------
 # http://udk.openoffice.org/common/man/tutorial/office_automation.html
 # http://udk.openoffice.org/common/man/tutorial/writerdemo.html
 # http://api.openoffice.org/basic/man/tutorial/tutorial.pdf
 ############################################

 package require tcom

 #-----------------------
 # create namespace to contain package specific procs and shared variables
 #-----------------------
 namespace eval TclOO {} {}

 #-----------------------
 # If OpenOffice isn't running then start it up!
 #-----------------------
 proc TclOO::begin {} {
  # The service manager is always the starting point
  set ::TclOO::ServiceManager [::tcom::ref createobject com.sun.star.ServiceManager]

  # Create the Desktop
  set ::TclOO::Desktop [$TclOO::ServiceManager createInstance com.sun.star.frame.Desktop]
 }

 #-----------------------
 # Open a new empty writer document
 #-----------------------
 proc TclOO::writer {} {
  array set args {}
  set ::TclOO::Document [$TclOO::Desktop loadComponentfromUrl private:factory/swriter _blank 0 [parray args]]
  set ::TclOO::Text [$::TclOO::Document getText]

  # Create a cursor object
  set ::TclOO::Cursor [$::TclOO::Text createTextCursor]
 }

 #-----------------------
 # Create a text object
 #-----------------------
 proc TclOO::text:Insert {str} {
  # Inserting some Text
  $::TclOO::Text insertString $::TclOO::Cursor "$str\n" false
 }

 #-----------------------
 # Print
 #-----------------------
 proc TclOO::print {} {
  array set args {}
  $::TclOO::Document Print [parray args]
 }

 #-----------------------
 # Table
 #-----------------------
 proc TclOO::table {rows cols} {
  # create instance of table object
  set ::TclOO::Table [$::TclOO::Document createInstance "com.sun.star.text.TextTable"]
  # set the size 
  $::TclOO::Table initialize $rows $cols
  # Insert the table
  $::TclOO::Text insertTextContent $::TclOO::Cursor $::TclOO::Table false
 }

 #-----------------------
 # Insert string into table cel
 #-----------------------
 proc TclOO::table:SetCel {cel str} {
  set cell [$::TclOO::Table getCellByName $cel] 
  $cell SetString $str
 }

 #-----------------------
 # Insert forumula into table cel
 #-----------------------
 proc TclOO::table:SetFormula {cel frm} {
  set cell [$::TclOO::Table getCellByName $cel] 
  eval $cell setFormula $frm
 }

 #-----------------------
 # goto, reposistion insert cursor
 #-----------------------
 proc TclOO::goto {keyword {spc {}} } {
  # make sure keyowrd is the right format
  switch [string toupper $keyword] {
    RIGHT { set keyword goRight }
    LEFT { set keyword goLeft }
    NEXTSENTENCE {set keyword gotoNextSentence}
    PREVIOUSENTENCE { set keyword gotoPreviousSentence}
    NEXTPARAGRAPH {set keyword gotoNextParagraph}
    PREVIOUSPARAGRAPH {set keyword gotoPreviousParagraph}
    ENDOFPARAGRAPH {set keyword gotoEndOfParagraph}
    STARTOFPARAGRAPH {set keyword gotoStartOfParagraph}
    }
  $::TclOO::Cursor $keyword $spc false    
 }

 #-----------------------
 # the ubiquitous demo
 #-----------------------
 proc demo {} {
  # begin the rendering process
  TclOO::begin
  TclOO::writer
  
  # some sample text
  TclOO::text:Insert "Apple"
  TclOO::text:Insert "Bannana"
  TclOO::text:Insert "Cherry"
  TclOO::text:Insert "Damson"
  
  # add a table
  TclOO::table 4 4
  # add table headings
  TclOO::table:SetCel A1 Jan
  TclOO::table:SetCel B1 Feb
  TclOO::table:SetCel C1 Mar 
  TclOO::table:SetCel D1 Sum
  # first row of data
  TclOO::table:SetCel A2 10.0
  TclOO::table:SetCel B2 20.0
  TclOO::table:SetCel C2 30.5 
  # second row of data
  TclOO::table:SetCel A3 10.0
  TclOO::table:SetCel B3 20.0
  TclOO::table:SetCel C3 30.5 
  # some formulae
  TclOO::table:SetFormula D2 sum<A2:C2>
  TclOO::table:SetFormula D3 sum<A3:C3>  
  TclOO::table:SetCel C4 Total   
  TclOO::table:SetFormula D4 sum<D2:D3>  
  
  # reposition the cursor
  TclOO::goto Start
  TclOO::text:Insert "Top of Page"
  TclOO::goto End
  TclOO::text:Insert "Bottom of Page"
  TclOO::goto left 5
  TclOO::text:Insert "***"
  
  # and print!
  TclOO::print 
 }

 demo

schlenk 16. Oct 2005 While wrapping things in a nicer TclOO namespace is good, using Tcom limits it to windows. The same thing using TclUNO would be a nice addition.

Arnulf Wiedemann 18. Oct 2005 Just for information: There is some work in progress having a tcl-only package with the same interfaces as the tcluno C++ Version library, which should also run on Microsoft Windows. The base of the package is ready; there is only some more testing necessary before releasing it. Let me know if somebody likes to be the "guinea pig" for testing. Look on the tcluno page for contacting me.