Compartilhar via


Converter um documento de processamento de texto do formato de arquivo DOCM para DOCX

Este tópico mostra como utilizar as classes no SDK Open XML para o Office para converter programaticamente um documento do Microsoft Word que contém código VBA (e tem uma extensão .docm) num documento padrão (com uma extensão .docx). Contém um método de exemplo ConvertDOCMtoDOCX para ilustrar esta tarefa.

ConvertDOCMtoDOCX Method

O ConvertDOCMtoDOCX método de exemplo pode ser utilizado para converter um documento Word que contém código VBA (e tem uma extensão .docm) num documento padrão (com uma extensão .docx). Utilize este método para remover as macros e a parte vbaProject que as contém de um documento armazenado no formato de ficheiro .docm. O método aceita um único parâmetro que indica o nome do ficheiro a converter.

static void ConvertDOCMtoDOCX(string fileName)

A listagem de código completa para o método pode ser encontrada na secção Código de Exemplo .

Chamar o Método de Exemplo

Para chamar o método de exemplo, transmita uma cadeia que contém o nome do ficheiro a converter. O código de exemplo seguinte mostra um exemplo.

ConvertDOCMtoDOCX(args[0]);

Peças e a Peça vbaProject

Um pacote de documentos de processamento de palavras, como um ficheiro que tem uma extensão .docx ou .docm, é, de facto, um ficheiro .zip que consiste em várias partes. Pode considerar cada parte semelhante a um ficheiro externo. Uma parte tem um tipo de conteúdo específico e pode conter conteúdo equivalente a um ficheiro XML externo, ficheiro binário, ficheiro de imagem, etc., consoante o tipo. A norma que define a forma como os documentos Open XML são armazenados em ficheiros .zip é denominada Convenções de Empacotamento Aberto. Para obter mais informações sobre as Convenções de Embalagem Abertas, consulte ISO/IEC 29500-2:2021.

Quando cria e guarda uma macro VBA num documento, Word adiciona uma nova peça binária denominada vbaProject que contém a representação interna do projeto de macro. A imagem seguinte do Documento Explorer na Open XML SDK Productivity Tool for Microsoft Office (Ferramenta de Produtividade do SDK Open XML para Microsoft Office) mostra as partes do documento num documento de exemplo que contém uma macro. A parte vbaProject está realçada.

Figura 1. A parte vbaProject

vbaProject part shown in the Document Explorer

A tarefa de converter um documento com permissão para macros num documento que não esteja ativado para macros consiste, em grande parte, em remover a parte vbaProject do pacote de documentos.

Como Funciona o Código

O código de exemplo modifica o documento que especificar, verificando se o documento contém uma parte vbaProject e eliminando a peça. Depois de o código eliminar a peça, altera o tipo de documento internamente e muda o nome do documento para que utilize a extensão .docx.

O código começa por abrir o documento com o Open método e indicando que o documento deve estar aberto para acesso de leitura/escrita (o parâmetro verdadeiro final). Em seguida, o código obtém uma referência à parte Documento com a MainDocumentPart propriedade do documento de processamento de palavras.

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.");

Não basta eliminar a parte do documento. Também tem de converter o tipo de documento internamente. O SDK Open XML fornece uma forma de executar esta tarefa: pode chamar o método do documento ChangeDocumentType e indicar o novo tipo de documento (neste caso, indique o WordprocessingDocumentType.Document valor enumerado).

Também tem de mudar o nome do ficheiro. No entanto, não pode fazê-lo enquanto o ficheiro estiver aberto. O bloco de utilização fecha o ficheiro no final do bloco. Por conseguinte, tem de ter alguma forma de indicar ao código após o bloco que modificou o ficheiro: a fileChanged variável Booleana controla estas informações automaticamente.

// 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);

Em seguida, o código muda o nome do documento recentemente modificado. Para tal, o código cria um novo nome de ficheiro ao alterar a extensão; verifica se o ficheiro de saída existe e o elimina e, por fim, move o ficheiro do nome de ficheiro antigo para o novo nome de ficheiro.

// 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);
}

Código de exemplo

Segue-se o exemplo de código completo ConvertDOCMtoDOCX em C# e 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);
    }
}

Confira também