Office Automation/fr

From Free Pascal wiki
Jump to navigationJump to search

Deutsch (de) English (en) español (es) français (fr) italiano (it) русский (ru) 中文(中国大陆)‎ (zh_CN)

La possibilité d'interagir avec les programmes office et générer des feuilles de calcul, des documents texte et des présentations depuis le code peut être de grande valeur au bureau, et permet de gagner beaucoup de temps pour ceux qui peuvent le faire. Un exemple est la création d'applications qui peuvent lire et écrire des fichiers dans un format arbitraire et générer un fichier Excel, une tâche qu'il est bien plus efficace de faire par code que manuellement.

Utilisation de OpenOffice UNO Bridge

OpenOffice a des bindings de langage pour C++, Java, JavaScript et Python. Sur Windows, OpenOffice peut aussi être manipulé en Pascal via COM Automation (voir ci-dessous), mais il n'y a actuellement aucune façon simple d'utiliser OpenOffice UNO (Universal Network Objects) depuis Pascal sur OS X et Linux. Si vous êtes interessé par le développement d'un "bridge" OO pour Pascal, veuillez vous référer au liens suivants pour plus d'information (attention: ces liens sont relativement techniques à la mode de Sun):

api.openoffice.org

About Bridges

Voir aussi le sujet ci-dessous à propos de Python.

Utilisation de COM Automation pour interagir avec OpenOffice et Microsoft Office

Automation est uniquement valable sous Windows donc les deux exemples suivants ne fonctionneront pas sous OS X ou Linux. Pour ces plateformes, veuillez vous référer à Making do without Windows COM Automation. Si vous avez seulement besoin de créer et/ou visualiser un document de traitement de text depuis votre programme, veuillez jeter un oeil à XDev Toolkit.

OpenOffice sur Windows

Voici un exemple simple sur comment ouvrir un document avec votre programme en utilisant le serveur Automation d'OpenOffice. Notez que ça ne marche que sur Windows.

program TestOO;

{$IFDEF FPC}
 {$MODE Delphi}
{$ELSE}
 {$APPTYPE CONSOLE}
{$ENDIF} 

uses
  SysUtils, Variants, ComObj;

const
  ServerName = 'com.sun.star.ServiceManager';
var          
  Server     : Variant;
  Desktop    : Variant;
  LoadParams : Variant;
  Document   : Variant;
  TextCursor : Variant;
begin
  if Assigned(InitProc) then
    TProcedure(InitProc);

  try
    Server := CreateOleObject(ServerName);
  except
    WriteLn('Unable to start OO.');
    Exit;
  end;

  Desktop := Server.CreateInstance('com.sun.star.frame.Desktop');

  LoadParams := VarArrayCreate([0, -1], varVariant);

   {Crée un nouveeau document}
  Document := Desktop.LoadComponentFromURL('private:factory/swriter',
                                           '_blank', 0, LoadParams);

  TextCursor := Document.Text.CreateTextCursor;

   {Insère un nouveau document}  //Remplacer avc vos valeur de nom de fichier
  TextCursor.InsertDocumentFromURL('file:///C|/my/path/mydoc.doc',  
                                   LoadParams);
end.

Office sur Windows

Voici un exemple simple de comment ouvrir un document avec votre programme en utilisant le serveur d'automation de Word. Notez que ce serveur ne fonctionne que sous Windows. Ceci marchera avec Delphi et FPC.

program TestMsOffice;

{$IFDEF FPC}
 {$MODE Delphi}
{$ELSE}
 {$APPTYPE CONSOLE}
{$ENDIF} 

uses
  SysUtils, Variants, ComObj;

const
  ServerName = 'Word.Application';
var
  Server     : Variant;
  w:widestring;
begin
  if Assigned(InitProc) then
    TProcedure(InitProc);

  try
    Server := CreateOleObject(ServerName);
  except
    WriteLn('Unable to start Word.');
    Exit;
  end;

   {ouvre un document existant}  //Substituez votre votre chemin et nom de fichier
  w:= UTF8Decode('c:\my\path\mydoc.doc');
  Server.Documents.Open(w); //OLE utilises BSTR (http://msdn.microsoft.com/en-us/library/windows/desktop/ms221069(v=vs.85).aspx). Seule la widestring est compatible avec BSTR dans FPC, donc la conversion est nécessaire pour les caractères non latins.
  Server.Visible := True;  {Make Word visible}

end.

Voici un échantillon de code de comment travailler dans un document Word ouvert, en utilisant le serveur d'automation de Word.

var
  Server: Variant;
begin
  try
    Server := GetActiveOleObject('Word.Application');
  except
    try
      ShowMessage('Word pas encore ouvert, crée un objet');
      // Si aucune instance de Word ne tourne, essayer de créer un nouvel objet Word
      Server := CreateOleObject('Word.Application');
    except
      ShowMessage('Ne peut pas lancer Word/Word pas installé ?');
      Exit;
    end;
  end;
end;

Limitations: Parce que End est unmot réservé de FPC, il doit être utiliser comme un paramètre après le signe &.

Server.ActiveDocument.Application.Selection.start := Server.ActiveDocument.Application.Selection.&end+1;

De nombreux exemples pour Excel sont disponibles dans la page Wiki allemande.

Tenter d'utiliser Python pour piloter OpenOffice

Parce qu'OpenOffice inclut le support pour Python, il semble possible d'exécuter des scripts Python depuis Pascal pour piloter OO, au lieu des actuelles liaisons(bindings) Pascal. Voici les étapes pour une possible approcjhe pour faire cela:

  1. Tester UNO via une macro Python exécutée dans OO
  2. Tester UNO via un script Python autonome
  3. Support de l'exécution de scripts Python dans Pascal
  4. Tester UNO via un script Python exécuté dans Pascal.
  5. Une classe Pascal qui enveloppe Python UNO

Note: Les scripts suivant ont été testés avec OpenOffice 2.3.1 sur Windows XP et NeoOffice 2.2.5 Patch 6 sur Mac OS X 10.4.11 (PowerPC).

Etape 1. Tester UNO via une macro Python exécutée dans OO

OO a des outils pour créer des macro JavaScript, mais pas des macros en Python, donc utilisez un éditeur pour enregistrerle script suivant dans 'test_macro.py' et placez-le dans le dossier des macros utilisateur. Sur Windows, Ce dossier est:

C:\Document and Setting\<username>\Application Data\OpenOffice.org2\user\Scripts\python\Library1

Sur Mac OS X, ce dossier est:

~/Library/Preferences/NeoOffice-2.2/user/Scripts/python/Library1

Sur ces deux plates-formes, vous devrez créer le dossier python/Library1.

Voici le code pour test_macro.py, adapté de l'exemepl OO en Pascal du dessus:

# Macro Python qui teste UNO en créant un nouveau document et y insère du texte

import uno

def TestNewDoc():
  ctx = uno.getComponentContext()
  smgr = ctx.ServiceManager
  desktop = smgr.createInstance('com.sun.star.frame.Desktop')
  doc = desktop.loadComponentFromURL('private:factory/swriter', '_blank', 0, ())
  textCursor = doc.Text.createTextCursor()
  doc.Text.insertString(textCursor, 'Salut Monde', 0)

Dans OO, choisissez Tools | Macros | Organize Macros | Python et exécuter la macro pour être sûr que ça marche

Etape 2. Tester UNO via un script Python autonome

Voici le même code que dans le script autonome:

# Macro Python qui teste UNO en créant un nouveau document et y insère du texte

import sys

if sys.platform == 'darwin':
  sys.path.append('/Applications/NeoOffice.app/Contents/MacOS')

import officehelper

ctx = officehelper.bootstrap()
smgr = ctx.ServiceManager
desktop = smgr.createInstance('com.sun.star.frame.Desktop')
doc = desktop.loadComponentFromURL('private:factory/swriter', '_blank', 0, ())
textCursor = doc.Text.createTextCursor()
doc.Text.insertString(textCursor, 'Hello World', 0)

Sauvez cela dans le fichier test.py et exécutez-le sur Windows depuis la ligne de commande. note: Sur Windows et Linux, utiliser la version de Python incluse dans OO ; sur Mac OS X, utilisez le Python 2.3 du système.

"\program files\openoffice.org 2.3\program\python" test.py

Sur Mac OS X, exécutez le script comme ça depuis la fenêtre Terminal:

#!/bin/sh
export DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH":/Applications/NeoOffice.app/Contents/MacOS"
python2.3 test.py

Malheureusement, ce script ne fonctionne pas non plus sur Windows ou Mac OS X (NDT: cest ballot). Sur Windows, il affiche un dialogue d'erreur sans texte (!) et sort un message d'erreur vers la console qui dit "Cannot connect to soffice server". Sur Mac OS X, il démarre NeoOffice et crée le nouveau document, puis NeoOffice s'arrêt brutalement.

UNO Python A-faire

D'évidentes investigations supplémentaires sont nécessaires avant de pouvoir réaliser l'étape 3. Vous êtes le bienvenu pour travailler là-dessus. Voici deux choses à essayer:

  • Tester sur Linux
  • Tester sur des versions plus récentes d'OpenOffice
  • Jan. 5, 2009: Résultats des tests d'OpenOffice 3 sur Windows:
    • OO 3.0.0 Le support pour les utilisateurs de macro Python est rompu (Etape 1); corrigé avec OO 3.0.1 RC1.
    • Etape 2 n'affiche plus le message vide de la boîte de dialogue et le message d'exception vers la console est différent, mais ne démarre toujours pas OO.
    • Notez que les chemins vers les différentes parties de OO et des macros utilisateur ont changé avec OO 3.

En utilisant l'unité fpXMLXSDExport

FPC 2.6 et plus récent contient l'unité fpXMLXSDExport, partie des composant d'export de la FCL-DB. Avec cela, vous pouvez exporter des datasets vers divers formats XML, y compris un format compatible avec Microsoft Access et un format compatible avec Microsoft Excel.

Le format Access peut sortir du XML avec ou sans définition de donnée/table XSD incorporée. Observez que l'exportation de donnée de type binaire/blob nécessite une action supplémentaire à la fin de l'import Access car Access ne prend pas en charge les véritables champs binaires appropriés, seuls les champs OLE.

Dans le format Excel, les champs texte multi-ligne ne sont pas pris en charge actuellement: les fins de lignes sont supprimées pendant l'export.

Lazarus fournit un composant visuel pour cela: après l'installation du paquet lazdbexport, vous verrez le composant TXMLXSDExporter sur l'onglet Data Export.

Voir fpXMLXSDExport pour les détails.

En utilisant la bibliothèque Spreadsheet de Free Pascal

Une autre façon d'automatiser les tâches répétitives est d'utiliser la bibliothèque FPSpreadsheet. Elle peut lire ou écrire des classeurs dans plusieurs formats et ne nécessite l'installation d'aucune application externe sur la machine.

Les avantages sont que FPSpreadsheet est à 100% du code ObjectPascal et qu'elle ne nécessite aucune bibliothèque ou programme.

En écrivant un fichier Excel en utilisant ADO

Ecrire à l'auteur de la page anglaise.

En écrivant/lisant un fichier Excel en utilisant OLE

Cette méthode nécessite qu'Excel soit installé sur la machine de l'utilisateur car elle utilise OLE pour y accéder.

Garder à l'esprit que cette méthode démarre Excel en tâche de fond, lequel ouvre le fichier et travaille dessus comme un utilisateur véritable.

  • Créez un nouvelle fiche avec un TButton, un TStringGrid et un TEdit.
  • Créez un nouveau fichier Excel et remplissez quelques cellules.


excel123.png


Exemple - Ouvrir/lire le fichier Excel:

uses .....  comobj;

procedure TForm1.Button1Click(Sender: TObject);

Var   XLApp: OLEVariant;
      x,y: byte;
      path: variant;

begin
 XLApp := CreateOleObject('Excel.Application'); // nécessite comobj dans uses
 try
   XLApp.Visible := False;         // Cache Excel
   XLApp.DisplayAlerts := False;
   path := edit1.Text;
   XLApp.Workbooks.Open(Path);     // Ouvre le classeur
   for x := 1 to 4 do
    begin
     for y := 1 to 6 do
      begin
       SG.Cells[x,y] := XLApp.Cells[y,x].Value;  // Remplit le TStringGrid avec les valeurs
      end;
    end;
 finally
   XLApp.Quit;
   XLAPP := Unassigned;
  end;

Si vous voulez faire des modifications et que vous voulez les reporter dans Excel, vous pouvez utiliser:

XLApp.Cells[x,y].Value := SG.Cells[y,x];

Si vous voulez enregister:

XLApp.ActiveWorkBook.Save;

Read/Writing an Excel file using the SpreadSheet Interface Component

The component provides a library interface, abstracting the Excel COM and the Calc Open Office UNO interfaces. The component is available here: http://www.tcoq.org/composants

Since Automation is not yet available, but COM is available, the Excel interface component provides a set of Lazarus classes encapsulating calls to the Excel COM interface (the one below the Automation). It hides most of the drudgery of working with low-level code. Be careful, this is a work-in-progress. Use it at your own risk.

Functionality:

  • creating and loading excel workbooks,
  • saving workbooks,
  • creating and accessing sheets,
  • getting values and setting values (and formulas) in cells,
  • getting and changing color of cells,
  • getting and changing column height and row width,
  • creating comments,
  • creating shapes,
  • creating charts.

Inits first.

  IMPLEMENTATION
  USES
    ExcelUtilities,
    SpreadSheetInterfaces ;

  VAR
   aCell    : IRange ;
   aValue   : OleVariant ; // Not sure about this, but it works. ie( Edit.Text := STRING(aValue); )
   ExcelApp : TExcelApplication ;
   ExcelWbs : IWorkBooks ;

  ExcelBook   : IWorkBook ;
  ExcelSheet  : ISheet ;
  ExcelSheets : ISheets ;

Getting a sheet is simple:

  // Initializing the common excel workbook:
  ExcelApp         := TExcelApplication.Create(nil) ;
  ExcelApp.Active  := True ;
  ExcelApp.Visible := True ;

  ExcelWbs    := ExcelApp.WorkBooks ;
  ExcelBook   := ExcelWbs.Add ;
  ExcelSheets := ExcelBook.Sheets ;
  ExcelSheet  := ExcelSheets.Sheet(1) ;

Playing around with cells is simple too:

  // adding a value
  aCell := ExcelSheet.Cells(1, 1) ;
  aCell.Value := 10;

  // adding a formula
  aCell := ExcelSheet.Cells(2,1) ;
  aCell.Formula := '=A1+10' ;

  // getting the value computed in Excel
  aValue := aCell.Value ;


The test case provided has many more examples.

Copy HTML to the clipboard

You can copy HTML to the clipboard which is understood by many applications. This way you can copy formatted text. For those applications that only understand text put plain text too.

uses
  ClipBrd;
...
  // register the mime type for text/html. You can do this once at program start:
  ClipbrdFmtHTML:=RegisterClipboardFormat('text/html');
...
  // put text and html on the clipboard. Other applications will choose the best format automatically.
  ThePlainUTF8Text:='Simple text';
  Clipboard.AsText:=ThePlainUTF8Text; 
  AsHTML:='<b>Formatted</b> text'; // text with formattings
  Clipboard.AddFormat(ClipbrdFmtHTML,AsHTML[1],length(AsHTML));

Voir aussi

External links