Compartilhar via


Ligar um Item no Arquivo de Dados a uma Base de Dados SQL Server

Word permite-lhe gerar documentos através da criação de soluções baseadas em dados. Pode criar um documento de modelo que inclua uma peça XML personalizada e utilizar controlos de conteúdo para vincular a dados XML personalizados através do mapeamento XML. Embora o termo modelo seja utilizado neste contexto, este documento não é um modelo Word, mas partilha algumas características de um Word documento de modelo. Em seguida, pode criar uma aplicação baseada na Web gerida para criar um novo documento com base no documento de modelo. A aplicação baseada na Web gerida abre o documento de modelo, obtém dados de uma base de dados do Microsoft SQL Server para criar uma nova peça XML personalizada, substitui a peça XML personalizada do documento de modelo pela nova parte e guarda o documento de modelo como uma nova Word documento.

Estas instruções explicam como criar um novo documento de modelo e como criar uma aplicação do lado do servidor que gera documentos que apresentam dados armazenados numa base de dados do Microsoft SQL Server. Para criar esta aplicação, irá concluir as duas tarefas seguintes:

  1. Criar um Word documento de modelo.

  2. Crie uma aplicação baseada na Web do lado do servidor que extraia dados de uma base de dados do Microsoft SQL Server e gera novos documentos com base no documento de modelo Word.

Os objetos programáticos utilizados neste exemplo são os seguintes:

Para obter mais informações sobre os controles de conteúdo, consulte Trabalhando com controles de conteúdo.

Cenário Empresarial: Criar um Gerador de Documentos do Cliente

Para criar um gerador de documentos Word que liga um item no arquivo de dados a uma base de dados do Microsoft SQL Server, comece por criar um documento modelo de gerador de cartas do cliente que contém controlos de conteúdo que mapeiam para um ficheiro XML. Em seguida, vai criar uma aplicação baseada na Web de geração de documentos que lhe permite selecionar um nome de empresa para gerar um documento personalizado. A aplicação obtém dados de clientes a partir de uma base de dados do Microsoft SQL Server e utiliza o gerador de cartas do cliente para criar um novo documento que apresenta os dados dos clientes com base numa seleção de utilizador. O documento apresenta as seguintes informações:

  • Nome da Empresa
  • Nome do Contacto
  • Título do Contacto
  • Telefone

Utilize os seguintes passos gerais para criar um gerador de documentos Word.

Para criar um gerador de documentos personalizado e definir os mapeamentos XML para cada controlo de conteúdo

  1. Abra Word e crie um documento em branco.

  2. Adicione controlos de conteúdo de texto simples ao documento para vincular aos nós no arquivo de dados.

    Os controlos de conteúdo são partes de conteúdo predefinidas. Word oferece vários tipos de controlos de conteúdo. Isto inclui blocos de texto, caixas de marcar, menus pendentes, caixas de combinação, controlos de calendário e imagens. Pode mapear estes controlos de conteúdo para um elemento num ficheiro XML. Ao utilizar expressões XPath , pode mapear conteúdos através de programação num ficheiro XML para um controlo de conteúdo. Isto permite-lhe escrever uma aplicação simples e curta para manipular e modificar dados num documento.

    Para adicionar um controlo de conteúdo, no separador Programador , no grupo Controlos , clique em Controlo de Conteúdo de Texto Simples.

    Adicione quatro controlos de conteúdo de texto simples ao documento. Depois de adicionar cada controlo, atribua um título a cada um: clique no controlo; no grupo Controlos , clique em Propriedades; na caixa Título , escreva um título para o controlo, conforme mostrado na lista seguinte; e, em seguida, clique em OK.

    • Nome da Empresa
    • Nome do Contacto
    • Título do Contacto
    • Telefone

    Também pode utilizar o seguinte código Visual Basic for Applications (VBA) para adicionar controlos de conteúdo ao documento. Prima Alt+F11 para abrir o editor do Visual Basic, cole o código na janela de código, clique em qualquer parte do procedimento e, em seguida, prima F5 para executar o código e adicionar quatro controlos de conteúdo ao seu documento de modelo.

         Sub AddContentControls()
    
             Selection.Range.ContentControls.Add (wdContentControlText)
             Selection.ParentContentControl.Title = "Company Name"
             Selection.ParentContentControl.Tag = "Company Name"
             Selection.MoveDown Unit:=wdLine, Count:=1
             Selection.TypeParagraph
    
             Selection.Range.ContentControls.Add (wdContentControlText)
             Selection.ParentContentControl.Title = "Contact Name"
             Selection.ParentContentControl.Tag = "Contact Name"
             Selection.MoveDown Unit:=wdLine, Count:=1
             Selection.TypeParagraph
    
             Selection.Range.ContentControls.Add (wdContentControlText)
             Selection.ParentContentControl.Title = "Contact Title"
             Selection.ParentContentControl.Tag = "Contact Title"
             Selection.MoveDown Unit:=wdLine, Count:=1
             Selection.TypeParagraph
    
             Selection.Range.ContentControls.Add (wdContentControlText)
             Selection.ParentContentControl.Title = "Phone Number"
             Selection.ParentContentControl.Tag = "Phone Number"
             Selection.MoveDown Unit:=wdLine, Count:=1
             Selection.TypeParagraph
    
         End Sub
    
  3. Defina o mapeamento XML nos controlos de conteúdo.

    O mapeamento XML é uma funcionalidade de Word que lhe permite criar uma ligação entre um documento e um ficheiro XML. Isso cria uma separação real de dados/modos de exibição entre a formatação de documento e os dados XML personalizados.

    Para carregar uma peça XML personalizada, primeiro tem de adicionar um novo arquivo de dados a um objeto Documento com o método Add da coleção CustomXMLParts . Isto acrescenta um novo arquivo de dados vazio ao documento. Uma vez que está vazio, ainda não pode utilizá-lo. Em seguida, tem de carregar uma peça XML personalizada de um ficheiro XML para o arquivo de dados, ao chamar o Método de carregamento do objeto CustomXMLPart que utiliza um caminho válido para um ficheiro XML como o parâmetro .

  4. Guarde o documento, atribuindo-lhe o nome CustomerLetterGenerator.docm.

    Observação

    Uma vez que contém código VBA, tem de guardar o documento como um ficheiro de documento com permissão para macros (.docm).|

O procedimento seguinte explica como mapear um controlo de conteúdo para um ficheiro XML personalizado de exemplo. Crie um ficheiro XML personalizado válido, guarde o ficheiro e, em seguida, utilize Visual Basic for Applications código VBA para adicionar ao documento de modelo um arquivo de dados que contém as informações a que pretende mapear.

Para definir um mapeamento XML num controlo de conteúdo

  1. Crie um ficheiro de texto e guarde-o como CustomerData.xml.

  2. Copie o seguinte código XML para o ficheiro de texto e guarde o ficheiro.

         <?xml version="1.0"?> 
         <Customer> 
         <CompanyName>Alfreds Futterkiste</CompanyName> 
         <ContactName>Maria Anders</ContactName> 
         <ContactTitle>Sales Representative</ContactTitle> 
         <Phone>030-0074321</Phone> 
         </Customer> 
    
  3. Prima Alt+F11 para abrir o editor do Visual Basic, cole o seguinte código na janela de código, clique em qualquer parte do procedimento e, em seguida, prima F5 para executar o código e anexar um ficheiro XML ao seu documento de modelo para que se torne um item de arquivo de dados disponível.

         Public Sub LoadXML()
    
         ' Load CustomerData.xml file
         ActiveDocument.CustomXMLParts.Add
         ActiveDocument.CustomXMLParts(ActiveDocument.CustomXMLParts.Count).Load ("C:\CustomerData.xml")
         End Sub
    

    Observação

    Existem, pelo menos, três partes XML personalizadas predefinidas que são sempre criadas com um documento: "Páginas de rosto", "Propriedades do documento" e "Propriedades da aplicação". Além disso, podem ser criadas várias outras partes XML personalizadas num determinado computador, consoante vários fatores. Estes incluem os suplementos que estão instalados, as ligações com o SharePoint, etc. Chamar o método Add na coleção CustomXMLParts no código anterior adiciona uma parte XML adicional, na qual o ficheiro XML é carregado. É nessa parte que o método Load é chamado, na linha de código seguinte.

    Para determinar o número de índice da parte na qual carregar o ficheiro XML, é necessário passar a contagem de peças XML personalizadas para o método Load . ActiveDocument.CustomXMLParts(ActiveDocument.CustomXMLParts.Count).Load ("C:\CustomerData.xml")

  4. Defina um mapeamento XML num controlo de conteúdo que se refira a um nó no arquivo de dados adicionado.

    Para criar um mapeamento XML, utilize uma expressão XPath que aponte para o nó na parte de dados XML personalizada à qual pretende mapear um controlo de conteúdo. Depois de adicionar um arquivo de dados ao seu documento (e o arquivo de dados apontar para um ficheiro XML válido), está pronto para mapear um dos respetivos nós para um controlo de conteúdo.

    Para tal, transmita uma Cadeia que contenha um XPath válido para um objeto ContentControl com o método SetMapping do objeto XMLMapping (utilizando a propriedade XMLMapping do objeto ContentControl ). Abra o editor do Visual Basic e execute o seguinte código VBA para vincular controlos de conteúdo a itens no arquivo de dados.

         Public Sub MapXML()
    
             Dim strXPath1 As String
             strXPath1 = "/Customer/CompanyName"
             ActiveDocument.ContentControls(1).XMLMapping.SetMapping strXPath1
    
             Dim strXPath2 As String
             strXPath2 = "/Customer/ContactName"
             ActiveDocument.ContentControls(2).XMLMapping.SetMapping strXPath2
    
             Dim strXPath3 As String
             strXPath3 = "/Customer/ContactTitle"
             ActiveDocument.ContentControls(3).XMLMapping.SetMapping strXPath3
    
             Dim strXPath4 As String
             strXPath4 = "/Customer/Phone"
             ActiveDocument.ContentControls(4).XMLMapping.SetMapping strXPath4
    
    

Criar uma Aplicação Server-Side que extrai Dados de uma Base de Dados SQL Server e Gera um Novo Documento

Pode criar uma aplicação baseada na Web que permita aos utilizadores selecionar um nome de empresa e gerar uma letra personalizada. A aplicação baseada na Web obtém dados de clientes a partir de uma base de dados SQL Server, abre o documento de modelo de carta do cliente e cria um novo documento que apresenta os dados dos clientes com base numa seleção de utilizador. Esta aplicação baseada na Web não requer a utilização de Word ou VBA. Utilize a sua linguagem de código gerido favorito (Visual Basic .NET ou C#) para criar esta aplicação.

Observação

A aplicação baseada na Web aqui apresentada obtém os respetivos dados a partir da base de dados Northwind.mdf. Esta base de dados foi instalada com versões anteriores do SQL Server e do Office. Se não tiver a base de dados Northwind no seu computador, pode transferi-la a partir do seguinte site: Base de dados Northwind

Para criar uma aplicação do lado do servidor que extrai dados de uma base de dados SQL Server e gera um novo documento

  1. Abra o Visual Studio ou o Visual Web Developer.

  2. Crie uma aplicação Web ASP.NET e dê-lhe o nome SqlServerSample.

    Nos passos seguintes, irá ligar a aplicação Web ASP.NET a uma base de dados SQL Server.

  3. Adicione o seguinte cadeia de conexão ao ficheiro Web.config no projeto do Visual Studio.

         <connectionStrings>
         <add name="NorthwindConnectionString"
             connectionString="data source=(local);database=Northwind; integrated security=SSPI;persist security info=false;"
             providerName="System.Data.SqlClient" />
         </connectionStrings>
    
  4. No projeto do Visual Studio, adicione o documento CustomerLetterGenerator.docm à pasta App_Data : clique com o botão direito do rato App_Data, aponte para Adicionar, clique em Item Existente, navegue até à localização onde guardou o documento, selecione-o e, em seguida, clique em Adicionar.

  5. Adicione uma referência a WindowsBase.dll ao projeto: clique com o botão direito do rato em Referências, clique em Adicionar Referência, clique no separador .NET , selecione WindowsBase e, em seguida, clique em OK.

  6. Transferir e instalar o Microsoft .NET Framework 4.0

  7. Configure a assemblagem no ficheiro Web.config da seguinte forma.

         <compilation debug="false">
         <assemblies>
             <add assembly="WindowsBase, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
         </assemblies>
         </compilation>
    
  8. Adicionar um Formulário Web ao seu projeto: no menu Projeto , clique em Adicionar Novo Item; em Modelos Instalados, clique em Web; selecione Formulário Web e, em seguida, clique em Adicionar.

  9. Na Gerenciador de Soluções, clique com o botão direito do rato em Propriedades e, em seguida, clique em Abrir.

  10. No separador Web , em Iniciar Ação, selecione Página Específica, clique no botão procurar e navegue até à página WebForm1.aspx.

  11. Adicione o seguinte código ao ficheiro WebForm1.aspx , substituindo a parte do ficheiro delimitada pelas etiquetas de abertura e de fecho <html> .

        <html xmlns="https://www.w3.org/1999/xhtml">
        <head runat="server">
            <title>Data-Driven Document Generation - SQL Server Sample</title>
        </head>
        <body>
            <form id="form1" runat="server">
            <div>
            <h1>Customer Letter Generator</h1>
                    <table border="0" cellpadding="0" cellspacing="0" style="width: 100%; height: 12%">
                        <tr>
                            <td>
                                Choose a customer:</td>
                            <td>
                                <asp:DropDownList 
                                ID="ddlCustomer"
                                runat="server"
                                AutoPostBack="True"
                                DataSourceID="CustomerData"
                                DataTextField="CompanyName"
                                DataValueField="CustomerID" 
                                Width="301px">
                                </asp:DropDownList>
                                <asp:SqlDataSource
                                ID="CustomerData"
                                runat="server"
                                ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>"
                                SelectCommand="SELECT [CustomerID], [CompanyName] FROM [Customers]" ProviderName="<%$ ConnectionStrings:NorthwindConnectionString.ProviderName %>">
                                </asp:SqlDataSource>
                            </td>
                        </tr>
                </table>
                </div>
                <br />
                <asp:Button
                ID="Button1"
                runat="server"
                OnClick="SubmitBtn_Click" 
                Text="Create Letter"
                Width="123px" />    
            </form>
        </body>
        </html>
    
    
  12. Consoante a linguagem de codificação que utilizar, adicione o seguinte código .NET ou C# do Visual Basic à página adequada WebForm1.aspx code-behind no projeto.

Código de Exemplo: Visual Basic .NET

O seguinte exemplo de .NET do Visual Basic mostra como vincular a uma base de dados SQL Server para obter dados com base na seleção de um cliente e criar um novo documento com base no documento de modelo CustomerLetterGenerator.docm. Adicione o seguinte código ao ficheiro WebForm1.aspx.vb , substituindo o código existente no ficheiro.

Imports System.Collections.Generic
Imports System.Data
Imports System.Data.SqlClient
Imports System.IO
Imports System.IO.Packaging
Imports System.Linq
Imports System.Xml
Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.WebControls

Public Class WebForm1

    Inherits System.Web.UI.Page

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    End Sub

    Private Const strRelRoot As String = "https://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument"

    Private Sub CreateDocument()
        ' Get the template document file and create a stream from it
        Const DocumentFile As String = "~/App_Data/CustomerLetterGenerator.docm"

        ' Read the file into memory
        Dim buffer() As Byte = File.ReadAllBytes(Server.MapPath(DocumentFile))
        Dim memoryStream As MemoryStream = New MemoryStream(buffer, True)
        buffer = Nothing

        ' Open the document in the stream and replace the custom XML part
        Dim pkgFile As Package = Package.Open(memoryStream, FileMode.Open, FileAccess.ReadWrite)
        Dim pkgrcOfficeDocument As PackageRelationshipCollection = pkgFile.GetRelationshipsByType(strRelRoot)
        For Each pkgr As PackageRelationship In pkgrcOfficeDocument
            If (pkgr.SourceUri.OriginalString = "/") Then

                ' Get the root part
                Dim pkgpRoot As PackagePart = pkgFile.GetPart(New Uri(("/" + pkgr.TargetUri.ToString), UriKind.Relative))

                ' Add a custom XML part to the package
                Dim uriData As Uri = New Uri("/customXML/item1.xml", UriKind.Relative)
                If pkgFile.PartExists(uriData) Then

                    ' Delete part "/customXML/item1.xml" part
                    pkgFile.DeletePart(uriData)
                End If

                ' Load the custom XML data
                Dim pkgprtData As PackagePart = pkgFile.CreatePart(uriData, "application/xml")
                GetDataFromSQLServer(pkgprtData.GetStream, ddlCustomer.SelectedValue)
            End If
        Next

        ' Close the file
        pkgFile.Close()

        ' Return the result
        Response.ClearContent()
        Response.ClearHeaders()
        Response.AddHeader("content-disposition", "attachment; filename=document.docx")
        Response.ContentEncoding = System.Text.Encoding.UTF8
        memoryStream.WriteTo(Response.OutputStream)
        memoryStream.Close()
        Response.End()
    End Sub

    Private Sub GetDataFromSQLServer(ByVal stream As Stream, ByVal customerID As String)

        'Connect to a SQL Server database and get data
        Dim source As String = ConfigurationManager.ConnectionStrings("NorthwindConnectionString").ConnectionString
        Const SqlStatement As String = "SELECT CompanyName, ContactName, ContactTitle, Phone FROM Customers WHERE CustomerID=@customerID"
        Dim conn As SqlConnection = New SqlConnection(source)
        conn.Open()
        Dim cmd As SqlCommand = New SqlCommand(SqlStatement, conn)
        cmd.Parameters.AddWithValue("@customerID", customerID)
        Dim dr As SqlDataReader = cmd.ExecuteReader
        If dr.Read Then
            Dim writer As XmlWriter = XmlWriter.Create(stream)
            writer.WriteStartElement("Customer")
            writer.WriteElementString("CompanyName", CType(dr("CompanyName"), String))
            writer.WriteElementString("ContactName", CType(dr("ContactName"), String))
            writer.WriteElementString("ContactTitle", CType(dr("ContactTitle"), String))
            writer.WriteElementString("Phone", CType(dr("Phone"), String))
            writer.WriteEndElement()
            writer.Close()
        End If
        dr.Close()
        conn.Close()
    End Sub

    Protected Sub SubmitBtn_Click(ByVal sender As Object, ByVal e As EventArgs)
        CreateDocument()
    End Sub

End Class

Código de Exemplo: C#

O exemplo de C# seguinte mostra como vincular a uma base de dados SQL Server para obter dados com base numa seleção de cliente e criar um novo documento com base no documento de modelo CustomerLetterGenerator.docm. Adicione o seguinte código ao ficheiro WebForm1.Aspx.cs , copiando o código existente.

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.IO;
using System.IO.Packaging;
using System.Linq;
using System.Xml;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace SQLServerSample
{
    public partial class WebForm1 : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }

        private const string strRelRoot = "https://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument";

        private void CreateDocument()
        {
            // Get the template document file and create a stream from it
            const string DocumentFile = @"~/App_Data/CustomerLetterGenerator.docm";
            
            // Read the file into memory
            byte[] buffer = File.ReadAllBytes(Server.MapPath(DocumentFile));
            MemoryStream memoryStream = new MemoryStream(buffer, true);
            buffer = null;

            // Open the document in the stream and replace the custom XML part
            Package pkgFile = Package.Open(memoryStream, FileMode.Open, FileAccess.ReadWrite);
            PackageRelationshipCollection pkgrcOfficeDocument = pkgFile.GetRelationshipsByType(strRelRoot);
            foreach (PackageRelationship pkgr in pkgrcOfficeDocument)
            {
                if (pkgr.SourceUri.OriginalString == "/")
                {
                    // Get the root part
                    PackagePart pkgpRoot = pkgFile.GetPart(new Uri("/" + pkgr.TargetUri.ToString(), UriKind.Relative));

                    // Add a custom XML part to the package
                    Uri uriData = new Uri("/customXML/item1.xml", UriKind.Relative);

                    if (pkgFile.PartExists(uriData))
                    {
                        // Delete document "/customXML/item1.xml" part
                        pkgFile.DeletePart(uriData);
                    }
                    // Load the custom XML data
                    PackagePart pkgprtData = pkgFile.CreatePart(uriData, "application/xml");
                    GetDataFromSQLServer(pkgprtData.GetStream(), ddlCustomer.SelectedValue);
                }
            }

            // Close the file
            pkgFile.Close();

            // Return the result
            Response.ClearContent();
            Response.ClearHeaders();
            Response.AddHeader("content-disposition", "attachment; filename=CustomLetter.docx");
            Response.ContentEncoding = System.Text.Encoding.UTF8;

            memoryStream.WriteTo(Response.OutputStream);

            memoryStream.Close();

            Response.End();
        }

        private void GetDataFromSQLServer(Stream stream, string customerID)
        {
            // Connect to a SQL Server database and get data
            String source = System.Configuration.ConfigurationManager.ConnectionStrings["NorthwindConnectionString"].ConnectionString;            
            const string SqlStatement =
                "SELECT CompanyName, ContactName, ContactTitle, Phone FROM Customers WHERE CustomerID=@customerID";

            using (SqlConnection conn = new SqlConnection(source))
            {
                conn.Open();
                SqlCommand cmd = new SqlCommand(SqlStatement, conn);
                cmd.Parameters.AddWithValue("@customerID", customerID);
                SqlDataReader dr = cmd.ExecuteReader();

                if (dr.Read())
                {
                    XmlWriter writer = XmlWriter.Create(stream);
                    writer.WriteStartElement("Customer");
                    writer.WriteElementString("CompanyName", (string)dr["CompanyName"]);
                    writer.WriteElementString("ContactName", (string)dr["ContactName"]);
                    writer.WriteElementString("ContactTitle", (string)dr["ContactTitle"]);
                    writer.WriteElementString("Phone", (string)dr["Phone"]);
                    writer.WriteEndElement();
                    writer.Close();
                }
                dr.Close();
                conn.Close();
            }
        }

        protected void SubmitBtn_Click(object sender, EventArgs e)
        {
            CreateDocument();
        }
    }
}

Para obter mais informações sobre como trabalhar com o ASP.NET 2.0, consulte https://www.asp.net/get-started/.

Este artigo explica como extrair dados de uma base de dados SQL Server e inseri-lo no seu documento de modelo. Também pode extrair os dados de outras origens de dados, incluindo, por exemplo, o Access e o Excel. Para obter mais informações sobre como ligar a dados nessas aplicações através de programação, veja a documentação para programadores do Access e do Excel.

Suporte e comentários

Tem dúvidas ou quer enviar comentários sobre o VBA para Office ou sobre esta documentação? Confira Suporte e comentários sobre o VBA para Office a fim de obter orientação sobre as maneiras pelas quais você pode receber suporte e fornecer comentários.