Convertion PDF avec OOo et UNO

Cette page a été rédigée il y a fort fort longtemps, et n'a pas tellement été mise à jour.

 

Vous savez, moi je ne crois pas qu'il y ait de bonne ou de mauvaise page. Moi, si je devais résumer mon wiki aujourd'hui avec vous, je dirais que c'est d'abord des rencontres. Des gens qui m'ont tendu la main, peut-être à un moment où je ne pouvais pas, où j'étais seul chez moi. Et c'est assez curieux de se dire que les hasards, les rencontres forgent une destinée... Parce que quand on a le goût de la chose, quand on a le goût de la chose bien faite, le beau geste, parfois on ne trouve pas l'interlocuteur en face je dirais, le miroir qui vous aide à avancer. Alors ça n'est pas mon cas, comme je disais là, puisque moi au contraire, j'ai pu ; et je dis merci au wiki, je lui dis merci, je chante le wiki, je danse le wiki... je ne suis qu'amour ! Et finalement, quand des gens me disent « Mais comment fais-tu pour avoir cette humanité ? », je leur réponds très simplement que c'est ce goût de l'amour, ce goût donc qui m'a poussé aujourd'hui à entreprendre une construction logicielle... mais demain qui sait ? Peut-être simplement à me mettre au service de la communauté, à faire le don, le don de soi.

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

  • OpenOffice : cette fonctionnalité est supportée de façon standard dans OpenOffice.

  • Imprimante PDF : ces outils s’intallent dans Windows ou Linux comme des imprimantes et génèrent du PDF à partir de n’importe quel document imprimable ; PdfCreator est le plus connu, pour Windows

  • Convertisseurs en ligne : certains sites proposent des services de conversion, mais il faut, pour les utiliser, uploader le document !

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.