Convertion PDF avec OOo et UNO


Il existe plusieurs types d'outils qui permettent de transformer un document Word ou OpenOffice en PDF :

Toutes ces procédures sont manuelles, alors que mon but était de lancer les conversions en ligne de commande ou depuis une application java. En me basant sur la documentation et les exemples d'OpenOffice, j'ai développé cette classe qui utilise l'API UNO :

 package fr.sewatech.sewatoool.pdf;
 
 import java.io.File;
 import java.net.MalformedURLException;
 
 import com.sun.star.beans.PropertyValue;
 import com.sun.star.comp.helper.Bootstrap;
 import com.sun.star.frame.XComponentLoader;
 import com.sun.star.frame.XStorable;
 import com.sun.star.io.IOException;
 import com.sun.star.lang.IllegalArgumentException;
 import com.sun.star.lang.XMultiComponentFactory;
 import com.sun.star.uno.UnoRuntime;
 import com.sun.star.uno.XComponentContext;
 import com.sun.star.uri.ExternalUriReferenceTranslator;
 
 public class PdfConverter {
 
   public static void main(String[] args) {
     try {
       new PdfConverter().convert("D:\\Temp\\tmp.doc");
     } catch (Exception e) {
       e.printStackTrace();
     } finally {
       System.exit(0);
     }
   }
   
   private XComponentContext xContext;
   private Object component;
   private Object desktop;
   
   /**
    * Convertit un fichier en PDF
    * 
    * @param filename
    * @throws Exception
    */
   public void convert(String filename) throws Exception {
     startOpenOffice();
     String unoUrl = loadDocument(filename);
     generatePdf(unoUrl);
   }
   
   private void generatePdf(String unoUrl) throws IOException {
     XStorable xStorable = (XStorable) UnoRuntime.queryInterface(
     XStorable.class, component);
     
     PropertyValue[] convertProperties = new PropertyValue[2];
     convertProperties[0] = new PropertyValue();
     convertProperties[0].Name = "Overwrite";
     convertProperties[0].Value = true;
     
     convertProperties[1] = new PropertyValue();
     convertProperties[1].Name = "FilterName";
     convertProperties[1].Value = "writer_pdf_Export";
     
     xStorable.storeToURL(unoUrl.substring(0, unoUrl.lastIndexOf('.')) + ".pdf", convertProperties);
   }
   
   /**
    * Chargement d'un fichier OpenOffice
    * 
    * @param filename
    * @return
    * @throws MalformedURLException
    * @throws IOException
    * @throws IllegalArgumentException
    */
   private String loadDocument(String filename) throws MalformedURLException, IOException, IllegalArgumentException {
     XComponentLoader loader = (XComponentLoader) UnoRuntime.queryInterface(XComponentLoader.class, desktop);
     
     String unoUrl = formatUnoUrl(filename);
     
     // Value=true => pas d'interface graphique
     PropertyValue[] loadProperties = new PropertyValue[1];
     loadProperties[0] = new PropertyValue();
     loadProperties[0].Name = "Hidden";
     loadProperties[0].Value = true;
     
     component = loader.loadComponentFromURL(unoUrl, "_blank", 0,loadProperties);
     return unoUrl;
   }
   
   /**
    * Démarrage d'OpenOffice
    * 
    * @return Instance d'OOo avec contexte
    * @throws Exception
    */
   private Object startOpenOffice() throws Exception {
     xContext = Bootstrap.bootstrap();
     XMultiComponentFactory xMCF = xContext.getServiceManager();
     
     desktop = xMCF.createInstanceWithContext("com.sun.star.frame.Desktop", xContext);
     return desktop;
   }
   
   /**
    * Formatte un chemin traditionnel en chemin compatible UNO 
    * 
    * @param filename Chemin du fichier, au format traditionnel
    * @return Chemin du fichier, au format UNO
    * @throws MalformedURLException 
    */
   private String formatUnoUrl(String filename) throws MalformedURLException {
     String unoUrl = ExternalUriReferenceTranslator.create(xContext)
                                                   .translateToInternal(new File(filename).toURL().toExternalForm());
     return unoUrl;
   }
 }

Cette classe reste rudimentaire, mais est déjà fonctionnelle. Elle peut être intégrée dans une application ou, moyennant une petite adaptation du main, utilisée en ligne de commande.