Open Office avec Tcl et tcom

 

Miko

La suite bureautique Open Office constitue une alternative gratuite à Office de Microsoft. elle peut être contrôlée à partir de Tcl avec l'extension tcom.

Ce code a été testé sur la plateforme suivante: Tcl 8.4, tcom 3.9 Open Office 1.1.4 et Windows XP. Sous Windows NT4 SP6 avec les même composants, ça ne fonctionne pas.

 package require tcom
 set OO [::tcom::ref createobject "com.sun.star.ServiceManager"]
 set OD [$OO createInstance com.sun.star.frame.Desktop ]
 set doc [$OD LoadComponentFromUrl private:factory/swriter _blank 0 ""]

ce code fonctionne avec Tclsh, par contre une fois "emballé" avec Freewrap, ça ne fonctionne plus... "Explication": le dernier argument de LoadComponentFromUrl est avec Delphi un tableau de variant, initialisé avec une fonction spécifique... il fallait traduire ça en Tcl... Plusieurs essais (empiriques, je le reconnais) avec list n'ayant rien donné, je m'étais résolu à employer Delphi pour la partie de mon programme appelant OO. Puis en fouillant sur le web je trouve cette page: http://www.oooforum.org/forum/viewtopic.phtml?t=9815 Avec des exemples pour piloter Open Office par le biais de COM avec différents langages, dont Tcl. Le rédacteur souligne d'ailleurs la nécessité d'avoir déjà ouvert un document Open Office et il emploie le code suivant:

 package require tcom
 array set args {}
 set objServiceManager [::tcom::ref createobject com.sun.star.ServiceManager]
 set Stardesktop [$objServiceManager createInstance com.sun.star.frame.Desktop]
 #Because I was not able to get the correct corresponding object type for a UNO sequence type I commented the loadComponentfromUrl out
 #set doc [$Stardesktop LoadComponentfromUrl private:factory/swriter _blank 0 "args"]
 set  doc [$Stardesktop getCurrentComponent]
 set xtext [$doc text]
 $xtext setString {Hello World}

Bizarrement, vous pouvez constater qu'il a eu l'idée (judicieuse) d'utiliser "array set" pour le dernier argument de LoadComponentfromUrl. La solution (testée avec freewrap et le tableur Calc de OO):

 set OO [::tcom::ref createobject "com.sun.star.ServiceManager"]
 set OD [$OO createInstance com.sun.star.frame.Desktop ]
 array set arguments {}
 set doc [$OD LoadComponentFromUrl private:factory/scalc _blank 0 [parray arguments]]

...il fallait utiliser parray, qui en l'occurence ne renvoie rien, mais parfois rien n'égale pas rien.(bon, d'accord, une chaîne vide n'est pas identique à un array vide vu de l'intérieur de Tcl, mais ceci ne m'explique pas pourquoi les trois premières lignes de code fonctionnent avec tclsh et pas avec freewrap). "array get" pourrait sembler plus judicieux, mais provoque une erreur.

Enfin, maintenant que le classeur est à l'écran, on peut acceder à ses objets:

  set feuilles [$classeur Sheets [expr 0]]
  if [catch {set feuille1 [$feuilles GetByName Sheet1]} ] {
    set feuille1 [$feuilles GetByName Feuille1]
  }

Ou (plus portable)

 set feuille1 [$classeur GetByIndex [expr 0]]

et remplir les cellules (il faut tester la valeur à insérer car la méthode d'accès n'est pas la même pour les chaînes ou les nombres)

 #l'index des cellules est colonne/ligne
 set cellule [$feuille1  getCellByPosition [expr 0] [expr 0]]
 $cellule SetString "Vive Tcl"
 set cellule [$feuille1  getCellByPosition [expr 1] [expr 0]]
 $cellule SetValue 2005

On regretterait presque que COM n'existe pas sous Linux car pour piloter OO chez le pingouin il faut le faire en Java...


Voir aussi le projet Tcluno [1] qui donne un accès à l'interface UNO de OpenOffice.