Преобразовать текстовый документ из DOCM в формат файла DOCX
В этом разделе показано, как использовать классы в пакете SDK Open XML для Office для программного преобразования документа Microsoft Word, содержащего код VBA (с расширением DOCM) в стандартный документ (с расширением .docx). Он содержит пример ConvertDOCMtoDOCX
метода для иллюстрации этой задачи.
Метод ConvertDOCMtoDOCX
Пример ConvertDOCMtoDOCX
метода можно использовать для преобразования документа Word, содержащего код VBA (с расширением DOCM), в стандартный документ (с расширением .docx). Используйте этот метод для удаления макросов и части vbaProject, содержащей макросы из документа, хранящегося в формате DOCM. Метод принимает один параметр, указывающий имя файла, который требуется преобразовать.
static void ConvertDOCMtoDOCX(string fileName)
Полный листинг кода метода можно найти в разделе Пример кода.
Вызов примера метода
Для вызова примера метода передайте строку, содержащую имя файла, который требуется преобразовать. В следующем примере кода показан пример.
ConvertDOCMtoDOCX(args[0]);
Части и часть vbaProject
Пакет документа Word, например файл с расширением DOCX или DOCM, фактически представляет собой ZIP-файл, который состоит из нескольких частей. Каждую часть можно представить как внешний файл. Часть относится к определенному типу контента и может содержать контент, эквивалентный внешнему XML-файлу, двоичному файлу, файлу изображения и т. д. в зависимости от типа контента. Стандарт, который определяет, как открывать документы Open XML, хранимые в ZIP-файлах, называется Open Packaging Conventions. Дополнительные сведения о соглашениях об открытой упаковке см. в разделе ISO/IEC 29500-2:2021.
При создании и сохранения макроса VBA в документе Word добавляет новую двоичную часть с именем vbaProject, содержащую внутреннее представление макроса. На следующем рисунке из документа Обозреватель в средстве повышения производительности пакета SDK Open XML для Microsoft Office показаны части документа в примере документа, содержащего макрос. Часть vbaProject выделена.
Рис. 1. Часть vbaProject
Задача преобразования документа с включенными макросами в документ, в котором макросы отключены, заключается, в основном, в удалении части vbaProject из пакета документа.
Как работает код
Пример кода изменяет проверяет, содержит ли указанный документ часть vbaProject, и удаляет ее, если она существует. После этого код изменяет тип документа и переименовывает его, чтобы он использовал расширение DOCX.
Код начинается с открытия документа с помощью Open
метода и указывает, что документ должен быть открыт для чтения и записи (последний параметр true). Затем код получает ссылку на часть Document с помощью MainDocumentPart
свойства текстового документа.
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.");
Удалить часть из документа недостаточно. Вам также необходимо преобразовать тип документа. Пакет SDK Open XML предоставляет способ выполнения этой задачи: можно вызвать метод документа ChangeDocumentType
и указать новый тип документа (в этом случае укажите WordprocessingDocumentType.Document перечисленное значение).
Кроме того, необходимо переименовать файл, однако это невозможно, пока файл открыт. Блок using закрывает файл в конце блока. Таким образом вам необходимо иметь возможность указать коду после блока о том, что вы изменили файл. Таким образом, необходимо указать коду после блока, что вы изменили файл: Логическая fileChanged
переменная отслеживает эти сведения за вас.
// Look for the vbaProject part. If it is there, delete it.
var vbaPart = docPart.VbaProjectPart;
if (vbaPart is not null)
{
// Delete the vbaProject part.
docPart.DeletePart(vbaPart);
Затем код переименовывает измененный документ. Для этого код создает новое имя файла, изменяя расширение, проверяет, существует ли выходной файл, удаляет его и, наконец, перемещает старый файл в файл с новым именем.
// 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);
}
Пример кода
Ниже приведен полный ConvertDOCMtoDOCX
пример кода на C# и Visual Basic.
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.
docPart.DeletePart(vbaPart);
// 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);
}
}