共用方式為


將資料儲存中的項目連接到 SQL Server 資料庫

Word 讓你能透過建立數據驅動的解決方案來產生文件。 你可以建立包含自訂 XML 部分的範本文件,並利用內容控制項透過 XML 映射綁定自訂 XML 資料。 雖然在此語境中使用「範本」一詞,但本文件並非 Word 範本,且具有 Word 範本文件的一些特徵。 接著你可以建立一個受管理的網頁應用程式,根據範本文件建立新文件。 這個受管理的網頁應用程式會打開範本文件,從 Microsoft SQL Server 資料庫取得資料以建立新的自訂 XML 部分,然後將範本文件的自訂 XML 部分替換成新部分,並將該範本文件儲存為新的 Word 文件。

本教學說明如何建立新的範本文件,以及如何建立伺服器端應用程式,產生顯示資料並儲存在 Microsoft SQL Server 資料庫中的文件。 要建立這個應用程式,你將完成以下兩項任務:

  1. 建立一個 Word 範本文件。

  2. 建立一個伺服器端網頁應用程式,從 Microsoft SQL Server 資料庫擷取資料,並根據 Word 範本文件產生新文件。

本範例中使用的程式化物件如下:

如需內容控制項的詳細資訊,請參閱使用內容控制項

商業情境:建立客戶文件產生器

要建立一個將資料儲存中的項目連結到 Microsoft SQL Server 資料庫的 Word 文件產生器,首先建立一個包含內容控制並映射到 XML 檔案的客戶信件產生器範本文件。 接著,你建立一個文件生成的網頁應用程式,讓你能選擇公司名稱來產生自訂文件。 該應用程式會從 Microsoft SQL Server 資料庫取得客戶資料,並利用客戶信函產生器建立一份新文件,根據使用者選擇顯示客戶資料。 文件顯示以下資訊:

  • 公司名稱
  • 聯絡名稱
  • 聯絡人標題
  • 電話號碼

請依照以下一般步驟建立 Word 文件產生器。

建立自訂文件產生器,並為每個內容控制項定義 XML 映射

  1. 打開 Word,建立一個空白文件。

  2. 在文件中加入純文字內容控制項,以便綁定到資料儲存中的節點。

    內容控制是預先定義的內容片段。 Word 提供多種內容控制。 這包括文字區塊、勾選框、下拉選單、組合方塊、行事曆控制和圖片。 你可以將這些內容控制映射到 XML 檔案中的元素。 透過使用 XPath 表達式,你可以程式化地將 XML 檔案中的內容映射到內容控制項。 這讓你能撰寫一個簡單且簡短的應用程式,來操作和修改文件中的資料。

    要新增內容控制,請在 開發 者標籤的 控制 群組中,點擊 純文字內容控制

    在文件中新增四個純文字內容控制項。 新增每個控制項後,為每個控制項指定標題:點擊控制項;在 控制 組中,點選 屬性;在 標題 框中輸入控制項標題,如下列表所示;然後點擊 確定

    • 公司名稱
    • 聯絡名稱
    • 聯絡人標題
    • 電話號碼

    你也可以使用以下 Visual Basic for Applications (VBA) 程式碼,為文件新增內容控制。 按 ALT+F11 開啟 Visual Basic 編輯器,將程式碼貼上到程式碼視窗,點擊程序中的任意位置,然後按 F5 執行程式碼,並在範本文件中新增四個內容控制項。

         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. 在內容控制項上設定 XML 映射。

    XML 映射是 Word 的一項功能,讓你能建立文件與 XML 檔案之間的連結。 如此一來,會建立文件格式設定與自訂 XML 資料之間的真正資料/檢視區隔。

    要載入自訂 XML 部分,必須先透過 CustomXMLParts 集合的 Add 方法,將新的資料儲存加入文件物件。 這會將一個新的空白資料儲存附加到文件上。 因為是空的,你還不能用。 接著,你必須從 XML 檔案載入自訂 XML 部分,方法是呼叫 CustomXMLPart 物件的 Load 方法,該物件的參數是使用 XML 檔案的有效路徑。

  4. 儲存文件,命名為 CustomerLetterGenerator.docm。

    注意事項

    由於文件包含 VBA 程式碼,您必須將文件儲存為啟用 巨集 的文件檔 (.docm) .|

以下程序說明如何將內容控制項映射到範例自訂 XML 檔案。 你建立一個有效的自訂 XML 檔案,儲存檔案,然後使用 Visual Basic for Applications (VBA) 程式碼,將包含你想要對應的資訊儲存到範本文件中。

在內容控制項上設定 XML 映射

  1. 建立一個文字檔並儲存為 CustomerData.xml。

  2. 將以下 XML 程式碼複製到文字檔並儲存。

         <?xml version="1.0"?> 
         <Customer> 
         <CompanyName>Alfreds Futterkiste</CompanyName> 
         <ContactName>Maria Anders</ContactName> 
         <ContactTitle>Sales Representative</ContactTitle> 
         <Phone>030-0074321</Phone> 
         </Customer> 
    
  3. 按 ALT+F11 開啟 Visual Basic 編輯器,將以下程式碼貼上到程式碼視窗,點擊程序中的任意位置,然後按 F5 執行程式碼,並將 XML 檔案附加到範本文件中,使其成為可用的資料儲存項目。

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

    注意事項

    文件中至少有三個預設的自訂 XML 部分,且這些部分總是會隨文件建立:『封面頁』、『文件屬性』和『應用程式屬性』。 此外,根據多種因素,在同一台電腦上還可能建立各種自訂 XML 部分。 這些包括安裝了哪些外掛、與 SharePoint 的連線等等。 在前一段程式碼中呼叫 CustomXMLParts 集合的 Add 方法,會新增一個 XML 部分,XML 檔案會載入其中。 下一段程式碼中,就是在那個部分呼叫 Load 方法。

    為了確定要載入 XML 檔案的零件索引號,必須將自訂 XML 部分的數量傳給 Load 方法。 ActiveDocument.CustomXMLParts(ActiveDocument.CustomXMLParts.Count).Load ("C:\CustomerData.xml")

  4. 在內容控制項上設定一個 XML 映射,該控制項指向新增資料儲存中的節點。

    要建立 XML 映射,請使用 XPath 表達式指向你想映射內容控制的自訂 XML 資料部分中的節點。 當你在文件 (中新增資料儲存,且資料儲存指向有效的 XML 檔案) 後,你就可以將其中一個節點映射到內容控制項。

    為此,請使用 XMLMapping 物件的 SetMapping 方法,將包含有效 XPath字串傳遞給 ContentControl, (使用 ContentControl 物件) 的 XMLMapping 屬性。 開啟 Visual Basic 編輯器,執行以下 VBA 程式碼,將內容控制項綁定到資料儲存中的項目。

         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
    
    

建立一個 Server-Side 應用程式,從SQL Server資料庫擷取資料並產生新文件

你可以建立一個網頁應用程式,讓使用者選擇公司名稱並產生自訂字母。 這個基於網頁的應用程式會從 SQL Server 資料庫取得客戶資料,打開客戶信範本文件,並建立一個新文件,根據使用者選擇顯示客戶資料。 此網頁應用程式不需使用 Word 或 VBA。 使用你最喜歡的管理程式碼 (Visual Basic .NET 或 C#) 語言來建立這個應用程式。

注意事項

此處展示的網頁應用程式資料來自Northwind.mdf資料庫。 此資料庫是隨先前版本的 SQL Server 和 Office 安裝的。 如果你電腦上沒有 Northwind 資料庫,可以從以下網站下載: Northwind 資料庫

建立一個伺服器端應用程式,從 SQL Server 資料庫擷取資料並產生新文件

  1. 開啟 Visual Studio 或 Visual Web Developer。

  2. 建立一個 ASP.NET 網頁應用程式,並將其命名為 SqlServerSample。

    在接下來的步驟中,你將 ASP.NET 網頁應用程式連接到SQL Server資料庫。

  3. 請將以下連接字串加入 Visual Studio 專案的 Web.config 檔案。

         <connectionStrings>
         <add name="NorthwindConnectionString"
             connectionString="data source=(local);database=Northwind; integrated security=SSPI;persist security info=false;"
             providerName="System.Data.SqlClient" />
         </connectionStrings>
    
  4. 在你的 Visual Studio 專案中,將 CustomerLetterGenerator.docm 文件加入 App_Data 資料夾:右鍵點擊 App_Data,指向 新增,點擊 現有項目,瀏覽到儲存文件的位置,選取它,然後點擊 新增

  5. 為你的專案新增 WindowsBase.dll 參考:右鍵點擊 參考資料,點 選新增參考,點選 .NET 標籤,選擇 WindowsBase,然後按 確定

  6. 下載並安裝 Microsoft .NET Framework 4.0

  7. 在 Web.config 檔案中配置組裝件如下。

         <compilation debug="false">
         <assemblies>
             <add assembly="WindowsBase, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
         </assemblies>
         </compilation>
    
  8. 新增網頁表單到您的專案:在 專案 選單中,點選 新增項目;在 已安裝範本中,點擊 「網頁」;選擇 網頁表單,然後點擊 新增

  9. 在方案總管中,右鍵點擊屬性,然後點擊「開啟」。

  10. 網頁 分頁,在 開始動作中選擇 特定頁面,點擊瀏覽按鈕,然後導向頁面 WebForm1.aspx

  11. 將以下程式碼加入 WebForm1.aspx 檔案,覆蓋由開啟與關閉 <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. 根據你使用的程式語言,請在專案中適當的 WebForm1.aspx 代碼背後頁面加入以下 Visual Basic .NET 或 C# 程式碼。

範例程式碼:Visual Basic .NET

以下 Visual Basic .NET 範例展示了如何綁定 SQL Server 資料庫,根據客戶選擇取得資料,並根據 CustomerLetterGenerator.docm 範本文件建立新文件。 將以下程式碼加入 WebForm1.aspx.vb 檔案,覆蓋檔案中現有的程式碼。

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#

以下 C# 範例展示了如何綁定 SQL Server 資料庫,根據客戶選擇取得資料,並根據 CustomerLetterGenerator.docm 範本文件建立新文件。 將以下程式碼加入 WebForm1.Aspx.cs 檔案,並複製現有程式碼。

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

欲了解更多關於使用 ASP.NET 2.0 的資訊,請參見 https://www.asp.net/get-started/

本文說明如何從 SQL Server 資料庫擷取資料並將其插入範本文件中。 你也可以從其他資料來源擷取資料,例如 Access 和 Excel。 欲了解更多如何以程式方式連接這些應用程式中資料的資訊,請參閱 Access 與 Excel 開發者文件。

支援和意見反應

有關於 Office VBA 或這份文件的問題或意見反應嗎? 如需取得支援服務並提供意見反應的相關指導,請參閱 Office VBA 支援與意見反應