Je suis actuellement en train de développer un petit bout de code en C# permettant d'utiliser Open Office 4.1.1 pour faire du publipostage via le SDK sous Windows 8.1.
Au niveau de la structure, j'ai une simple source de données au format CSV, utilisée dans un document ODT via la définition d'un ODB. Cette partie fonctionne bien selon mes besoins ... à part le fait que Open Office m'intercale des pages blanches invisibles entre chaque impression d'un élément de ma source de données.
Par exemple, si mon CSV contient 3 lignes et que mon document modèle ne fait qu'une seule page, je vais obtenir (dans un ODT ou à l'impression directe): Page de donnée 1 / Page blanche / Page de donnée 2 / Page blanche / Page de donnée 3. Soit un document de 5 pages alors qu'il ne devrait en faire que 3.
Plus curieux, si j'utilise la fonction de génération d'un document ODT et que j'ouvre le fichier résultat avec Writer, je ne vois pas les pages vides, seule l'indication "Page 1 sur 5" dans la barre d'information d'Open Office m'indique l'existence des pages indésirables (cf capture en pièce jointe).
Voici le code de mon publipostage pour obtenir mon fichier résultat :
Code : Tout sélectionner
static void FusionODTFile(string filePath, string destFolder, bool saveAsSingleFile = false)
{
XComponentContext oStrap = uno.util.Bootstrap.bootstrap();
XMultiServiceFactory oServMan = (XMultiServiceFactory)oStrap.getServiceManager();
XJob publipostageJob = (XJob)oServMan.createInstance("com.sun.star.text.MailMerge");
string odtFile = string.Format("file:///{0}", filePath.Replace("\\", "/"));
string resultFolder = string.Format("file:///{0}", destFolder.Replace("\\", "/"));
NamedValue[] namedValue = new NamedValue[8];
namedValue[0] = new NamedValue();
namedValue[0].Name = "DocumentURL";
namedValue[0].Value = new uno.Any(odtFile);
// Nom de la source de données
namedValue[1] = new NamedValue();
namedValue[1].Name = "DataSourceName";
namedValue[1].Value = new uno.Any(_dataSourceName);
// Données de la table
namedValue[2] = new NamedValue();
namedValue[2].Name = "CommandType";
namedValue[2].Value = new uno.Any(unoidl.com.sun.star.sdb.CommandType.TABLE);
// Nom de la table utilisée
namedValue[3] = new NamedValue();
namedValue[3].Name = "Command";
namedValue[3].Value = new uno.Any(_tableName);
// Type de sortie
namedValue[4] = new NamedValue();
namedValue[4].Name = "OutputType";
namedValue[4].Value = new uno.Any(unoidl.com.sun.star.text.MailMergeType.FILE);
// Dossier contenant les fichiers
namedValue[5] = new NamedValue();
namedValue[5].Name = "OutputURL";
namedValue[5].Value = new uno.Any(resultFolder);
// Préfixe des fichiers de sortie
namedValue[6] = new NamedValue();
namedValue[6].Name = "FileNamePrefix";
namedValue[6].Value = new uno.Any(_outputFilePrefix);
// Création d'un seul fichier de sortie
namedValue[7] = new NamedValue();
namedValue[7].Name = "SaveAsSingleFile";
namedValue[7].Value = new uno.Any(saveAsSingleFile);
publipostageJob.execute(namedValue);
}
De plus, cette option semble persistante ce qui est gênant (modifier les options de l'utilisateur dans son dos n'est jamais terrible).
Voici le code que j'utilise pour modifier l'option d'impression puis ouvrir le document pour l'imprimer :
Code : Tout sélectionner
static void OpenAndPrintODTFile(string filePath, string printerName, bool hidden)
{
XComponentContext oStrap = uno.util.Bootstrap.bootstrap();
XMultiServiceFactory oServMan = (XMultiServiceFactory)oStrap.getServiceManager();
// Permet de ne pas imprimer les pages vides automatiquement placées entre chaque enregistrement
XPrintSettingsSupplier printSettingSupplier = (XPrintSettingsSupplier)oServMan.createInstance("com.sun.star.text.GlobalSettings");
XPropertySet printSettings = printSettingSupplier.getPrintSettings();
uno.Any printEmptyPage = printSettings.getPropertyValue("PrintEmptyPages");
if (((bool)printEmptyPage.Value) == true)
{
printSettings.setPropertyValue("PrintEmptyPages", new uno.Any(false));
}
XComponentContext oStraper = uno.util.Bootstrap.bootstrap();
XMultiServiceFactory oServManager = (XMultiServiceFactory)oStraper.getServiceManager();
XComponentLoader oDesk = (XComponentLoader)oServManager.createInstance("com.sun.star.frame.Desktop");
string url = string.Format("file:///{0}", filePath.Replace("\\", "/"));
// Ouverture d'un doc vide
// url = @"private:factory/scalc";
PropertyValue[] propVals;
if (hidden)
{
// Permet de masquer la fenetre
propVals = new PropertyValue[1];
propVals[0] = new PropertyValue();
propVals[0].Name = "Hidden";
propVals[0].Value = new uno.Any(true);
}
else
{
propVals = new PropertyValue[0];
}
XComponent oDoc = oDesk.loadComponentFromURL(url, "_blank", 0, propVals);
XTextDocument doc = (XTextDocument)oDoc;
XPrintable printableDocument = (XPrintable)oDoc;
PropertyValue[] printerProperties = new PropertyValue[1];
// Nom de l'imprimante utilisée
printerProperties[0] = new PropertyValue();
printerProperties[0].Name = "Name";
printerProperties[0].Value = new uno.Any(printerName);
printableDocument.setPrinter(printerProperties);
PropertyValue[] printJobProperties = new PropertyValue[3];
// Nombre de copies du doc
printJobProperties[0] = new PropertyValue();
printJobProperties[0].Name = "CopyCount";
printJobProperties[0].Value = new uno.Any(1);
// Impression synchrone
printJobProperties[1] = new PropertyValue();
printJobProperties[1].Name = "Wait";
printJobProperties[1].Value = new uno.Any(true);
printJobProperties[2] = new PropertyValue();
printJobProperties[2].Name = "Collate";
printJobProperties[2].Value = new uno.Any(true);
// Impression
printableDocument.print(printJobProperties);
oDoc.dispose();
oDoc = null;
}
Je cherche donc de l'aide pour savoir s'il est possible de supprimer ces mystérieuses pages blanches :
- soit à la source, lors du publipostage (utilisation du service mailMerge avec une option non-documentée ?).
- soit par programmation en supprimant les pages indésirables du document.
- soit à l'impression en trouvant le moyen de forcer l'application du paramétrage, me permettant ainsi de faire le changement d'option uniquement le temps de l'impression.
C'est également la première fois que j'utilise l'API Open Office, je suis donc ouvert à toute suggestion concernant mon code si vous avez des conseils, astuces, etc.
Merci à vous pour votre aide, n'hésitez pas si vous avez des questions complémentaires.