Python, OpenOffice et OLE : Convertir un fichier en PDF
Par Florent Manens, dimanche 5 mars 2006 à 00:59 :: Informatique :: #41 :: rss
Aujourd'hui, un petit exemple de pilotage de OpenOffice.org depuis Python avec OLE (c'est donc uniquement pour Windows). J'ai choisi de montrer comment utiliser OpenOffice pour convertir un fichier texte en pdf, avec un petit script.
Contexte technique :
- Python 2.4
- Pywin32 207
- OpenOffice.org 2.0.1
Il existe 2 difficultées, liées à l'utilisation de OpenOffice.org avec OLE. La première concerne une particularitée du bridge Python COM/OLE. Dans certains cas (et c'est le cas ici avec OpenOffice.org), les objets OLE sont mal reconnus. En particulier, les méthodes ne sont pas bien identifiées, elles sont reconnues comme des propriétés. L'astuce consiste à utiliser _FlagAsMethod avant d'utiliser une méthode. Bizarement, ce n'est pas nécessaire pour toutes les méthodes, tant mieux.
Ensuite, le deuxième problème concerne l'utilisation des types spécifiques à OpenOffice.org. Par exemple, un type de données qui revient régulièrement est le type com.sun.star.beans.PropertyValue. Ce type de données n'est pas disponible directement en Python mais il est nécessaire pour passer des paramètres aux fonctions OpenOffice.org. Je vous conseille la lecture du livre Programmation OpenOffice.org pour avoir plus d'information sur la programmation OpenOffice et la manipulation de son API. Dans le même ordre d'idée, des documentations sont disponibles sur le site d'OpenOffice.org. Pour utiliser un type de données spécifique à OpenOffice, il faut utiliser Bridge_GetStruct (Voir la documentation de l'API de OpenOffice.org).
Pour travailler avec OpenOffice.org, il faut commencer par obtenir un objet OpenOffice, c'est le but de getOOoContext.
Voici le script, il est utilisable telquel, peut être que je le ferai évoluer par la suite pour supporter d'autres formats :p.
Notes :
- Je positionne le paramètre Hidden à True : Le fichier est ouvert de façon cachée
- Je positionne le paramètre ReadOnly à True : Le fichier est ouvert en lecture seule
import sys import getopt import os import urllib __doc__ = """ Convert text file (.doc, .sxw, ...) to PDF with OpenOffice doc2pdf.py filename.doc """ def getOOoContext(): import win32com.client objServiceManager = win32com.client.dynamic.Dispatch("com.sun.star.ServiceManager") objServiceManager._FlagAsMethod("CreateInstance") objServiceManager._FlagAsMethod("Bridge_GetStruct") corereflection = objServiceManager.CreateInstance("com.sun.star.reflection.CoreReflection") return objServiceManager.createInstance("com.sun.star.frame.Desktop"), objServiceManager, corereflection #Original from DannyB. def MakePropertyValues(oServiceManager, values): return [MakePropertyValue(oServiceManager, value[0], value[1]) for value in values] def MakePropertyValue(oServiceManager, Name, Value): oStruct = oServiceManager.Bridge_GetStruct("com.sun.star.beans.PropertyValue") oStruct.Name = Name oStruct.Value = Value return oStruct def convert_to_pdf(filename, pdffilename): StarDesktop, objServiceManager, corereflection = getOOoContext() document = StarDesktop.LoadComponentFromURL(filename, "_blank", 0, MakePropertyValues(objServiceManager, [["ReadOnly", True], ["Hidden", True]])) document.storeToUrl( pdffilename, MakePropertyValues(objServiceManager, [["CompressMode", 1], ["FilterName", "writer_pdf_Export"]])) document.close(False) def main(args): if not args or ("-h" in args): print __doc__ return try: opts, fileArgs = getopt.getopt(args, "") except getopt.GetoptError: print __doc__ return for filename in fileArgs: if os.path.exists(filename): pdffilename = ''.join([os.path.splitext(filename)[0], ".pdf"]) convert_to_pdf(''.join(["file:",urllib.pathname2url(filename)]), ''.join(["file:",urllib.pathname2url(pdffilename)])) if __name__ == "__main__": main(sys.argv[1:])
PS : Javoue, j'ai une petite idée derrière la tête...
Edit : ça ne fonctionne pas avec la version 2.0.2 de OpenOffice si on utilise le paramètre
["Hidden", True].
L'exception suivante est levée : com.sun.star.task.ErrorCodeIOException
C'est du à un bug OpenOffice.org (2.0.2) : http://qa.openoffice.org/issues/show_bug.cgi?id=63210
Correction prévue dans la 2.0.3.
Commentaires
Aucun commentaire pour le moment.
Ajouter un commentaire