Verwenden einer VB ActiveX-Komponente für die Word-Automatisierung aus Internet Explorer

Zusammenfassung

In diesem Artikel wird veranschaulicht, wie Sie eine ActiveX-Komponente für die clientseitige Automatisierung von Word von einer Webseite aus verwenden können, die in Internet Explorer gerendert wird. Die Verwendung einer ActiveX-Komponente von einer Webseite anstelle eines Skripts, das in die Webseite selbst eingebettet ist, bietet mehrere Vorteile:

  • Wenn Sie bereits über Visual Basic-Code verfügen, der Microsoft Word automatisiert, können Sie Ihren Code im Browser wiederverwenden, indem Sie Ihr Visual Basic-Projekt in eine ActiveX-EXE oder eine ActiveX-DLL konvertieren.
  • Word ist nicht als sicher für Skripts gekennzeichnet. Abhängig von den Sicherheitseinstellungen in Internet Explorer wird Word-Automatisierungscode im Skript möglicherweise nicht ausgeführt, oder der Benutzer wird möglicherweise mit einer Sicherheitswarnung aufgefordert. Unter der Annahme, dass Ihre ActiveX-Komponente bestimmte Richtlinien erfüllt, kann sie für Skripts als sicher markiert werden, um diese Sicherheitsprobleme zu vermeiden.
  • Visual Basic verfügt über mehrere Features, die Sie nicht mit Skripts auf einer Webseite verwenden können. Ein Feature, das für Visual Basic, aber nicht für Webseitenskripts verfügbar ist, ist beispielsweise die Möglichkeit, die Windows-Api (Application Programming Interface) aufzurufen.

Ein gängiges Entwicklerszenario besteht darin, Benutzern eine Webseite zum Erstellen eines Word-Dokuments mithilfe von Daten aus einer externen Quelle oder Logik zu präsentieren. Obwohl Sie das Dokument mithilfe der serverseitigen Word-Automatisierung generieren und wieder auf den Client streamen können, gibt es viele Nachteile bei der Verwendung eines serverseitigen Ansatzes, der die Word-Automatisierung umfasst. Der Hauptnachteil ist skalierbarkeit; Word ist ein sehr ressourcenintensiver Automatisierungsserver und wird nicht für die Dokumentgenerierung auf dem Webserver empfohlen.

Mithilfe einer ActiveX-Komponente zum Ausführen der Dokumentgenerierung auf dem Client können Sie die ressourcenintensive Word-Automatisierung vom Webserver weg verschieben. Dies ist die Lösung, die von der ActiveX-Beispielkomponente vorgestellt wird, die in diesem Artikel erläutert wird. Obwohl das Beispiel spezifisch für die Word-Automatisierung ist, können dieselben Prinzipien für die Automatisierung anderer Microsoft Office-Anwendungen wie Microsoft Excel angewendet werden.

Weitere Informationen

Visual Basic ActiveX-Komponente

Die Visual Basic ActiveX-Komponente in diesem Beispiel interagiert mit dem Webseitenskript, um auf Anforderung des Benutzers ein Auftragsrechnungsdokument zu generieren. Die Webanwendung kann es der ActiveX-Komponente ermöglichen, die Bestellinformationen für eine bestimmte Auftrags-ID abzurufen, oder die Webanwendung kann die Bestellinformationen als XML verpacken und zur Verarbeitung an die ActiveX-Komponente senden. In beiden Fällen kann die Komponente, nachdem sie die Auftragsinformationen abgerufen hat, Word automatisieren, um das Rechnungsdokument für die Bestellung zu erstellen und anzuzeigen.

Die ActiveX-Komponente (AutomateWord) enthält eine einzelne Klasse, die Invoice-Klasse, die drei Methoden verfügbar macht:

  • Die GetData-Methode verwendet ActiveX Data Objects (ADO), um Informationen zu einer Bestellung in der Northwind-Beispieldatenbank zu extrahieren. Die Bestellinformationen werden in der m_Data privaten Membervariablen gespeichert. Die GetData-Methode kann aufgerufen werden, damit die Datenextraktion clientseitig erfolgt.
  • Die SendData-Methode verwendet Microsoft XML (MSXML), um die m_Data private Membervariable mit den Vom Aufrufer bereitgestellten Bestellinformationen zu füllen. SendData erwartet einen Parameter, der ein DOMDocument-Objekt für die Bestellinformationen darstellt. Die SendData-Methode kann aufgerufen werden, um die Bestellinformationen von der Webseite an die Komponente zu senden. Bei diesem Ansatz können Sie ASP verwenden, um die serverseitige Daten zu extrahieren und dem Client eine XML-Dateninsel zu präsentieren, die für die Dokumentgenerierung verwendet werden kann.
  • Die MakeInvoice-Methode verwendet Word Automation, um ein Dokument zu erstellen, das die Bestellinformationen in der m_Data privaten Membervariablen enthält. Ein Dokument, das auf dem Webserver gespeichert ist, wird als Ausgangspunkt für die Rechnung verwendet. Der Aufrufer kann das fertige Word-Dokument außerhalb des Browsers anzeigen oder das fertige Dokument zur späteren Verwendung auf einem Datenträger speichern.

Invoice.cls

Option Explicit

Private Type InvoiceData
    OrderID As String
    OrderDate As Date
    CustID As String
    CustInfo As String
    ProdInfo As Variant
End Type

Private m_Data As InvoiceData

Public Sub GetData(sOrderID As Variant, sConn As Variant)

Dim oConn As Object, oRS As Object

'Connect to the Northwind database.
    Set oConn = CreateObject("ADODB.Connection")
    oConn.Open sConn

'Obtain the Customer ID and Order Date.
    Set oRS = CreateObject("ADODB.Recordset")
    oRS.Open "Select [OrderDate], [CustomerID] from Orders where " & _
             "[OrderID]=" & sOrderID, oConn, 3 'adOpenStatic=3
    m_Data.OrderID = sOrderID
    m_Data.OrderDate = CDate(oRS.Fields("OrderDate").Value)
    m_Data.CustID = oRS.Fields("CustomerID").Value
    oRS.Close

'Obtain Customer information.
    Set oRS = CreateObject("ADODB.Recordset")
    oRS.Open "Select * from Customers Where CustomerID='" & _
             m_Data.CustID & "'", oConn, 3 'adOpenStatic=3
    m_Data.CustInfo = oRS.Fields("CompanyName").Value & vbCrLf & _
                      oRS.Fields("City") & " "
    If Not (IsNull(oRS.Fields("Region"))) Then
       m_Data.CustInfo = m_Data.CustInfo & oRS.Fields("Region").Value & " "
    End If
    m_Data.CustInfo = m_Data.CustInfo & oRS.Fields("PostalCode").Value & _
                      vbCrLf & oRS.Fields("Country").Value
    oRS.Close

'Obtain Product information.
    Set oRS = CreateObject("ADODB.Recordset")
    oRS.Open "Select ProductName, Quantity, [Order Details].UnitPrice," & _
             "Discount from Products Inner Join [Order Details] on " & _
             "Products.ProductID = [Order Details].ProductID " & _
             "Where OrderID = " & sOrderID, oConn, 3 'adOpenStatic=3
    m_Data.ProdInfo = oRS.GetRows
    oRS.Close

'Close the connection to the database.
    oConn.Close

End Sub

Public Sub SendData(oXML As Variant)

'Extract the information from the DOMDocument object oXML and store
    'it in the private member variable m_Data.

m_Data.OrderID = oXML.getElementsByTagName("OrderID").Item(0).Text
    m_Data.OrderDate = oXML.getElementsByTagName("OrderDate").Item(0).Text
    m_Data.CustID = oXML.getElementsByTagName("CustID").Item(0).Text
    m_Data.CustInfo = oXML.getElementsByTagName("CustInfo").Item(0).Text

Dim oItems As Object, oItem As Object
    Set oItems = oXML.getElementsByTagName("Items").Item(0)
    ReDim vArray(0 To 3, 0 To oItems.childNodes.Length - 1) As Variant
    Dim i As Integer
    For i = 0 To UBound(vArray, 2)
        Set oItem = oItems.childNodes(i)
        vArray(0, i) = oItem.getAttribute("Desc")
        vArray(1, i) = oItem.getAttribute("Qty")
        vArray(2, i) = oItem.getAttribute("Price")
        vArray(3, i) = oItem.getAttribute("Disc")
    Next
    m_Data.ProdInfo = vArray

End Sub

Public Sub MakeInvoice(sTemplate As Variant, Optional bSave As Variant)

Dim oWord As Object
    Dim oDoc As Object
    Dim oTable As Object

If IsMissing(bSave) Then bSave = False

'Open the document as read-only.
    Set oWord = CreateObject("Word.Application")
    Set oDoc = oWord.Documents.Open(sTemplate, , True)

'Fill in the bookmarks.
    oDoc.Bookmarks("Customer_Info").Range.Text = m_Data.CustInfo
    oDoc.Bookmarks("Customer_ID").Range.Text = m_Data.CustID
    oDoc.Bookmarks("Order_ID").Range.Text = m_Data.OrderID
    oDoc.Bookmarks("Order_Date").Range.Text = m_Data.OrderDate

'Fill in the table with the product information.
    '** Note that the table starts out with three rows -- the first row
    '   contains headers for the table, the second row is for
    '   the first set of product data, and the third row contains a total.
    '   New rows are added for additional products before the "total row".

Set oTable = oDoc.Tables(1)
    Dim r As Integer, c As Integer
    For r = 1 To UBound(m_Data.ProdInfo, 2) + 1
        If r > 1 Then oTable.Rows.Add (oTable.Rows(oTable.Rows.Count))
        For c = 1 To 4
            oTable.Cell(r + 1, c).Range.Text = _
               m_Data.ProdInfo(c - 1, r - 1)
        Next
        oTable.Cell(r + 1, 5).Formula _
            "=(B" & r + 1 & "*C" & r + 1 & ")*(1-D" & r + 1 & ")", _
            "#,##0.00"
    Next

'Update the field for the grand total and protect the document.
    oTable.Cell(oTable.Rows.Count, 5).Range.Fields.Update
    oDoc.Protect 1 'wdAllowOnlyComments=1

If bSave Then
        'Save the document as "c:\invoice.doc" and quit Word.
        Dim nResult As Long
        nResult = MsgBox("Are you sure you wish to create the document" & _
             " ""c:\invoice.doc""? If this document already exists, " & _
             "it will be replaced", vbYesNo, "AutomateWord")
        If nResult = vbYes Then oDoc.SaveAs "c:\invoice.doc"
        oDoc.Close False
        oWord.Quit
    Else
        'Make Word visible.
        oWord.Visible = True
    End If

End Sub

Verwenden der ActiveX-Komponente von einer Webseite

Autoword1.htm veranschaulicht, wie Sie die GetData-Methode verwenden können, damit die ActiveX-Komponente die Auftragsdaten clientseitig abrufen und das Dokument erstellen kann.

Autoword1.htm

<HTML>
<HEAD>
   <OBJECT ID="AutoWord"
    CLASSID="CLSID:32646EBA-0919-4C2F-94D6-599F46DC34F2"
    CODEBASE="https://YourWebServer/invoice/package/AutomateWord.CAB#version=1,0,0,0">
   </OBJECT>
</HEAD>
<BODY>
Enter an order id between 10248 and 11077 and click the button to view the invoice for the order:
<P/><INPUT TYPE="text" VALUE="10500" ID="OrderID">
<P/><BUTTON ID="InvoiceButton">Create Invoice</BUTTON>
</BODY>

<SCRIPT Language="VBScript">

Function InvoiceButton_OnClick()
      Dim sConn
      sConn = "Provider=sqloledb;Data Source=YourSQLServer;Initial Catalog=Northwind;UID=sa;"
      AutoWord.GetData OrderID.Value, sConn
      AutoWord.MakeInvoice "https://YourWebServer/invoice/invoice.doc"
   End Function

</SCRIPT>
</HTML>

Das Skript in Autoword1.htm verwendet die ActiveX-Komponente, um das fertige Dokument außerhalb des Browsers anzuzeigen. Sie können auch das fertige Dokument speichern und im Browser anzeigen. Dies erfordert jedoch, dass das Word-Dokument auf einem Datenträger gespeichert wird. Die Komponente kann das Dokument als C:\Invoice.doc auf dem lokalen Laufwerk des Clients speichern. Da die ActiveX-Komponente als sicher für Skripting gekennzeichnet ist, wird der Client aufgefordert, den Speichervorgang zu bestätigen.

Wenn Sie das fertige Dokument im Browser anzeigen möchten, ändern Sie den Aufruf von MakeInvoice in Autoword1.htm wie folgt:

      AutoWord.MakeInvoice "https://YourWebServer/invoice/invoice.doc", True
      window.navigate "c:\invoice.doc"

Autoword2.htm veranschaulicht, wie Sie die SendData-Methode verwenden können, um die Bestelldaten als DOMDocument-Objekt an die ActiveX-Komponente zum Generieren des abgeschlossenen Dokuments zu senden. Das DOMDocument wird aus einer XML-Dateninsel erstellt, die sich auf der Webseite befindet. Damit die ActiveX-Komponente die vom Aufrufer gesendeten Bestellinformationen ordnungsgemäß verarbeiten kann, muss der XML-Code wohlgeformt und strukturiert sein, damit die Komponente sie als Bestellinformationen interpretieren kann.

Autoword2.htm

<HTML>
<HEAD>
   <OBJECT ID="AutoWord"
    CLASSID="CLSID:32646EBA-0919-4C2F-94D6-599F46DC34F2"
    CODEBASE="https://YourWebServer/invoice/package/AutomateWord.CAB#version=1,0,0,0">
   </OBJECT>
</HEAD>
<BODY>
   <BUTTON ID="InvoiceButton">Create Invoice</BUTTON>
   <XML ID="DataXML">
     <Order>
        <OrderID>10700</OrderID>
        <OrderDate>10/10/2000</OrderDate>
        <CustID>SAVEA</CustID>
        <CustInfo>Save-a-lot
Markets Boise ID 83720
USA</CustInfo>
        <Items>
           <Product Desc="Chai" Qty="5" Price="18" Disc="0.2"/>
           <Product Desc="Sasquatch Ale" Qty="12" Price="14" Disc="0.2"/>
           <Product Desc="Scottish Longbreads" Qty="40" Price="12.5" Disc="0.2"/>
           <Product Desc="Flotemysost" Qty="60" Price="21.5" Disc="0.2"/>
        </Items>        
     </Order>
   </XML>
</BODY>

<SCRIPT Language="VBScript">

Function InvoiceButton_OnClick()
      AutoWord.SendData DataXML.XMLDocument
      AutoWord.MakeInvoice "https://YourWebServer/invoice/invoice.doc"
   End Function

</SCRIPT>
</HTML>

In Autoword1.htm und Autoword2.htm sollten Sie beachten, dass die ActiveX-Komponente anstelle der CreateObject-Funktion durch ein Tag instanziiert wird. Der Zweck der Verwendung des Tags besteht darin, den automatischen Download der ActiveX-Komponente für Benutzer zu aktivieren, für die die Komponente noch nicht installiert ist. Wenn ein Benutzer eine dieser Seiten besucht und die Komponente nicht installiert ist, wird die Komponente aus der CAB-Datei (CAB) unter der URL heruntergeladen, die im CODEBASE-Attribut angegeben ist. Je nach den Sicherheitseinstellungen des Benutzers in Internet Explorer wird er möglicherweise zuerst aufgefordert, den Download zu bestätigen.

HINWEIS: Die CAB-Datei, die in Autoword.exe enthalten ist, wurde mit dem Paket- und Bereitstellungs-Assistenten für Visual Basic erstellt. Die ActiveX-Komponente im Paket ist als sicher für Skripting und Initialisierung gekennzeichnet, aber nicht digital signiert.

Weitere Informationen zum Erstellen von Downloads von Internetkomponenten, zum digitalen Signieren und Zum Kennzeichnen von Komponenten als sicher für Skripting und Initialisierung finden Sie auf den folgenden Microsoft Developer Network (MSDN)-Websites:

Signieren und Überprüfen von Code mit Authenticode https://msdn.microsoft.com/en-us/library/ms537364.aspx

Sichere Initialisierung und Skripting für ActiveX-Steuerelemente https://msdn.microsoft.com/en-us/library/Aa751977.aspx

References

Wenn Sie weitere Informationen benötigen, klicken Sie auf die folgenden Artikelnummern, um die Artikel in der Microsoft Knowledge Base anzuzeigen:

257757 INFO: Die Automatisierung von Office für unbeaufsichtigte Ausführung wird nicht empfohlen oder unterstützt

(c) Microsoft Corporation 2001, Alle Rechte vorbehalten. Beiträge von Lori B. Turner, Microsoft Corporation.