OOoConv

On-line converter

Logo OOoConv

The idea behind this converter came about on the OpenOffice.org Franocophone native language list. I'll indicate the general outline of the application on this pages, where I see the project to be going in the future, and the various details of the source code that is used. I would add that this is only represents my personal view of the converter and is in no way an official representation from the OpenOffice.org project.

Historical tools

OpenOffice.org version 1.1 beta was used. I chose this version because it can natively export files to the PDF format, as well as record macros. The host machine uses a Windows operating system., on which I've installed easyPhP (version 1.6) that includes Apache and PHP4. All of this is connected to a ADSL with a dynamic DNS for the domain name.

The Architecture

Originally, this converter had been intended just to produce online PDF export capabilities for SXW files. The resulting file was initially sent to the requester by e-mail. The project then evolved into an attempt to provide a greater variety of export formats. Since I received several comments from users pertaining to user data privacy and the law in France, I unplugged the mailing functionality, which is just as well because the server wasn't intended to the final home of the converter anyway. As a result of this, once the file is processed, a link is now offered that gives the user the choice of viewing or downloading the converted document.

On the first page, the user indicates the type of OpenOffice.org that he/she wants to convert, and the intended converted output format.
The form that is filled in is checked for conformity and then sent to a PhP script that does the following :

In this way, the user can see the result of the conversion immediately, just by clicking on the link, and then "saving as" if he/she is satisfied with the appearance. The session files are kept at most for 24h.
I would like to thank Frederic Labbe for his advice on the use of PhP and e-mail, as well as the whole community for having participated in the tests, that are still ongoing...

Supported export format table

Supported export format table
OpenOffice.org file extension Available export formats
Writer : SXW, STW, SDW, VOR Acrobat PDF
HTML
Latex 2e (Writer2Latex)
XHTML + MathML (Writer2Latex)
RTF
MS Word 97/2000/XP
MS Word 95
MS Word 6.0
Calc : SXC, STC, SDC Acrobat PDF
HTML
MS Excel 97/2000/XP
MS Excel 95
MS Excel 5.0
Draw : SXD, STD, SDD, SDA Acrobat PDF
Macromedia Flash
Image JPG
Image PNG
Image EPS
Image TIFF
Image SVG
Impress : SXI, STI, SDP Acrobat PDF
MS PowerPoint 97/2000/XP
Macromedia Flash
Image JPG
Image PNG
Image EPS
Image TIFF
Image SVG

Warning : not all of these combinations have been tested yet. Please inform me of any that do not work or cause problems.

Unanswered questions

Of course, nothing is perfect ! Here are a few points where I'm still experiencing problems (or I did experience ones). First of all, some documentation links :


If you have any questions, and particularly if you have any answers to my questions, please a drop me a line.

Future developpement

Source code

The sources published here are made freely available under the GNU LGPL licence. If something seems a bit unclear, just get in touch with me, I may be a bit convoluted in my programming at times...

Form.php

<?php /* Copyright (C) 2003 Laurent Godard oooconv@free.fr This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); header("Cache-Control: no-cache, must-revalidate"); header("Pragma: no-cache"); error_reporting (E_ALL); echo("<html><head><meta http-equiv=\"Content-Type\" "); echo("content=\"text/html; charset=iso-8859-1\">"); echo (" <style type=\"text/css\"><!-- A:link {text-decoration: none;} A:visited {text-decoration: none;} A:active {text-decoration: none;} A:hover {text-decoration: none; color:red;} --></style> "); // logo echo("</head><body bgcolor=\"#D3ECFF\">"); echo("<center><img src=\"ooobanner.gif\" border=\"1\"></center>"); echo("<br><br>"); //Chargement du fichier de langue //Load the language file $IndPage="2"; include "tradOOO.inc"; //ajout pour oooconv.de $lang=$_POST['lang']; $trad=ChargeLang($lang, $IndPage); //Recherche du chemin Prod/Dev - seeking for root prod/Dev $a=strpos($_SERVER['PATH_TRANSLATED'],"form.php"); $racine=substr($_SERVER['PATH_TRANSLATED'],0,$a); //Renseignez ici le chemin absolu du répertoire http de OOOconv $oooconv_home="/home/httpd/oooconv.de/engine/"; $nom_fichier=$_FILES["file"]["name"]; $nom_fichier=str_replace(" ","-",$nom_fichier); $nom_fichier=str_replace(",","-",$nom_fichier); $nom_fichier=str_replace("'","-",$nom_fichier); for ($i = 0 ; $i<strlen($nom_fichier) ; $i++) { $chaine=substr($nom_fichier,$i,1); if((ord($chaine)<32)||(ord($chaine)>128)) { $nom_fichier=substr_replace($nom_fichier,"_",$i,1); } } //code de session - session code $code=UniqueID(); //Creation du repertoire de session - Create session directory $chemin=$racine . "temp/$code"; mkdir ( $chemin , 0777); $dest="temp/$code/" . $nom_fichier; $retour = move_uploaded_file ($_FILES['file']['tmp_name'] , $dest ); echo("<b>" . $nom_fichier . "</b> : $trad[1]"); //code de session - session code $code=UniqueID(); $type_doc = $_POST['type_doc']; //Cherche l'extension du fichier généré - Look for the file extension of the generated file $ExtFin=TrouveExtension($dest,$type_doc,$IsZip,$ExtSrc); //Test de compatibilité de l'export - Export compatibility test if($ExtFin=="") { echo("<br><br><b><font size=\"+1\" color=\"red\">"); echo("$trad[2]"); echo("<br><br>$trad[3]"); echo("<br><br>$trad[4]"); echo("</font></b>"); echo("<br><br>"); $retour="<b><u><a href='javascript:history.back()'> $trad[5] </a></u></b>"; echo("$retour"); exit; }; //cas des fichiers resultats multiples - Multiple output files if ($IsZip !=0){ //$chemin=$racine . "temp\\$code.$type_doc"; $chemin=$racine . "temp/$code/$type_doc"; mkdir ( $chemin , 0777); if ($type_doc=="TEX"){ copy("writer.sty",$chemin."/writer.sty"); }; }; // Appel de la macro par transforme.bat contenant juste la ligne suivante // call the macro via transforme.bat that only contains the following line // "<ooo path>\program\soffice.exe" macro:///convOOO.Module1.Test("%1,%2,%3") echo("<br><br>"); echo("$trad[6]"); $execution=" HOME=\"/home/httpd\" ".$oooconv_home."transforme.sh ". $racine.$dest ; $execution = $execution . " " . $type_doc . " " . $code ; $execution = $execution . " 2>&1 > /tmp/test.txt"; exec( $execution ); echo("<br>"); //Test de bon déroulement du script == Existence du fichier cible // Test correct execution of the script $erreur=0; //Fichier de stats - Stat file log $fp = fopen("Stats.log", "a+"); $string ="\n".date("Y/m/d H:i:s")."|$ExtSrc|$type_doc|$erreur|$lang"; $write = fputs($fp, $string); fclose($fp); if ($erreur==0) { $filename = $racine.$dest.$ExtFin; $AjoutHTML=""; if ($IsZip !=0) { $AjoutHTML=".zip"; } //liens de fin - end links echo("<br><br>"); $fic=""; if ($IsZip!=0) { echo("$trad[8]"); echo("<br><br>"); $fic="temp/$code/$type_doc/$nom_fichier$ExtFin"; //zip repertoire - zip directory ZipRepertoire("temp/".$code."/".$type_doc, $nom_fichier .$ExtFin, $code); //creation de la page de consultation - creating the viewing page if ($IsZip==2) { $string = "<html><body bgcolor=\"#D3ECFF\">"; $string.="<font size=\"+1\"><b>$trad[9]</b></font><br><br>"; //examen du repertoire - scanning the directory $rep=$racine."temp/$code/$type_doc"; if ($dh = opendir($rep)) { while (($f = readdir($dh)) !== false) { if ($f!="." and $f!="..") { $string.="<br><a href=\"$f\">$f</a>"; } } closedir($dh); } $string .="<br><br><a href=\"../$nom_fichier$ExtFin$AjoutHTML\; $string .=">$trad[10]</a>"; $string .="<br><br><a href='javascript:history.go(-2)'>$trad[5]</a>"; $fic="temp/$code/$type_doc/voir.html"; $fp = fopen($racine."/temp/$code/$type_doc/voir.html", "w"); $write = fputs($fp, $string); fclose($fp); } else { $string ="<br><a href=\"temp/$code/$nom_fichier$ExtFin$AjoutHTML\; $qtring .=">$trad[10]</a><br><br>"; echo($string); } } else { $fic= $dest.$ExtFin; } } $retour="<b><u><a href=\"$fic\"> $trad[11] </a></u></b>"; echo("$retour"); echo("<br><br>"); $retour="<b><u><a href='javascript:history.back()'> $trad[5] </a></u></b>"; echo("$retour"); echo("</body></html>"); // //----------------------------------------------------------------------------------------- //Fin du script //end of the script //----------------------------------------------------------------------------------------- // function TrouveExtension($dest,$type_doc,&$IsZip,&$ExtSrc){ //recherche de l'extension cible suivant le format d'entré sxc ou sxw //et le type d'export demandé //look for the target file extension according to the entrance file extension // and the kind of export required $ExtSrc =strtoupper(substr($dest,-3)); $ExtFin=""; $IsZip=0; switch ($ExtSrc) { case "SXC" : case "STC" : case "SDC" : switch($type_doc) { case "PDF": $ExtFin=".pdf"; break; case "MSXP": case "MS95": case "MS50": $ExtFin=".xls"; break; case "HTML": $ExtFin=".html"; $IsZip=1; break; }; break; case "SXW" : case "STW" : case "SDW" : case "VOR" : switch($type_doc) { case "PDF": $ExtFin=".pdf"; break; case "MSXP": case "MS95": case "MS60": $ExtFin=".doc"; break; case "RTF": $ExtFin=".rtf"; break; case "HTML": $ExtFin=".html"; $IsZip=1; break; case "XHTML": $ExtFin=".xhtml"; $IsZip=2; break; case "TEX": $ExtFin=".tex"; $IsZip=2; break; }; break; case "SXI" : case "STI" : case "SDP" : switch($type_doc) { case "PDF": $ExtFin=".pdf"; break; case "MSXP": $ExtFin=".ppt"; break; case "HTML": $ExtFin=".html"; $IsZip=1; break; case "JPG": $ExtFin=".jpg"; $IsZip=2; break; case "PNG": $ExtFin=".png"; $IsZip=2; break; case "TIFF": $ExtFin=".tif"; $IsZip=2; break; case "SVG": $ExtFin=".svg"; $IsZip=2; break; case "EPS": $ExtFin=".eps"; $IsZip=2; break; case "SWF": $ExtFin=".swf"; $IsZip=2; break; }; break; case "SXD" : case "STD" : case "SDD" : case "SDA" : switch($type_doc) { case "PDF": $ExtFin=".pdf"; break; case "JPG": $ExtFin=".jpg"; $IsZip=2; break; case "PNG": $ExtFin=".png"; $IsZip=2; break; case "TIFF": $ExtFin=".tif"; $IsZip=2; break; case "EPS": $ExtFin=".eps"; $IsZip=2; break; case "SVG": $ExtFin=".svg"; $IsZip=2; break; case "SWF": $ExtFin=".swf"; $IsZip=2; break; }; break; }; return $ExtFin; } // ---------------------------------------------------------------------------- function UniqueID() { $id="uniqueID"; $i=0; srand(time()); $a="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; for($i; $i<=16; $i++) { $id.=substr($a, (rand()%(strlen($a))),1); } return(md5($id)); } // ---------------------------------------------------------------------------- function ZipRepertoire($rep, $FichierFin,$code){ require("pclzip.lib.php3"); $fichier=array(); /* Liste les fichiers - File list */ $i=-1; if ($dh = opendir($rep)) { while (($file = readdir($dh)) !== false) { if ($file!="." and $file!=".." and $file!="voir.html"){ $i+=1; $fichier[$i] = $rep."/".$file; }; } closedir($dh); }; $fichier_zip = "temp/$code/".$FichierFin.".zip"; // nom du fichier zip a obtenir - zip file name to get // On crée un nouvel objet zip de la classe zipfile // create a new zip object having the zipfile class $zip= new pclzip($fichier_zip); // On efface l'ancienne archive si zip.zip existe déja // (sinon les fichiers identiques sont ajoutés en fin d'archive !!!) // delete old archive if zip.zip already exists // (otherwise the files are added to the end of the archive !!!) $taille = sizeof($zip->listContent()) -1; $zip->deleteByIndex(0-$taille); // On lui ajoute le fichier voulu avec ou sans chemin pour l'extraction // then add the desired file with or without its path for extraction $zip->add($fichier,$FichierFin,$rep); }; ?>

Macro

'************************************************ 'Copyright (C) 2003 Laurent Godard 'oooconv@free.fr 'This library is free software; you can redistribute it and/or 'modify it under the terms of the GNU Lesser General Public 'License as published by the Free Software Foundation; either 'version 2.1 of the License, or (at your option) any later version. 'This library is distributed in the hope that it will be useful, 'but WITHOUT ANY WARRANTY; without even the implied warranty of 'MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 'Lesser General Public License for more details. 'You should have received a copy of the GNU Lesser General Public 'License along with this library; if not, write to the Free Software 'Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA '************************************************ dim FilterName as string dim ExtDESt as string dim FichDest as string Sub Exporte(fichier, typedoc,code) call DefinirFiltre(fichier, typedoc,code) call TransformeDocument(fichier,TypeDoc,code) End Sub sub DefinirFiltre(fichier, typedoc,code) 'Determine quel type d'export faire ExtSRC=lcase(right(fichier,3)) fichdest=fichier Select case ExtSRc case "sxc","stc","sdc": select case typedoc case "PDF": FilterName="calc_pdf_Export" ExtDESt=".pdf" case "MSXP": FilterName="MS Excel 97" ExtDESt=".xls" case "MS95": FilterName="MS Excel 95" ExtDESt=".xls" case "MS50": FilterName="MS Excel 5.0/95" ExtDESt=".xls" case "HTML": FilterName="HTML (StarCalc)" ExtDESt=".html" FichDest=TrouveNomRep(fichier,code,typedoc) end select case "sxw","vor","stw","sdw": select case typedoc case "PDF": FilterName="writer_pdf_Export" ExtDESt=".pdf" case "MSXP": FilterName="MS Word 97" ExtDESt=".doc" case "MS95": FilterName="MS Word 95" ExtDESt=".doc" case "MS60": FilterName="MS WinWord 6.0" ExtDESt=".doc" case "RTF": FilterName="Rich Text Format" ExtDESt=".rtf" case "HTML": FilterName="HTML (StarWriter)" ExtDESt=".html" FichDest= TrouveNomRep(fichier,code,typedoc) case "XHTML": FilterName="XHTML plus MathML File" ExtDESt=".xhtml" FichDest= TrouveNomRep(fichier,code,typedoc) case "TEX": FilterName="Latex File" ExtDESt=".tex" FichDest= TrouveNomRep(fichier,code,typedoc) end select case "sxi","sti","sdd","sdp": select case typedoc case "PDF": FilterName="impress_pdf_Export" ExtDESt=".pdf" case "MSXP": FilterName="MS Powerpoint 97" ExtDESt=".ppt" case "JPG": FilterName="image/jpeg" ExtDESt=".jpg" FichDest= TrouveNomRep(fichier,code,typedoc) case "PNG": FilterName="image/png" ExtDESt=".png" FichDest= TrouveNomRep(fichier,code,typedoc) case "TIFF": FilterName="image/tiff" ExtDESt=".tif" FichDest= TrouveNomRep(fichier,code,typedoc) case "SVG": FilterName="image/svg+xml" ExtDESt=".svg" FichDest= TrouveNomRep(fichier,code,typedoc) case "EPS": FilterName="application/postscript" ExtDESt=".eps" FichDest= TrouveNomRep(fichier,code,typedoc) case "SWF": FilterName="impress_flash_Export" ExtDESt=".swf" FichDest= TrouveNomRep(fichier,code,typedoc) end select case "sxd","std","sda","sdd": select case typedoc case "PDF": FilterName="draw_pdf_Export" ExtDESt=".pdf" case "JPG": FilterName="image/jpeg" ExtDESt=".jpg" FichDest= TrouveNomRep(fichier,code,typedoc) case "PNG": FilterName="image/png" ExtDESt=".png" FichDest= TrouveNomRep(fichier,code,typedoc) case "TIFF": FilterName="image/tiff" ExtDESt=".tif" FichDest= TrouveNomRep(fichier,code,typedoc) case "SVG": FilterName="image/svg+xml" ExtDESt=".svg" FichDest= TrouveNomRep(fichier,code,typedoc) case "EPS": FilterName="application/postscript" ExtDESt=".eps" FichDest= TrouveNomRep(fichier,code,typedoc) case "SWF": FilterName="draw_flash_Export" ExtDESt=".swf" FichDest= TrouveNomRep(fichier,code,typedoc) end select end select end sub sub TransformeDocument(fichier,TypeDoc,code) on error resume next dim args() 'dim args(0) as new com.sun.star.beans.PropertyValue 'args(0).Name = "Hidden" 'args(0).Value = True dim oDesktop as object, oDocument as object dim surl as string oDesktop=createUnoService("com.sun.star.frame.Desktop") sURL=ConvertToURL(fichier) oDocument=oDesktop.loadComponentFromURL(surl,"_blank",0,args()) on error goto fin fichdest=ConvertToUrl(fichdest) select case typedoc 'graphical exports case "JPG", "PNG", "TIFF","EPS","SVG": oGraphic=CreateUnoService("com.sun.star.drawing.GraphicExportFilter") dim args3(1) as new com.sun.star.beans.PropertyValue for i=0 to odocument.drawpages.getcount()-1 opage=odocument.drawPages(i) ographic.setSourceDocument(opage) args3(0).Name = "URL" nom=opage.name url = ConvertToURL(fichdest+"-"+RemplaceChaine(nom," ","")+ ExtDest) args3(0).Value = url args3(1).Name = "MediaType" args3(1).Value = filtername oGraphic.filter(args3()) next i 'all other exports case else: dim args2(1) as new com.sun.star.beans.PropertyValue args2(0).Name = "InteractionHandler" args2(0).Value = "" args2(1).Name = "FilterName" args2(1).Value = FilterName NomFichier = ConvertToUrl(fichdest + ExtDest) wait(100) odocument.storeToURL(NomFichier,args2()) end select wait(100) oDocument.dispose() exit sub fin: on error resume next oDocument.dispose() end sub function CorrigeNom(chaine as string) as string 'Remplace les antislash chaine=remplacechaine(chaine,"\","/") 'Remplace les deux points chaine=remplacechaine(chaine,":","|") CorrigeNom=chaine end function function TrouveNomRep(chemin as string,code as string,typedoc as string) as string i=instr(1,chemin,"/temp/"+code+"/")+len("/temp/"+code+"/")-1 j=len(chemin)+1 nomfichier=mid(chemin,i,j-i) TrouveNomRep=mid(chemin,1,i)+typedoc+nomfichier end function function RemplaceChaine(chaine as string,src as string, dest as string) 'remplace toutes les occurences de src par dest dans chaine i=1 lsrc = len(src) ldest = len(dest) while i<>0 i = instr(i,chaine,src) if i<>0 then imax = len(chaine) avant=mid(chaine,1,i-1) apres=mid(chaine,i+lsrc,imax-i) chaine=avant + dest +apres i=i+ldest-lsrc+1 end if wend RemplaceChaine=chaine end function

Download OOoConv