Publié dimanche 8 juin 2008 20:43 par Audrey

[WPF] Après le XPS, un petit lecteur de DOC et de PDF

Après le format XPS, voici la version DOC et PDF. Pour pouvoir générer des images à partir de ces types de documents, j'ai testé plusieurs bibliothéques gratuites et libres que l'on peut trouver en cherchant sur Internet. Après plusieurs tests infructueux, j'ai opté pour l'utilisation des composants COM de l'outil PDFCreator. Cette solution est un peu moins intuitive que celle utilisée pour les XPS, peu de documentation existe malheureusement pour manipuler au mieux ces objets COM, un petit exemple ici de documentation sur cet objet COM.

Voici le code que j'ai utilisé afin de pouvoir traiter les documents DOC et les PDF.

Tout d'abord, l'activation d'une instance de l'objet COM de PDFCreator :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
string parameters;
pErr = new PDFCreator.clsPDFCreatorError();

_PDFCreator = new PDFCreator.clsPDFCreator();

_PDFCreator.eError += new PDFCreator.__clsPDFCreator_eErrorEventHandler(_PDFCreator_eError);
_PDFCreator.eReady += new PDFCreator.__clsPDFCreator_eReadyEventHandler(_PDFCreator_eReady);

parameters = "/NoProcessingAtStartup";


// ouverture de l'objet COM PDFCreator
if (!_PDFCreator.cStart(parameters, false))
{
System.Windows.MessageBox.Show("Attention", "PDFCreator est déjà ouvert !");
this.Close();
}

Ensuite, les options d'impression sont définies :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// option d'impression
opt = _PDFCreator.cOptions;
opt.UseAutosave = 1;
opt.UseAutosaveDirectory = 1;
opt.AutosaveDirectory = fi.DirectoryName;
opt.AutosaveFormat = FileTyp;
opt.AutosaveStartStandardProgram = 1;
opt.PNGColorscount = 1;
opt.OptionsVisible = 0;
opt.NoProcessingAtStartup = 1;
opt.AutosaveFilename = fname;
_PDFCreator.cOptions = opt;

_PDFCreator.cClearCache();

Puis, l'imprimante PDFCreator est définie comme l'imprimante par défaut :

1
2
3
                // définition de l'imprimante par défaut
DefaultPrinter = _PDFCreator.cDefaultPrinter;
_PDFCreator.cDefaultPrinter = "PDFCreator";

Le seul problème majeur que j'ai rencontré concerne les fichiers PDF. Lors du lancement de l'impression, la méthode d'impression de l'objet COM ouvre une instance du document PDF avec le logiciel approprié (dans mon cas il s'agit d'Adobe Reader). Et tant que l'utilisateur ne ferme pas manuellement le logiciel, le traitement du document est bloqué. J'ai identifié d'où venait le problème mais il faudrait que je modifie le code du composant COM et je n'en ai pas le temps et/ou les compétences pour le faire. Pour palier à cela, j'ai utilisé un pop-up pour avertir l'utilisateur de bien vouloir fermer le lecteur de PDF. Je sais que ce n'est pas la manière la plus élégante, et la plus transparente pour l'utilisateur, mais pour moi c'est celle qui fournira le moins de problèmes une fois mon projet fini (bientôt j'espère Wink). Si certains d'entre vous ont une solution je suis preneuse !

Ensuite l'impression peut commencer :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
                    // impression
_PDFCreator.cPrintFile(fi.FullName);

ReadyState = false;
_PDFCreator.cPrinterStop = false;


// attente jusqu'à la fin de l'impression
do
{
System.Windows.Forms.Application.DoEvents();

} while (!ReadyState && _PDFCreator.cProgramIsRunning);

                    _PDFCreator.cPrinterStop = true;


// retour de l'imprimante par défaut du départ
_PDFCreator.cDefaultPrinter = DefaultPrinter;

Enfin la méthode qui permet de fermer l'objet COM, lorsque l'impression est terminée :

1
2
3
4
5
6
7
8
9
10
11
12
        private void ClosePDFCreator()
{
// fermeture de l'objet COM PDFCreator
_PDFCreator.cClose();
System.Runtime.InteropServices.Marshal.ReleaseComObject(_PDFCreator);
System.Runtime.InteropServices.Marshal.ReleaseComObject(pErr);
pErr = null;
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
}

Pour l'affichage des images, j'ai utilisé le même WPFControlBook de Mitsu et le même user control UCBitmap qui m'avait permis d'afficher un Bitmap dans un control Image dans un application WPF, dont j'avais parlé dans un post précédent, sauf qu'ici ce sont des PNG que j'affiche :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
        private void Window_Loaded(object sender, RoutedEventArgs e)
{
object itemPage;

try
{
// génération des images PNG
SaveDocPageToPng();


// ajout des images comme item du user control
for (int i = 1; i < pageCount; i++)
{
string source = FileName + i + ".png";
UCPng bt = new UCPng(source);

itemPage = (object)bt;
myBook.Items.Add(itemPage);
}
}
catch
{
ClosePDFCreator();
}
}

Voici la comparaison de disposition des pages, entre une lecture par défilement, et une lecture au format codex :

Comparaison DOC - WPF

Dans cet exemple, j'ai utilisé le format PNG pour la génération d'images, qui permet une plus grande compression des images que le BMP et donc les fichiers générés tiennent moins de place sur le disque dur. Par exemple, pour un document de 111 pages, en les générant en BMP j'obtiens un dossier pesant 690 Mo et en PNG seulement 5 Mo !

Pour conclure, le traitement avec des objets COM est un peu plus contraignant car il faut s'appuyer sur une application externe, en l'occurence PDFCreator, et il faut que l'utilisateur est cette application d'installée sur sa machine. Malgré tout je suis arrivée au but que je recherchais Smile.

(Pour l'exemple de document et de pdf, j'ai pris un ebook de William Shakespeare trouvé ici)

Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :

Classé sous , , ,

Les 10 derniers blogs postés

- Merci par Blog de Jérémy Jeanson le 10-01-2019, 20:47

- Office 365: Script PowerShell pour auditer l’usage des Office Groups de votre tenant par Blog Technique de Romelard Fabrice le 04-26-2019, 11:02

- Office 365: Script PowerShell pour auditer l’usage de Microsoft Teams de votre tenant par Blog Technique de Romelard Fabrice le 04-26-2019, 10:39

- Office 365: Script PowerShell pour auditer l’usage de OneDrive for Business de votre tenant par Blog Technique de Romelard Fabrice le 04-25-2019, 15:13

- Office 365: Script PowerShell pour auditer l’usage de SharePoint Online de votre tenant par Blog Technique de Romelard Fabrice le 02-27-2019, 13:39

- Office 365: Script PowerShell pour auditer l’usage d’Exchange Online de votre tenant par Blog Technique de Romelard Fabrice le 02-25-2019, 15:07

- Office 365: Script PowerShell pour auditer le contenu de son Office 365 Stream Portal par Blog Technique de Romelard Fabrice le 02-21-2019, 17:56

- Office 365: Script PowerShell pour auditer le contenu de son Office 365 Video Portal par Blog Technique de Romelard Fabrice le 02-18-2019, 18:56

- Office 365: Script PowerShell pour extraire les Audit Log basés sur des filtres fournis par Blog Technique de Romelard Fabrice le 01-28-2019, 16:13

- SharePoint Online: Script PowerShell pour désactiver l’Option IRM des sites SPO non autorisés par Blog Technique de Romelard Fabrice le 12-14-2018, 13:01