Convertir un document de traitement de texte DOCM au format de fichier DOCX
Cette rubrique montre comment utiliser les classes du Kit de développement logiciel (SDK) Open XML pour Office pour convertir par programmation un document Microsoft Word 2010 ou Microsoft Word 2013 qui contient du code VBA (et qui a une extension .docm) en document standard (avec une extension .docx). Il contient un exemple de méthode ConvertDOCMtoDOCX pour illustrer cette tâche.
ConvertDOCMtoDOCX, méthode
L’exemple de méthode ConvertDOCMtoDOCX peut être utilisé pour convertir un document Word 2010 ou Word 2013 qui contient du code VBA (et a une extension .docm) en document standard (avec une extension .docx). Utilisez cette méthode pour supprimer les macros et le composant vbaProject qui les contient d’un document stocké au format de fichier .docm. La méthode accepte un seul paramètre qui indique le nom du fichier à convertir.
public static void ConvertDOCMtoDOCX(string fileName)
La liste de code complète pour la méthode se trouve dans la section Exemple de code.
Appel de la méthode de l’exemple
Pour appeler l’exemple de méthode, transmettez une chaîne qui contient le nom du fichier à convertir. Le code suivant est fourni à titre d'exemple.
string filename = @"C:\Users\Public\Documents\WithMacros.docm";
ConvertDOCMtoDOCX(filename);
Composants et partie vbaProject
Un package de document de traitement de texte tel qu’un fichier qui a une extension .docx ou .docm est en fait un fichier .zip qui se compose de plusieurs parties. Vous pouvez considérer que chaque partie est similaire à un fichier externe. Un composant a un type de contenu particulier et peut contenir du contenu équivalent à un fichier XML externe, un fichier binaire, un fichier image, etc., selon le type. La norme qui définit la façon dont les documents Open XML sont stockés dans .zip fichiers est appelée Open Packaging Conventions. Pour plus d’informations sur les conventions open packaging, consultez ISO/IEC 29500-2.
Lorsque vous créez et enregistrez une macro VBA dans un document, Word ajoute une nouvelle partie binaire nommée vbaProject qui contient la représentation interne de votre projet de macro. L’image suivante de l’Explorer document dans l’outil de productivité du Kit de développement logiciel (SDK) Open XML pour Microsoft Office montre les parties de document dans un exemple de document qui contient une macro. Le composant vbaProject est mis en surbrillance.
Figure 1. Composant vbaProject
La tâche de conversion d’un document activé par macro en un document qui n’est pas activé par macro consiste donc en grande partie à supprimer le composant vbaProject du package de documents.
Fonctionnement du code
L’exemple de code modifie le document que vous spécifiez, en vérifiant que le document contient un composant vbaProject et en supprimant le composant. Une fois que le code a supprimé le composant, il modifie le type de document en interne et renomme le document afin qu’il utilise l’extension .docx.
Le code commence par ouvrir le document à l’aide de la méthode Open et en indiquant que le document doit être ouvert pour l’accès en lecture/écriture (paramètre true final). Le code récupère ensuite une référence au composant Document à l’aide de la propriété MainDocumentPart du document de traitement de texte.
using (WordprocessingDocument document =
WordprocessingDocument.Open(fileName, true))
{
// Get access to the main document part.
var docPart = document.MainDocumentPart;
// Code removed here…
}
L’exemple de code vérifie ensuite que le composant vbaProject existe, supprime le composant et enregistre le document. Le code n’a aucun effet si le fichier à convertir ne contient pas de composant vbaProject. Pour trouver le composant, l’exemple de code récupère la propriété VbaProjectPart du document. Il appelle la méthode DeletePart pour supprimer la partie, puis appelle la méthode Save du document pour enregistrer les modifications.
// Look for the vbaProject part. If it is there, delete it.
var vbaPart = docPart.VbaProjectPart;
if (vbaPart != null)
{
// Delete the vbaProject part and then save the document.
docPart.DeletePart(vbaPart);
docPart.Document.Save();
// Code removed here.
}
Il ne suffit pas de supprimer le composant du document. Vous devez également convertir le type de document en interne. Le Kit de développement logiciel (SDK) Open XML permet d’effectuer cette tâche : vous pouvez appeler la méthode ChangeDocumentType du document et indiquer le nouveau type de document (dans ce cas, indiquez la valeur énumérée WordProcessingDocumentType.Document ).
Vous devez également renommer le fichier. Toutefois, vous ne pouvez pas le faire tant que le fichier est ouvert. Le bloc using ferme le fichier à la fin du bloc. Par conséquent, vous devez avoir un moyen d’indiquer au code après le bloc que vous avez modifié le fichier : La variable booléenne fileChanged suit ces informations pour vous.
// Change the document type to
// not macro-enabled.
document.ChangeDocumentType(
WordprocessingDocumentType.Document);
// Track that the document has been changed.
fileChanged = true;
Le code renomme ensuite le document qui vient d’être modifié. Pour ce faire, le code crée un nom de fichier en modifiant l’extension ; Vérifie que le fichier de sortie existe et le supprime, puis déplace le fichier de l’ancien nom de fichier vers le nouveau nom de fichier.
// If anything goes wrong in this file handling,
// the code will raise an exception back to the caller.
if (fileChanged)
{
// Create the new .docx filename.
var newFileName = Path.ChangeExtension(fileName, ".docx");
// If it already exists, it will be deleted!
if (File.Exists(newFileName))
{
File.Delete(newFileName);
}
// Rename the file.
File.Move(fileName, newFileName);
}
Exemple de code
Voici l’exemple de code ConvertDOCMtoDOCX complet en C# et Visual Basic.
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using System;
using System.IO;
ConvertDOCMtoDOCX(args[0]);
// Given a .docm file (with macro storage), remove the VBA
// project, reset the document type, and save the document with a new name.
static void ConvertDOCMtoDOCX(string fileName)
{
bool fileChanged = false;
using (WordprocessingDocument document = WordprocessingDocument.Open(fileName, true))
{
// Access the main document part.
var docPart = document.MainDocumentPart ?? throw new ArgumentNullException("MainDocumentPart is null.");
// Look for the vbaProject part. If it is there, delete it.
var vbaPart = docPart.VbaProjectPart;
if (vbaPart is not null)
{
// Delete the vbaProject part and then save the document.
docPart.DeletePart(vbaPart);
docPart.Document.Save();
// Change the document type to
// not macro-enabled.
document.ChangeDocumentType(
WordprocessingDocumentType.Document);
// Track that the document has been changed.
fileChanged = true;
}
}
// If anything goes wrong in this file handling,
// the code will raise an exception back to the caller.
if (fileChanged)
{
// Create the new .docx filename.
var newFileName = Path.ChangeExtension(fileName, ".docx");
// If it already exists, it will be deleted!
if (File.Exists(newFileName))
{
File.Delete(newFileName);
}
// Rename the file.
File.Move(fileName, newFileName);
}
}