Dernièrement j’ai eu le problème suivant : soit un fichier Microsoft Word en .doc ou .docx, créer un programme sous Windows qui permette de convertir ce fichier en .pdf en gardant la mise en page.
Le premier réflexe : “ben je vais utiliser LibreOffice”. Une belle API Python, et tout, et tout. Mais couac, quelques fichiers de tests prouveront rapidement que la mise en page pouvait parfois être légèrement différente, ce qui ne remplissait pas le cahier des charges.
Tentative de recherche du côté de PanDoc qui prends en charge plus de formats que je ne peux en nommer. Malheureusement, le docx n’est supporté qu’en écriture. Diantre.
Une option serait d’acheter une licence Office et son plugin PDF et de scripter ça avec l’API COM, mais là ça commence à revenir cher et c’est très lourd.
Finalement j’ai opté pour un bidouillage : utiliser Microsoft Word Viewer et son addon pour docx. Ensuite, pour la conversion en PDF, on installe CC PDF Converter, qui va nous mettre une imprimante virtuelle vers du PDF.
Enfin, il fallait trouver un moyen de scripter tout ça. J’ai tenté pywinauto. Fail. AutoHotKey, erreurs aléatoires. Et finalement, AutoIt, trouvé via Sebsauvage.
Le langage est de script n’est pas (trop) horrible, et facile à comprendre :
; Matcher le nom des fenêtre par morceau sans se ; soucier de la casse. AutoItSetOption('WinTitleMatchMode', -2) ; Chopper les options de la ligne de commande $VIEWER_EXE = "C:\Program Files (x86)\Microsoft Office\OFFICE11\WORDVIEW.EXE" $FROM = $CmdLine[1] $TO = $CmdLine[2] ; Fermer ou force killer tout ce qu'on a pu ouvrir précédement Winclose('reader') Winclose('viewer') Winkill('reader') Winkill('viewer') ; Ouvrir MS Word Viewer, et répondre "oui" à ; tout pop up qui s'ouvre en appuiyant sur ; Entrée Run($VIEWER_EXE & " " & $FROM) WinWaitActive('viewer', '', 2) Send('{Enter}') ; Utiliser Ctrl + P pour demander une ; impression. Les paramètres par défaut ; sont ok : couleur, 1 copie, le tout ; sur le Bureau. Send('^p') WinWaitActive('imprimer', '', 2) Send('{Enter}') ; On attent qu'apparaisse la fenêtre ; de choix de nom de fichier pour la ; sortie en PDF. Le focus est automatiquement ; sur le champ "name"; on a juste à écrire ; le nom de fichier de dans et à faire ; Entrée. WinWaitActive('select a filename', '', 2) Send($TO) Send('{Enter}') ; Si le fichier existe déjà, il va ; demander confirmation d'écrasement ; ce qu'on fait. Si la fenêtre ; n'apparait pas, Alt+O ne fait rien ; de bien méchant de toute façon. WinWaitActive('confirmer', '', 2) Send('!o') ; On attend que le lecteur PDF se lance, ; prouvant que le fichier est prêt. WinWaitActive('reader') ; Le PDF est prêt. On va pisser un coup. ; On ferme aussi toutes les fenêtres à ; coup de marteau. Winclose('reader') Winclose('viewer') Winkill('reader') Winkill('viewer')
Voilà c’était le code dégueulasse du jour, Max serait fier de moi. Evidement c’est très fragile : dépendant de la config, de la langue, etc.
Mais zob, j’ai mon PDF.
Ouais je ne connaissais pas CC PDF. Moi j’utilise PDFCreator donc l’un dans l’autre…
PDF Creator est maintenant plein de composant close source, en installe en prime un logiciel commercial (PDF architecte) et une barre de recherche amazon sur les navigateurs si on fait pas gaffe. Triste.
Mais de toute façon, ça permet pas d’automatiser la tâche.
ya un an je faisais ça pour pondre des doc Ooo et ca pour les coller en PDF. Et je me sers de ce script au quotidien pour produire la doc d’installation aux clients… Si ca peut servir ;)
AutoIT est quand même pas mal comme langage de script. LiLi USB Creator a été écrit avec ça :3
Sinon pour GUI-scripter en Python il y a aussi Sikuli !
http://www.sikuli.org/
Pour scripter windows office (excel principalement) j’utilise win32com.
Évidemment ça suppose d’être sous windows, d’avoir les applis windows installées, il n’y a pas beaucoup de doc, c’est tordu mais ça marche.
C’est mal maître ?
Ps: bravo pour ce blog de cul et vulgarisation en français que je découvre à l’instant