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.
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.
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...
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.
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 :
oDocument=oDesktop.loadComponentFromURL(surl,"_blank",0,Noargs())
What I'm looking for is a reference to oDocument, but without it being visible, much like the invisible switch when you start OpenOffice.org from the command line.dim args(0) as new com.sun.star.beans.PropertyValue
args(0).Name = "Hidden"
args(0).Value = True
dim tab() as string
oGraphic=CreateUnoService("com.sun.star.drawing.GraphicExportFilter")
tab=ographic.getSupportedMimeTypeNames()
for i=0 to ubound(tab)
msgbox(tab(i))
next i
Check out the macro to see how they're used.sub ExportDocumentPDF
rem -----------------------------------------------------
rem define variables
dim doc as object, desktop as object
dim args() as new com.sun.star.beans.PropertyValue
rem -----------------------------------------------------
rem get access to the document
oDesktop=createUnoService("com.sun.star.frame.Desktop")
sUrl="file:///test.sxw"
doc=oDesktop.loadComponentFromURL(surl,"_blank",0,args())
rem -----------------------------------------------------
Dim PDFArgs(1) as new com.sun.star.beans.PropertyValue
PDFArgs(0).Name = "FilterName"
PDFArgs(0).Value = "writer_pdf_Export"
PDFArgs(1).Name = "CompressMode"
PDFArgs(1).Value = 0 'Valeurs possibles : 0 - 1 - 2
doc.storeToURL("file:///test.pdf",PDFArgs())
doc.dispose()
end sub
There is an interresting XML file in OpenOffice.org directories.If you have any questions, and particularly if you have any answers to my questions, please a drop me a line.
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...
<?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);
};
?>
'************************************************
'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