| By: Olivier Date: 2007-06-06 Time: 12:20 | Re: Génération de document pdfBonjour, 
Voici quelques informations pour l'installation d'OpenOffice sous Linux sans X (tests effectués sur une Fedora). 
Le code date de 2 ans et c'etait OpenOffice 1.1 
J'ai fais une petite compilation de la procedure pour l'installer.
 
*** Votre mission sera de la faire refonctionner et de la partager aux autres ***
 
Pour information je suis parti de l'exemple de OOconvert
http://delta-flyer.musc.edu/ooconvert/ 
Mais je n'ai ni besoin du Perl, ni besoin du Java.
 
PHP fait une requete au service de conversion  
Ce service de conversion est lancé via OpenOffice et le script Python associé
 
1/---> Installation de XVFB
 
Xorg doit être installé. 
Vérifier que xvfb est installé avec « up2date -i xorg-x11-Xvfb» 
Télécharger xvfb-run (--nodeps) à partir de http://distro.ibiblio.org/pub/linux/distributions/altlinux/Sisyphus/noarch/RPMS.master/xvfb-run-1.2-alt1.noarch.rpm 
Les dépendances requises sont résolues mais les noms de packages ne sont pas les même. Installer avec –nodeps.
 
2/---> Installation d’Open Office
 
up2date -i openoffice.org (ATTENTION, plutot utiliser yum) 
Telecharger si besoin le package openoffice.org-pyuno-2.0.1-1.i586.rpm pour supporter le langage python dans OpenOffice
 
3/---> Creation d'un utilisateur, par exemple oobatch
 
groupadd –g 5000 oobatch 
useradd –c "Utilisateur Batch conversion OOCONVERT" –d /home/oobatch –g 5000 –m –s /bin/bash –u 5000 oobatch 
cd /home/oobatch/ 
faire ls –al /home/oobatch et vérifier la presence de fichier .openoffice* (Si OpenOffice a déjà été lancé avec le user oobatch)
 
4/---> Installation du service de conversion
 
A la fin de /etc/rc.local, ajouter /usr/local/bin/ooconvert.daemon.sh.
 
Contenu du fichier /usr/local/bin/ooconvert.daemon.sh
 | #!/bin/bash su - oobatch -c 'nohup xvfb-run --server-args=":99 -fbdir /tmp" /usr/lib/ooo-1.1/program/soffice "-accept=socket,host=localhost,port=2002;urp;">/dev/null &'
 
 | 
Faire chmod 755 /usr/local/bin/ooconvert.daemon.sh 
Lancer le script /usr/local/bin/ooconvert.daemon.sh
  
Faire ps –ax. La sortie devrait contenir quelque chose de ce genre 
4757 pts/0    S      0:00 /bin/sh /usr/bin/xvfb-run --server-args=:99 -fbdir /tmp /usr/local/openoffice/program/soffice -acc 
4764 pts/0    S      0:00 Xvfb :99 :99 -fbdir /tmp -nolisten tcp 
4767 pts/0    S      0:03 /usr/local/openoffice/program/soffice.bin -accept=socket,host=localhost,port=2002;urp;
 
5/---> Installation des scripts Python
 
Mettez les 2 fichiers en Python qq part sur votre serveur, dans l'arborescence web par exemple 
Creer un repertoire "python" 
Mettre les 2 fichiers convooo_calc.py et convooo_writer.py 
Attention ils devront être executable par le user php (apache en general). A verifier pour l'utilisateur oobatch
 
NOTE : attention a ne pas modifier les tabulations et espaces des fichiers Python, car cela en modifie l'interprétation. 
Ce n'est pas comme le PHP ou l'on peut justifier comme l'on veut et le début et la fin des instructions sont données en général par les accolades { } 
Si vous avez un probleme, je pourrais vous envoyer les fichiers directement, ou je demanderais à Skrol de les mettre sur le site.
 
contenu du fichier : convooo_calc.py
 | #!/usr/local/openoffice/program/python 
 import getopt,sys
 import uno
 from unohelper import Base,systemPathToFileUrl, absolutize
 from os import getcwd
 
 from com.sun.star.beans import PropertyValue
 from com.sun.star.beans.PropertyState import DIRECT_VALUE
 from com.sun.star.uno import Exception as UnoException
 from com.sun.star.io import IOException,XInputStream, XOutputStream
 
 class OutputStream( Base, XOutputStream ):
 def __init__( self ):
 self.closed = 0
 
 def closeOutput(self):
 self.closed = 1
 
 def writeBytes( self, seq ):
 sys.stdout.write( seq.value )
 
 def flush( self ):
 pass
 
 def main():
 retVal = 0
 doc = None
 
 try:
 opts, args = getopt.getopt(sys.argv[1:], "hc:",["help", "connection-string=" , "csv", "dbf", "dif", "html", "pdf", "excel", "ps", "sylk"])
 format = None
 url = "uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext"
 filterName = "Text (Encoded)"
 for o, a in opts:
 if o in ("-h", "--help"):
 usage()
 sys.exit()
 if o in ("-c", "--connection-string" ):
 url = "uno:" + a + ";urp;StarOffice.ComponentContext"
 if o == "--cvs":
 filterName = "Text - txt - csv (StarCalc)"
 if o == "--dbf":
 filterName = "dBase"
 if o == "--dif":
 filterName = "DIF"
 if o == "--html":
 filterName = "HTML (CalcWriter)"
 if o == "--pdf":
 filterName = "calc_pdf_Export"
 if o == "--excel":
 filterName = "MS Excel 97"
 if o == "--ps":
 filterName = "calc_ps_Export"
 if o == "--sylk":
 filterName = "SYLK"
 #print filterName
 if not len( args ):
 usage()
 sys.exit()
 
 ctxLocal = uno.getComponentContext()
 smgrLocal = ctxLocal.ServiceManager
 
 resolver = smgrLocal.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", ctxLocal )
 ctx = resolver.resolve( url )
 smgr = ctx.ServiceManager
 
 desktop = smgr.createInstanceWithContext("com.sun.star.frame.Desktop", ctx )
 
 cwd = systemPathToFileUrl( getcwd() )
 outProps = (
 PropertyValue( "FilterName" , 0, filterName , 0 ),
 PropertyValue( "OutputStream",0, OutputStream(),0))
 inProps = PropertyValue( "Hidden" , 0 , True, 0 ),
 for path in args:
 try:
 fileUrl = uno.absolutize( cwd, systemPathToFileUrl(path) )
 doc = desktop.loadComponentFromURL( fileUrl , "_blank", 0,inProps)
 
 if not doc:
 raise UnoException( "Couldn't open stream for unknown reason", None )
 
 doc.storeToURL("private:stream",outProps)
 except IOException, e:
 sys.stderr.write( "Error during conversion: " + e.Message + "\n" )
 retVal = 1
 except UnoException, e:
 sys.stderr.write( "Error ("+repr(e.__class__)+") during conversion:" + e.Message + "\n" )
 retVal = 1
 if doc:
 doc.dispose()
 
 except UnoException, e:
 sys.stderr.write( "Error ("+repr(e.__class__)+") :" + e.Message + "\n" )
 retVal = 1
 except getopt.GetoptError,e:
 sys.stderr.write( str(e) + "\n" )
 usage()
 retVal = 1
 
 sys.exit(retVal)
 
 def usage():
 sys.stderr.write( "usage: ooextract.py --help |\n"+
 "       [-c <connection-string> | --connection-string=<connection-string>\n"+
 "       file1 file2 ...\n"+
 "\n" +
 "Extracts plain text from documents and prints it to stdout.\n" +
 "Requires an OpenOffice.org instance to be running. The script and the\n"+
 "running OpenOffice.org instance must be able to access the file with\n"+
 "by the same system path.\n"
 "\n"+
 "-c <connection-string> | --connection-string=<connection-string>\n" +
 "        The connection-string part of a uno url to where the\n" +
 "        the script should connect to in order to do the conversion.\n" +
 "        The strings defaults to socket,host=localhost,port=2002\n"
 "--html \n"
 "        Instead of the text filter, the writer html filter is used\n"
 )
 
 main()
 
 | 
contenu du fichier : convooo_writer.py
 | #!/usr/local/openoffice/program/python 
 import getopt,sys
 import uno
 from unohelper import Base,systemPathToFileUrl, absolutize
 from os import getcwd
 
 from com.sun.star.beans import PropertyValue
 from com.sun.star.beans.PropertyState import DIRECT_VALUE
 from com.sun.star.uno import Exception as UnoException
 from com.sun.star.io import IOException,XInputStream, XOutputStream
 
 class OutputStream( Base, XOutputStream ):
 def __init__( self ):
 self.closed = 0
 
 def closeOutput(self):
 self.closed = 1
 
 def writeBytes( self, seq ):
 sys.stdout.write( seq.value )
 
 def flush( self ):
 pass
 
 def main():
 retVal = 0
 doc = None
 
 try:
 opts, args = getopt.getopt(sys.argv[1:], "hc:",["help", "connection-string=" , "html", "pdf", "rtf", "text", "word"])
 format = None
 url = "uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext"
 filterName = "Text (Encoded)"
 for o, a in opts:
 if o in ("-h", "--help"):
 usage()
 sys.exit()
 if o in ("-c", "--connection-string" ):
 url = "uno:" + a + ";urp;StarOffice.ComponentContext"
 if o == "--html":
 filterName = "HTML (StarWriter)"
 if o == "--pdf":
 filterName = "writer_pdf_Export"
 if o == "--rtf":
 filterName = "Rich Text Format"
 if o == "--text":
 filterName = "Text"
 if o == "--word":
 filterName = "MS Word 97"
 #print filterName
 if not len( args ):
 usage()
 sys.exit()
 
 ctxLocal = uno.getComponentContext()
 smgrLocal = ctxLocal.ServiceManager
 
 resolver = smgrLocal.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", ctxLocal )
 ctx = resolver.resolve( url )
 smgr = ctx.ServiceManager
 
 desktop = smgr.createInstanceWithContext("com.sun.star.frame.Desktop", ctx )
 
 cwd = systemPathToFileUrl( getcwd() )
 outProps = (
 PropertyValue( "FilterName" , 0, filterName , 0 ),
 PropertyValue( "OutputStream", 0, OutputStream(),0))
 inProps = PropertyValue( "Hidden" , 0 , True, 0 ),
 for path in args:
 try:
 fileUrl = uno.absolutize( cwd, systemPathToFileUrl(path) )
 doc = desktop.loadComponentFromURL( fileUrl , "_blank", 0,inProps)
 
 if not doc:
 raise UnoException( "Couldn't open stream for unknown reason", None )
 
 doc.storeToURL("private:stream",outProps)
 except IOException, e:
 sys.stderr.write( "Error during conversion: " + e.Message + "\n" )
 retVal = 1
 except UnoException, e:
 sys.stderr.write( "Error ("+repr(e.__class__)+") during conversion:" + e.Message + "\n" )
 retVal = 1
 if doc:
 doc.dispose()
 
 except UnoException, e:
 sys.stderr.write( "Error ("+repr(e.__class__)+") :" + e.Message + "\n" )
 retVal = 1
 except getopt.GetoptError,e:
 sys.stderr.write( str(e) + "\n" )
 usage()
 retVal = 1
 
 sys.exit(retVal)
 
 def usage():
 sys.stderr.write( "usage: ooextract.py --help |\n"+
 "       [-c <connection-string> | --connection-string=<connection-string>\n"+
 "       file1 file2 ...\n"+
 "\n" +
 "Extracts plain text from documents and prints it to stdout.\n" +
 "Requires an OpenOffice.org instance to be running. The script and the\n"+
 "running OpenOffice.org instance must be able to access the file with\n"+
 "by the same system path.\n"
 "\n"+
 "-c <connection-string> | --connection-string=<connection-string>\n" +
 "        The connection-string part of a uno url to where the\n" +
 "        the script should connect to in order to do the conversion.\n" +
 "        The strings defaults to socket,host=localhost,port=2002\n"
 "--html \n"
 "        Instead of the text filter, the writer html filter is used\n"
 "--pdf \n"
 "        Instead of the text filter, the writer pdf filter is used\n"
 )
 
 main()
 
 | 
6/---> Installation de la bibliothèque PHP
 
Mettez le fichier ci-dessous avec vos bibliothèques
 
contenu de : convooo_class.php
 | <?php /*
 ********************************************************
 ConvOOo
 ********************************************************
 Author   : Olivier LOYNET (tbsooo@free.fr)
 Version  : 0.1.5
 Require  : PHP >= 4.0.6
 Date     : 2005-09-24
 Web site : www.tinybutstrong.com
 ********************************************************
 Released under the GNU GPL license
 http://www.gnu.org/copyleft/gpl.html
 ********************************************************
 Inspired and enhanced from :
 http://delta-flyer.musc.edu/ooconvert/
 Don't have to use the Perl scripts in /cgi-bin
 ********************************************************
 */
 
 class clsConvOOo
 {
 // ===== public properties =====
 
 var $source_filename       = '';
 var $target_type           = '';
 var $target_filename       = '';
 var $error_message         = '';
 
 // ===== private properties =====
 
 var $_python_bin           = '';
 var $_python_script_dir    = '';
 var $_python_script_calc   = 'convooo_calc.py';
 var $_python_script_writer = 'convooo_writer.py';
 
 // ===== constructor =====
 
 function clsConvOOo()
 {
 }
 
 // ===== public method =====
 
 function SetPythonBin($binary)
 {
 // set the binary for 'Python scripts'
 if ($binary == '') {
 $this->error_message = 'Python binary not set';
 return false;
 }
 $this->_python_bin = $this->_BinaryQuote($binary);
 return true;
 }
 
 function SetPythonScriptDir($path)
 {
 // set the path Python script directory
 $this->_python_script_dir = $path.($path != '' && substr($path, -1, 1) != '/' ? '/' : '');
 }
 
 function SetPythonScriptCalc($script)
 {
 // set the Python script calc
 if ($script == '') {
 $this->error_message = 'Python script to convert calc is not set';
 return false;
 }
 if (!file_exists($this->_python_script_dir.$script)) {
 $this->error_message = 'Python script \''.$script.'\' not found in dir \''.$this->_python_script_dir.'\'';
 return false;
 }
 if (!is_executable($this->_python_script_dir.$script)) {
 $this->error_message = 'Python script \''.$script.'\' can\'t be executed';
 return false;
 }
 $this->_python_script_calc = $script;
 return true;
 }
 
 function SetPythonScriptWriter($script)
 {
 // set the Python script writer
 if ($script == '') {
 $this->error_message = 'Python script to convert writer is not set';
 return false;
 }
 if (!file_exists($this->_python_script_dir.$script)) {
 $this->error_message = 'Python script \''.$script.'\' not found in dir \''.$this->_python_script_dir.'\'';
 return false;
 }
 if (!is_executable($this->_python_script_dir.$script)) {
 $this->error_message = 'Python script \''.$script.'\' can\'t be executed';
 return false;
 }
 $this->_python_script_writer = $script;
 return true;
 }
 
 function Convert($source_filename, $target_type)
 {
 $this->source_filename = $source_filename;
 $this->target_type     = strtolower($target_type);
 $this->target_filename = '';
 
 $shell_command = $this->_GetPythonShellCommand();
 if ($shell_command === false) {
 return false;
 } else {
 // execute shell command
 return shell_exec($shell_command);
 }
 }
 
 function ConvertToFile($source_filename, $target_type, $target_filename = '')
 {
 $this->source_filename = $source_filename;
 $this->target_type     = strtolower($target_type);
 $this->target_filename = ($target_filename == '' ? $this->source_filename.'.'.$this->target_type : $target_filename);
 
 $shell_command = $this->_GetPythonShellCommand();
 
 if ($shell_command === false) {
 return false;
 } else {
 exec($shell_command);
 // return target filename
 return $this->target_filename;
 }
 }
 
 function RemoveDoc()
 {
 if ($this->target_filename != '' && file_exists($this->target_filename)) {
 unlink ($this->target_filename);
 }
 }
 
 // ===== private method =====
 
 function _GetPythonShellCommand()
 {
 // define the python script depends on the OOo document type
 $script_name = array();
 $script_name['sxc'] = $this->_python_script_calc;
 $script_name['stc'] = $this->_python_script_calc;
 $script_name['sdc'] = $this->_python_script_calc;
 $script_name['ods'] = $this->_python_script_calc;   // OpenDocument Spreadsheet
 $script_name['ots'] = $this->_python_script_calc;   // OpenDocument Spreadsheet Template
 $script_name['sxw'] = $this->_python_script_writer;
 $script_name['stw'] = $this->_python_script_writer;
 $script_name['sdw'] = $this->_python_script_writer;
 $script_name['odt'] = $this->_python_script_writer; // OpenDocument Text
 $script_name['ott'] = $this->_python_script_writer; // OpenDocument Text Template
 
 // define the convert parameter depend on the OOo document type and the python script
 $convert_type = array();
 $convert_type[$this->_python_script_calc]['csv']   = '--csv';
 $convert_type[$this->_python_script_calc]['dbf']   = '--dbase';
 $convert_type[$this->_python_script_calc]['dif']   = '--dif';
 $convert_type[$this->_python_script_calc]['htm']   = '--html';
 $convert_type[$this->_python_script_calc]['pdf']   = '--pdf';
 $convert_type[$this->_python_script_calc]['xls']   = '--excel';
 $convert_type[$this->_python_script_calc]['slk']   = '--sylk';
 $convert_type[$this->_python_script_writer]['pdf'] = '--pdf';
 $convert_type[$this->_python_script_writer]['htm'] = '--html';
 $convert_type[$this->_python_script_writer]['txt'] = '--text';
 $convert_type[$this->_python_script_writer]['rtf'] = '--rtf';
 $convert_type[$this->_python_script_writer]['doc'] = '--word';
 
 // test if Python binary is set
 if ($this->_python_bin == '') {
 $this->error_message = 'Python binary not fixed';
 return false;
 }
 // test if Python binary exists
 if (!file_exists($this->_python_bin)) {
 $this->error_message = 'Python binary not exists';
 return false;
 }
 // test if source filename exists
 if (!file_exists($this->source_filename)) {
 $this->error_message = 'OpenOffice file not exists : \''.$this->source_filename.'\'';
 return false;
 }
 // get the document extension
 $source_extension = '';
 $a_pathinfo = pathinfo($this->source_filename);
 $source_extension = strtolower($a_pathinfo['extension']);
 
 // test if the OOo document can be convert
 if (!isset($script_name[$source_extension])) {
 $this->error_message = 'can convert only OpenOffice files with extension : sxc, stc, sdc, ods, ots, sxw, stw, sdw, odt, ott';
 return false;
 }
 
 // test if the Python script exists
 if (!file_exists($this->_python_script_dir.$script_name[$source_extension])) {
 $this->error_message = 'Python script file not exists';
 return false;
 }
 // test if the source document could be convert by the python script to the target type
 if (!isset($convert_type[$script_name[$source_extension]][$this->target_type])) {
 $this->error_message = 'target type : \''.$this->target_type.'\' not exists in Python script \''.$script_name[$source_extension].'\'';
 return false;
 }
 // test if target directory exist or is writable
 if ($this->target_filename != '') {
 if (!is_dir(dirname($this->target_filename))) {
 $this->error_message = 'target directory not found : \''.dirname($this->target_filename).'\'';
 return false;
 }
 if (!is_writable(dirname($this->target_filename))) {
 $this->error_message = 'target directory not writable : \''.dirname($this->target_filename).'\'';
 return false;
 }
 if (file_exists($this->target_filename)) {
 $this->error_message = 'target filename already exist : \''.$this->target_filename.'\'';
 return false;
 }
 }
 
 // generate shell command
 $command = $this->_python_bin;
 $command.= ' '.$this->_python_script_dir.$script_name[$source_extension];
 $command.= ' '.$convert_type[$script_name[$source_extension]][$this->target_type];
 $command.= ' '.$this->source_filename;
 $command.= ($this->target_filename != '' ? ' > '.$this->target_filename : '');
 return $command;
 }
 
 function _BinaryQuote($binary)
 {
 if (strpos($binary, ' ') !== false) {
 $binary = (strpos($binary, '"') === 0 ? '' : '"').$binary;
 $binary = $binary.((strrpos($binary, '"') == strlen($binary)-1) ? '' : '"');
 }
 return $binary;
 }
 }
 ?>
 
 | 
7/---> Exemple d'utilisation en PHP pour la conversion du fichier OpenOffice en PDF ou autre
 | define('BIN_ZIP'      , 'zip'); define('BIN_UNZIP'    , 'unzip');
 define('BIN_OOO'      , '/opt/soffice/program/soffice');
 define('BIN_PYTHON'   , '/usr/lib/ooo-1.1/program/python');
 define('SCRIPT_PYTHON', 'python');
 
 include_once('./inc/convooo_class.php');
 $conv = new clsConvOOo();
 $conv->SetPythonBin(BIN_PYTHON);
 $conv->SetPythonScriptDir(SCRIPT_PYTHON);
 $new_filename = $conv->ConvertToFile('fichier_openoffice.sxw', 'pdf');
 
 | 
Et voila le travail, pas si simple mais cela fonctionne sans probleme sur un serveur depuis 2 ans
 
Olivier
 |