Compartilhar via


Abrir um documento de processamento de texto para acesso somente leitura

Este tópico descreve como utilizar as classes no SDK Open XML para o Office para abrir programaticamente um documento de processamento de palavras para acesso só de leitura.


Quando Abrir um Documento para Acesso Só de Leitura

Por vezes, quer abrir um documento para inspecionar ou obter algumas informações e pretende fazê-lo de forma a garantir que o documento permanece inalterado. Nestes casos, quer abrir o documento para acesso só de leitura. Este tópico de procedimentos aborda várias formas de abrir programaticamente um documento de processamento de palavras só de leitura.


Criar um Objeto WordprocessingDocument

No SDK Open XML, a WordprocessingDocument classe representa um pacote de documento Word. Para trabalhar com um documento Word, crie primeiro uma instância da classe a WordprocessingDocument partir do documento e, em seguida, trabalhe com essa instância. Depois de criar a instância a partir do documento, pode obter acesso à main parte do documento que contém o texto do documento. Cada pacote Open XML contém um número de partes. No mínimo, um WordprocessingDocument tem de conter uma parte do documento main que funciona como um contentor para o texto main do documento. O pacote também pode conter peças adicionais. Repare que, num documento Word, o texto na parte do documento main é representado no pacote como XML através da marcação WordprocessingML.

Para criar a instância de classe a partir do documento a que chama um dos Open métodos. São fornecidos vários Open métodos, cada um com uma assinatura diferente. Os métodos que lhe permitem especificar se um documento é editável estão listados na tabela seguinte.

Open Method Tópico de Referência da Biblioteca de Classes Descrição
Open(String, Boolean) Open(String, Boolean) Crie uma instância da classe a WordprocessingDocument partir do ficheiro especificado.
Open(Stream, Boolean) Open(Stream, Boolean) Crie uma instância da classe a WordprocessingDocument partir do fluxo de E/S especificado.
Open(String, Boolean, OpenSettings) Open(String, Boolean, OpenSettings) Crie uma instância da classe a WordprocessingDocument partir do ficheiro especificado.
Open(Stream, Boolean, OpenSettings) Open(Stream, Boolean, OpenSettings) Crie uma instância da classe a WordprocessingDocument partir do fluxo de E/S especificado.

A tabela acima lista apenas os Open métodos que aceitam um valor Booleano como segundo parâmetro para especificar se um documento é editável. Para abrir um documento para acesso só de leitura, especifique false para este parâmetro.

Repare que dois dos Open métodos criam uma instância da WordprocessingDocument classe com base numa cadeia como o primeiro parâmetro. O primeiro exemplo no código de exemplo utiliza esta técnica. Utiliza o primeiro Open método na tabela acima, com uma assinatura que requer dois parâmetros. O primeiro parâmetro utiliza uma cadeia que representa o nome de ficheiro de caminho completo a partir do qual pretende abrir o documento. O segundo parâmetro é true ou false; este exemplo utiliza false e indica se pretende abrir o ficheiro para edição.

O seguinte exemplo de código chama o Open Método.

// Open a WordprocessingDocument based on a filepath.
using (WordprocessingDocument wordProcessingDocument = WordprocessingDocument.Open(filepath, false))

Os outros dois Open métodos criam uma instância da WordprocessingDocument classe com base num fluxo de entrada/saída. Pode utilizar esta abordagem, por exemplo, se tiver uma aplicação Microsoft Office SharePoint Online que utiliza entrada/saída de fluxo e quiser utilizar o SDK Open XML para trabalhar com um documento.

O seguinte exemplo de código abre um documento com base num fluxo.

// Get a stream of the wordprocessing document
using (FileStream fileStream = new FileStream(filepath, FileMode.Open))

// Open a WordprocessingDocument for read-only access based on a stream.
using (WordprocessingDocument wordDocument = WordprocessingDocument.Open(fileStream, false))

Suponha que tem uma aplicação que utiliza o suporte Open XML no espaço de nomes System.IO.Packaging da Biblioteca de Classes .NET Framework e que pretende utilizar o SDK Open XML para trabalhar com um pacote só de leitura. Embora o SDK Open XML inclua sobrecargas de métodos que aceitam um Package como primeiro parâmetro, não existe um que utilize um Booleano como segundo parâmetro para indicar se o documento deve ser aberto para edição.

O método recomendado é abrir o pacote como só de leitura para começar antes de criar a instância da WordprocessingDocument classe, conforme mostrado no segundo exemplo no código de exemplo. O seguinte exemplo de código efetua esta operação.

// Open System.IO.Packaging.Package.
using (Package wordPackage = Package.Open(filepath, FileMode.Open, FileAccess.Read))
// Open a WordprocessingDocument based on a package.
using (WordprocessingDocument wordDocument = WordprocessingDocument.Open(wordPackage))

Depois de abrir o pacote de documento Word, pode aceder à main parte do documento. Para aceder ao corpo da parte do documento main, atribua uma referência ao corpo do documento existente, conforme mostrado no exemplo de código seguinte.

// Assign a reference to the existing document body or create a new one if it is null.
MainDocumentPart mainDocumentPart = wordProcessingDocument.MainDocumentPart ?? wordProcessingDocument.AddMainDocumentPart();
mainDocumentPart.Document ??= new Document();

Body body = mainDocumentPart.Document.Body ?? mainDocumentPart.Document.AppendChild(new Body());

Estrutura de um Documento wordProcessingML

A estrutura de documentos básica de um WordProcessingML documento consiste nos document elementos e body , seguidos por um ou mais elementos de nível de bloco, como p, que representa um parágrafo. Um parágrafo contém um ou mais r elementos. Significa r execução, que é uma região de texto com um conjunto comum de propriedades, como formatação. Uma execução contém um ou mais t elementos. O t elemento contém um intervalo de texto. O seguinte exemplo de código mostra a WordprocessingML marcação de um documento que contém o texto "Texto de exemplo".

    <w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
      <w:body>
        <w:p>
          <w:r>
            <w:t>Example text.</w:t>
          </w:r>
        </w:p>
      </w:body>
    </w:document>

Com o SDK Open XML, pode criar estrutura e conteúdo de documentos com classes com tipos fortes que correspondem a WordprocessingML elementos. Encontrará estas classes no espaço de nomes. A tabela seguinte lista os nomes das classes que correspondem aos documentelementos , body, p, re t .

WordprocessingML Element Abrir Classe SDK XML Descrição
<document/> Document O elemento raiz para a parte do documento principal.
<body/> Body O contentor para as estruturas de nível de bloco, como parágrafos, tabelas, anotações e outros especificados na especificação ISO/IEC 29500 .
<p/> Paragraph Um parágrafo.
<r/> Run Uma execução.
<t/> Text Um intervalo de texto.

Para obter mais informações sobre a estrutura geral das partes e elementos de um documento do WordprocessingML, veja Structure of a WordprocessingML document (Estrutura de um documento wordprocessingML).


Gerar a Marcação WordprocessingML para Adicionar Texto e Tentar Guardar

O código de exemplo mostra como pode adicionar algum texto e tentar guardar as alterações para mostrar que o acesso é só de leitura. Assim que tiver acesso ao corpo da parte do documento main, adicione texto ao adicionar instâncias das Paragraphclasses , Rune Text . Isto gera a margem de lucro necessária do WordprocessingML. O seguinte exemplo de código adiciona o parágrafo, a execução e o texto.

// Attempt to add some text.
Paragraph para = body.AppendChild(new Paragraph());
Run run = para.AppendChild(new Run());
run.AppendChild(new Text("Append text in body, but text is not saved - OpenWordprocessingDocumentReadonly"));

// Call Save to generate an exception and show that access is read-only.
// mainDocumentPart.Document.Save();

Código de exemplo

O primeiro método de exemplo apresentado aqui, OpenWordprocessingDocumentReadOnly, abre um Word documento para acesso só de leitura. Chame-o ao transmitir um caminho completo para o ficheiro que pretende abrir. Por exemplo, o seguinte exemplo de código abre o caminho do ficheiro a partir do primeiro argumento da linha de comandos para acesso só de leitura.

OpenWordprocessingDocumentReadonly(args[0]);

O segundo método de exemplo, OpenWordprocessingPackageReadonly, mostra como abrir um Word documento para acesso só de leitura a partir de um Package. Chame-o ao transmitir um caminho completo para o ficheiro que pretende abrir. Por exemplo, o seguinte exemplo de código abre o caminho do ficheiro a partir do primeiro argumento da linha de comandos para acesso só de leitura.

OpenWordprocessingPackageReadonly(args[0]);

O terceiro método de exemplo, OpenWordprocessingStreamReadonly, mostra como abrir um Word documento para acesso só de leitura a partir de um fluxo. Chame-o ao transmitir um caminho completo para o ficheiro que pretende abrir. Por exemplo, o seguinte exemplo de código abre o caminho do ficheiro a partir do primeiro argumento da linha de comandos para acesso só de leitura.

OpenWordprocessingStreamReadonly(args[0]);

Importante

Se anular o comentário da instrução que guarda o ficheiro, o programa emitirá uma IOException porque o ficheiro está aberto para acesso só de leitura.

Segue-se o código de exemplo completo em C# e VB.

static void OpenWordprocessingDocumentReadonly(string filepath)
{
    // Open a WordprocessingDocument based on a filepath.
    using (WordprocessingDocument wordProcessingDocument = WordprocessingDocument.Open(filepath, false))
    {
        if (wordProcessingDocument is null)
        {
            throw new ArgumentNullException(nameof(wordProcessingDocument));
        }

        // Assign a reference to the existing document body or create a new one if it is null.
        MainDocumentPart mainDocumentPart = wordProcessingDocument.MainDocumentPart ?? wordProcessingDocument.AddMainDocumentPart();
        mainDocumentPart.Document ??= new Document();

        Body body = mainDocumentPart.Document.Body ?? mainDocumentPart.Document.AppendChild(new Body());

        // Attempt to add some text.
        Paragraph para = body.AppendChild(new Paragraph());
        Run run = para.AppendChild(new Run());
        run.AppendChild(new Text("Append text in body, but text is not saved - OpenWordprocessingDocumentReadonly"));

        // Call Save to generate an exception and show that access is read-only.
        // mainDocumentPart.Document.Save();
    }
}

static void OpenWordprocessingPackageReadonly(string filepath)
{
    // Open System.IO.Packaging.Package.
    using (Package wordPackage = Package.Open(filepath, FileMode.Open, FileAccess.Read))
    // Open a WordprocessingDocument based on a package.
    using (WordprocessingDocument wordDocument = WordprocessingDocument.Open(wordPackage))
    {
        // Assign a reference to the existing document body or create a new one if it is null.
        MainDocumentPart mainDocumentPart = wordDocument.MainDocumentPart ?? wordDocument.AddMainDocumentPart();
        mainDocumentPart.Document ??= new Document();

        Body body = mainDocumentPart.Document.Body ?? mainDocumentPart.Document.AppendChild(new Body());

        // Attempt to add some text.
        Paragraph para = body.AppendChild(new Paragraph());
        Run run = para.AppendChild(new Run());
        run.AppendChild(new Text("Append text in body, but text is not saved - OpenWordprocessingPackageReadonly"));

        // Call Save to generate an exception and show that access is read-only.
        // mainDocumentPart.Document.Save();
    }
}


static void OpenWordprocessingStreamReadonly(string filepath)
{
    // Get a stream of the wordprocessing document
    using (FileStream fileStream = new FileStream(filepath, FileMode.Open))

    // Open a WordprocessingDocument for read-only access based on a stream.
    using (WordprocessingDocument wordDocument = WordprocessingDocument.Open(fileStream, false))
    {


        // Assign a reference to the existing document body or create a new one if it is null.
        MainDocumentPart mainDocumentPart = wordDocument.MainDocumentPart ?? wordDocument.AddMainDocumentPart();
        mainDocumentPart.Document ??= new Document();

        Body body = mainDocumentPart.Document.Body ?? mainDocumentPart.Document.AppendChild(new Body());

        // Attempt to add some text.
        Paragraph para = body.AppendChild(new Paragraph());
        Run run = para.AppendChild(new Run());
        run.AppendChild(new Text("Append text in body, but text is not saved - OpenWordprocessingStreamReadonly"));

        // Call Save to generate an exception and show that access is read-only.
        // mainDocumentPart.Document.Save();
    }
}

Confira também