Compartir a través de


Conectar un elemento del almacén de datos a una base de datos SQL Server

Word le permite generar documentos mediante la creación de soluciones controladas por datos. Puede crear un documento de plantilla que incluya un elemento XML personalizado y usar controles de contenido para enlazar con datos XML personalizados mediante asignación XML. Aunque el término plantilla se usa en este contexto, este documento no es una plantilla de Word, sino que comparte algunas características de un documento de plantilla de Word. A continuación, puede crear una aplicación web administrada para crear un nuevo documento basado en el documento de plantilla. La aplicación web administrada abre el documento de plantilla, recupera los datos de una base de datos Microsoft SQL Server para crear un nuevo elemento XML personalizado, reemplaza el fragmento XML personalizado del documento de plantilla con el elemento nuevo y guarda el documento de plantilla como un nuevo documento Word.

En este tutorial se explica cómo crear un nuevo documento de plantilla y cómo crear una aplicación del lado servidor que genere documentos que muestren los datos almacenados en una base de datos Microsoft SQL Server. Para compilar esta aplicación, completará las dos tareas siguientes:

  1. Cree un documento de plantilla de Word.

  2. Cree una aplicación web del lado servidor que extraiga datos de una base de datos Microsoft SQL Server y genere documentos nuevos basados en el documento de plantilla de Word.

Los objetos de programación que se usan en este ejemplo son los siguientes:

Para obtener más información acerca de los controles de contenido, consulte Trabajar con controles de contenido.

Escenario de negocios: Crear un generador de documentos de cliente

Para crear un generador de documentos de Word que conecte un elemento en el almacén de datos con una base de datos de Microsoft SQL Server, cree primero un documento de plantilla generador de cartas al cliente que contiene controles de contenido que se asignan a un archivo XML. A continuación, cree una aplicación de generación de documentos basada en web que le permita seleccionar un nombre de empresa para generar un documento personalizado. La aplicación recupera los datos de los clientes de una base de datos Microsoft SQL Server y utiliza el generador de cartas al cliente para crear un documento nuevo en el que aparezcan los datos del cliente a partir de una selección de usuarios. El documento muestra la siguiente información:

  • Nombre de la compañía
  • Nombre del contacto
  • Puesto del contacto
  • Número de teléfono

Utilice los siguientes pasos generales para crear un generador de documentos de Word.

Para crear un generador de documentos personalizados y definir las asignaciones XML para cada control de contenido

  1. Abra Word y cree un documento en blanco.

  2. Agregue controles de contenido de texto sin formato al documento para enlazar con los nodos del almacén de datos.

    Los controles de contenido son elementos de contenido predefinidos. Word ofrece varios tipos de controles de contenido. Esto incluye bloques de texto, casillas de verificación, menús desplegables, cuadros combinados, controles de calendario e imágenes. Puede asignar estos controles de contenido a un elemento en un archivo XML. Mediante el uso de expresiones XPath , puede asignar mediante programación contenido de un archivo XML a un control de contenido. Esto le permite escribir una aplicación sencilla y corta para manipular y modificar datos en un documento.

    Para agregar un control de contenido, en la ficha Programador, en el grupo Controles, haga clic en Control de contenido de texto sin formato.

    Agregue cuatro controles de contenido de texto sin formato al documento. Después de agregar cada control, asigne a cada uno un título: haga clic en el control; en el grupo Controles, haga clic en Propiedades; en el Título, escriba un título para el control, como se muestra en la siguiente lista y, a continuación, haga clic en Aceptar.

    • Nombre de la compañía
    • Nombre del contacto
    • Puesto del contacto
    • Número de teléfono

    También puede usar el siguiente código de Visual Basic para Aplicaciones (VBA) para agregar controles de contenido al documento. Presione ALT+F11 para abrir el editor de Visual Basic, pegue el código en la ventana de código, haga clic en cualquier lugar del procedimiento y, a continuación, presione F5 para ejecutar el código y agregar cuatro controles de contenido al documento de plantilla.

         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. Establezca la asignación XML en los controles de contenido.

    La asignación XML es una característica de Word que le permite crear un vínculo entre un documento y un archivo XML. Esto crea una verdadera separación de datos y vistas entre el formato del documento y los datos XML personalizados.

    Para cargar un elemento XML personalizado, primero debe agregar un nuevo almacén de datos a un objeto Document mediante el método Add de la colección CustomXMLParts . Esto anexa un almacén de datos nuevo y vacío al documento. Como está vacío, aún no puede usarlo. A continuación, debe cargar un elemento XML personalizado desde un archivo XML al almacén de datos mediante una llamada al método Load del objeto CustomXMLPart que usa como parámetro una ruta de acceso válida a un archivo XML.

  4. Guarde el documento, asígnele el nombre CustomerLetterGenerator.docm.

    Nota:

    Dado que contiene código VBA, debe guardar el documento como un archivo de documento habilitado para macros (.docm).|

El siguiente procedimiento explica cómo asignar un control de contenido a un archivo XML personalizado de ejemplo. Cree un archivo XML personalizado válido, guarde el archivo y, a continuación, use Visual Basic para Aplicaciones (VBA) para agregar al documento de plantilla un almacén de datos que contiene la información que desea asignar.

Para establecer una asignación XML en un control de contenido

  1. Cree un archivo de texto y guárdelo como CustomerData.xml.

  2. Copie el siguiente código XML en el archivo de texto y guarde el archivo.

         <?xml version="1.0"?> 
         <Customer> 
         <CompanyName>Alfreds Futterkiste</CompanyName> 
         <ContactName>Maria Anders</ContactName> 
         <ContactTitle>Sales Representative</ContactTitle> 
         <Phone>030-0074321</Phone> 
         </Customer> 
    
  3. Presione ALT+F11 para abrir el editor de Visual Basic, pegue el código siguiente en la ventana de código, haga clic en cualquier lugar en el procedimiento y, a continuación, presione F5 para ejecutar el código y adjunte un archivo XML al documento de plantilla para que se convierte en un elemento del almacén de datos disponible.

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

    Nota:

    Hay al menos tres elementos XML personalizados predeterminados que siempre se crean con un documento: "Páginas de portada", "Propiedades de documento" y "Propiedades de la aplicación". Además, es posible que se creen otros elementos XML personalizados en un equipo determinado, dependiendo de varios factores. Estos incluyen los complementos que están instalados, las conexiones con SharePoint, etc. Al llamar al método Add en la colección CustomXMLParts del código anterior, se agrega un elemento XML adicional, en el que se carga el archivo XML. En esa parte se llama al método Load , en la siguiente línea de código.

    Para determinar el número de índice del elemento en el que se va a cargar el archivo XML, es necesario pasar el recuento de elementos XML personalizados al método Load. ActiveDocument.CustomXMLParts(ActiveDocument.CustomXMLParts.Count).Load ("C:\CustomerData.xml")

  4. Establezca una asignación XML en un control de contenido que hace referencia a un nodo del almacén de datos que se ha agregado.

    Para crear una asignación XML, use una expresión XPath que apunte al nodo en el elemento de datos XML personalizado al que desea asignar un control de contenido. Después de agregar un almacén de datos al documento (y de que el almacén de datos apunte a un archivo XML válido), ya está preparado para asignar uno de sus nodos a un control de contenido.

    Para ello, pase una cadena que contenga una XPath válida a un objeto ContentControl usando el método SetMapping del objeto XMLMapping (usando la propiedad XMLMapping del objeto ContentControl). Abra el editor de Visual Basic y ejecute el siguiente código VBA para enlazar controles de contenido a elementos del almacén de datos.

         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
    
    

Crear una aplicación del lado servidor que extrae datos de una base de datos SQL Server y genera un nuevo documento

Puede crear una aplicación web que permita a los usuarios seleccionar un nombre de compañía y generar una carta personalizada. La aplicación web recupera los datos del cliente desde una base de datos de SQL Server, abre el documento de plantilla de carta al cliente y crea un nuevo documento que muestra los datos del cliente a partir de una selección de usuarios. Esta aplicación web no requiere el uso de Word o VBA. Use el lenguaje de código administrado favorito (Visual Basic .NET o C#) para compilar esta aplicación.

Nota:

La aplicación web que se muestra aquí obtiene los datos de la base de datos Northwind.mdf. Esta base de datos se ha instalado a partir de versiones anteriores de SQL Server y Office. Si no tiene la base de datos Northwind en el equipo, puede descargarla desde el siguiente sitio: Base de datos Northwind

Para crear una aplicación del lado servidor que extrae datos de una base de datos SQL Server y genera un nuevo documento

  1. Abra Visual Studio o Visual Web Developer.

  2. Cree una aplicación web ASP.NET y asígnele el nombre SqlServerSample.

    En los pasos siguientes, conectará la aplicación web ASP.NET a una base de datos de SQL Server.

  3. Agregue la siguiente cadena de conexión al archivo Web.config en el proyecto de 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. En el proyecto de Visual Studio, agregue el documento CustomerLetterGenerator.docm a la carpeta App_Data: haga clic con el botón secundario del mouse en App_Data, seleccione Agregar, haga clic en Elemento existente, vaya a la ubicación donde guardó el documento, selecciónelo y, a continuación, haga clic en Agregar.

  5. Agregue una referencia a WindowsBase.dll a su proyecto: haga clic con el botón secundario el mouse en Referencias, haga clic en Agregar referencia, haga clic en la pestaña .NET, seleccione WindowsBase y, a continuación, haga clic en Aceptar.

  6. Descarga e instalación de Microsoft .NET Framework 4.0

  7. Configure el ensamblado en el archivo Web.config de la siguiente manera.

         <compilation debug="false">
         <assemblies>
             <add assembly="WindowsBase, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
         </assemblies>
         </compilation>
    
  8. Agregue un formulario web al proyecto: en el menú Proyecto, haga clic en Agregar nuevo elemento; en Plantillas instaladas, haga clic en Web; seleccione Formulario Web y, a continuación, haga clic en Agregar.

  9. En el Explorador de soluciones, haga clic en Propiedades y, a continuación, haga clic en Abrir.

  10. En la ficha Web, bajo Acción de inicio, seleccione Página específica, haga clic en el botón Examinar y vaya a la página WebForm1.aspx.

  11. Agregue el código siguiente al archivo WebForm1.aspx , sobrescribiendo la parte del archivo delimitada por las etiquetas de apertura y cierre <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. En función del lenguaje de programación que use, agregue el siguiente código de Visual Basic .NET o C# a la correspondiente página de código subyacente de WebForm1.aspx en el proyecto.

Código de ejemplo: Visual Basic .NET

En el siguiente ejemplo de Visual Basic .NET, se muestra cómo enlazar a una base de datos de SQL Server para recuperar datos a partir de una selección de clientes, y cómo crear un nuevo documento basado en el documento de plantilla CustomerLetterGenerator.docm. Agregue el siguiente código para el archivo WebForm1.aspx.vb, sobrescribiendo el código existente en el archivo.

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 ejemplo: C#

En el siguiente ejemplo de C#, se muestra cómo enlazar a una base de datos de SQL Server para recuperar datos a partir de una selección de clientes, y cómo crear un nuevo documento basado en el documento de plantilla CustomerLetterGenerator.docm. Agregue el siguiente código para el archivo WebForm1.Aspx.cs, copiando encima el 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 obtener más información sobre cómo trabajar con ASP.NET 2.0, vea https://www.asp.net/get-started/.

En este artículo se explica cómo extraer datos de una base de datos de SQL Server e insertarlos en el documento de plantilla. También puede extraer los datos de otros orígenes de datos, incluidos, por ejemplo, Access y Excel. Para obtener más información acerca de cómo conectarse a los datos en dichas aplicaciones mediante programación, consulte la documentación del desarrollador de Access y Excel.

Soporte técnico y comentarios

¿Tiene preguntas o comentarios sobre VBA para Office o esta documentación? Vea Soporte técnico y comentarios sobre VBA para Office para obtener ayuda sobre las formas en las que puede recibir soporte técnico y enviar comentarios.