Word, ASP e gli out-of-process components

di Oscar D'Angelo, in COM & WebClass,

Spesso può capitare di voler realizzare dinamicamente un documento su un server web e, per tale scopo, vengono spesso utilizzati strumenti che permettono di realizzare pagine HTML (CGI, PERL e ASP) ma la formattazione e, soprattutto, la stampa del documento risultante  spesso non raggiungono i livelli di qualità desiderati.

Una soluzione a questo problema può derivare dall'interfacciamento di un server web dinamico con programmi di elaborazione testi ed in rete esistono alcuni articoli che trattano l'argomento e relativamente ad ASP è utile segnalare questo per la realizzazione di file in Acrobat Portable Document Format (PDF) oppure questo per generare un file di Microsoft Word contenente delle tabelle.

In questo articolo cercherò di illustrare una soluzione leggermente diversa da quella prospettata sull'articolo di ASPToday per interfacciare Word 97 con il server ASP di IIS 4.0; questa possibilità deriva dall'implementazione della tecnologia COM sul server e in Word 97. Ad eccezione della parte dell'articolo dedicata alla configurazione del server, il contenuto degli esempi si può estendere a Windows Scripting Host con i piccoli ed ovvi aggiustamenti necessari.

Configurazione del server

Per prima cosa vediamo come occorre configurare il server tenendo presente che in seguito si farà riferimento ad una configurazione basata su Windows NT4 con Service Pack 4, Option Pack 4 ed ovviamente Word 97. Il discorso può essere esteso anche ad altre configurazioni, come Windows 98 con Peer Web Server.

Nell'interfacciamento fra il VBA (di Word) e il VBScript (del server) possono generarsi degli errori Type Mismatch che sono risolti dalla SR-1 di Office come descritto in questo articolo della KB di Microsoft che quindi dovrà essere installata sul server dopo aver installato Word.

Word non può essere invocato direttamente dal server perchè risulta un'applicazione esterna al processo e per motivi di sicurezza le impostazioni di base di IIS 4 non permettono l'esecuzione di oggetti Out Of Process. Quindi occorre abilitare esplicitamente tale funzione riducendo il livello di sicurezza del server.

Vi invito quindi a fare una valutazione preventiva prima di effettuare le operazioni che seguono.

Esiste un documento on-line di MSDN che spiega i passi necessari per abilitare l'esecuzione di oggetti esterni al processo che in sintesi può realizzarsi mediante lo script che segue in cui si può aumentare il livello di sicurezza finale cambiando la stringa IIS://LocalHost/W3svc con il percorso completo della directory virtuale che conterrà l'applicazione che utilizza Word.

On Error Resume Next
' Ottiene l'oggetto IIsWebService Admin
Set oWebService = GetObject("IIS://LocalHost/W3svc")
If (Err.Number <> 0) Then
    ReportError ()
End If
' Abilita AspAllowOutOfProcComponents
oWebService.Put "AspAllowOutOfProcComponents", True
If (Err.Number <> 0) Then
   ReportError ()
End If
' Salva il cambiamento nel database
oWebService.SetInfo

If (Err.Number <> 0) Then
   ReportError ()
End If

Sub ReportError ()
   Dim ErrorDescription
   Select Case (Err.Number)
   Case &h80070003
     ErrorDescription = "Non è possibile trovare il path richiesto."
   Case &h80070005
     ErrorDescription = "Accesso negato per la proprietà o il path richiesto."
   Case &h80070094
     ErrorDescription = "Il path richiesto è in uso da un'altra applicazione."
   Case Else
        ErrorDescription = Err.Description
   End Select
   WScript.Echo ErrorDescription
   WScript.Echo "Errore Numero: " & Err.Number & " (0x" & Hex(Err.Number) & ")"
End Sub 

Lo script va salvato con estensione .vbs ed eseguito mediante cscript o wscript, tramite WSH (a tal proposito si veda questo articolo ).

ATTENZIONE : prima di effettuare questa operazione è consigliabile fare il backup del file c:\winnt\system32\inetsrv\metabase.bin dalla MMC. Questo file contiene tutte le impostazioni di IIS e la sua corruzione può comportare il malfunzionamento o il bloccaggio totale dell'intero server.

Dopo aver fatto la modifica occorre impostare la proprietà Run In Separate Memory Space dalla MMC per la directory contenente l'applicazione e quindi riavviare il server.

Dalla teoria alla pratica

Per la realizzazione dei programmi avrete necessità di consultare la documentazione relativa al modello ad oggetti di Word 97 contenuta nel file Vbawrd8.hlp, che però nella configurazione standard di Office non viene installato.

Esistono due metodi per accedere a Word: il primo consiste nell'avviare un'istanza di Word ogni volta che risulti necessario realizzare un documento. La seconda consiste nell'eseguire il programma come oggetto avente scope application accertandosi che possa essere utilizzato da un solo utente alla volta.

Il primo metodo richiede molta memoria RAM e il tempo necessario a lanciare ogni volta un'istanza di Word. Il secondo metodo implica l'impossibilità di generare due documenti per due utenti diversi contemporaneamente. Ovviamente è necessaria un'attenta valutazione prima di decidere quale metodo utilizzare, basandosi sul numero di accessi concorrenti, la quantità di RAM installata, i tempi di esecuzione ecc. Di seguito viene realizzata una soluzione con il secondo metodo.

La realizzazione di un'istanza di Word avente scope application può avvenire mediante la seguente istruzione da inserire nel file global.asa:

 <OBJECT RUNAT=Server SCOPE=Application ID=wrdApp PROGID="Word.Application"> </OBJECT>
<SCRIPT LANGUAGE="VBScript" RUNAT="Server">
Sub Application_OnStart
  ' nasconde Word
  wrdApp.Visible = False
End Sub
Sub Application_OnEnd
  ' Chiude word senza salvare i documenti
  wrdApp.Quit(0)
  '   Rilascia la memoria allocata
  set wrdApp = Nothing
End Sub
</SCRIPT>

In questo modo Word potrà essere invocato da qualsiasi pagina asp mediante wrdApp e, poichè abbiamo detto che non si possono avere due accessi concorrenti all'oggetto, la pagina asp dovrà bloccare l'applicazione e poi accedere all'oggetto stesso:

<%
application.lock
  ' Qui andranno tutte le istruzioni per
  ' eseguire l'elaborazione mediante word
  application.unlock
%>

Il secondo passo consiste nel cancellare tutti i documenti eventualmente rimasti aperti per cause varie.

<%
application.lock
For Each MyDoc In wrdApp.Documents
  MyDoc.Close(0)
Next
' Qui andranno tutte le istruzioni per
' eseguire l'elaborazione mediante word
application.unlock
%>

Vediamo che è possibile invocare Word mediante l'identificativo dichiarato in global.asa (wrdApp).

Successivamente si dovrà realizzare un nuovo documento partendo da un modello predefinito:

<%
application.lock
For Each MyDoc In wrdApp.Documents
  MyDoc.Close(0)
Next
Root = "c:/InetPub/wwwroot"
Folder = "/Word"
Template = Folder & "/Modelli/ModelloDocumento.dot"
Docs = Folder & "/Docs"
File = "Prova.doc" 
Set MyDoc = wrdApp.Documents.Add(Root & Template)
' Qui andranno tutte le istruzioni per
' eseguire l'elaborazione mediante word
MyDoc.SaveAs(Root & Docs & "/" & File)
MyDoc.Close(0)
application.unlock
response.write("<a href='" & Docs & "/" & File & "'>Il documento generato</a>") %>

E' consigliabile definire dei segnalibri all'interno del modello di partenza in modo da rendere più semplice il posizionamento del punto di inserimento del testo o l'eventuale cancellazione:

MyDoc.Bookmarks("NomeSegnalibro").Select
wrdApp.Selection.InsertAfter("testo da inserire")

oppure

MyDoc.Bookmarks("NomeSegnalibro").Select
wrdApp.Selection.Delete

A questo punto potete utilizzare tutte le proprietà ed i comandi che la struttura ad oggetti di Word mette a disposizione nell'ambiente nativo.

Come si può capire, è relativamente semplice manipolare un file Word con una pagina ASP. Ovviamente il discorso può estendersi con ottimi risultati anche ad altri programmi che espongono un'interfaccia COM, come Excel o più in generale i prodotti della famiglia Office.

Contenuti dell'articolo

Commenti

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Approfondimenti

Nessuna risorsa collegata