Tracking-Info
Blog

+49 - 511 - 270 416 0

info@aldebaran.de

Philipp Urner

Workflow
mit ASP.Net und MS Word

von Philipp Urner, 20.02.2015 Tags: aldebaran, Webanwendung, ASP.Net mit Word, Workflow

Worum es geht

Für Talanx Reinsurance Broker sollte ein Datenaustausch zwischen MS Word Dokumenten und einer bestehenden ASP.NET Webanwendung realisiert werden.

Über die Anwendung werden Word-Dokumente erstellt und zum Download angeboten. Der Benutzer nimmt an diesen Dokumenten in seiner lokalen Word-Instanz Überarbeitungen vor. Danach soll das komplette Word-Dokument mit einem Word-Makro wieder in die Webanwendung hochgeladen werden.

Das Ganze sollte für MS Word ab Version 2010 funktionieren.

Die serverseitige Erstellung der Word-Dokumente aus Templates war mit dem Open XML SDK recht problemlos zu realisieren.

Der kritische Punkt war der Upload von Word nach ASP.NET.

Die Umsetzung

Die ASP.NET Webanwendung stellt eine Seite für den programmatischen Upload des Dokuments bereit. Das Hochladen wird automatisch durch ein VBA-Makro in dem Word-Dokument durchgeführt. Wichtig hierbei ist mir gewesen, dass der HTTP Post so aufgebaut ist, dass auf der ASP.NET-Seite das Dokument in der Files Auflistung des HttpRequest-Objektes, mit dem wir den HTTP Post entgegen nehmen, enthalten ist. Das bietet den Vorteil, dass der Inhalt des HTTP Post nicht eigenhändig geparsed werden muss, sondern die vom .NET Framework eingebauten Mechanismen genutzt werden können.

Hierfür habe ich in MS Word ein Makro geschrieben. Das Makro selbst speichert zuerst das aktuelle Dokument um sicherzustellen, dass der aktuellste Stand übertragen wird.

Dann wird der Inhalt des Dokuments als byte Array ausgelesen, um den HTTP Post zusammenbauen zu können.

Quelltext:  Alles auswählen  |  Zeilennummerierung an/aus
  1. Const STR_BOUNDARY As String = "3fbd04f5-b1ed-4060-99b9-fca7ff59c113"
  2.     Dim postData As String
  3.    
  4.     Dim fileBuffer As Byte
  5.     Dim docmContent As String
  6.     docmContent = ReadFile(fileName)
  7.        
  8.     postData = "--" & STR_BOUNDARY & vbCrLf & _
  9.     "Content-Disposition: form-data; name=""uploaddocm""; filename=""" & Mid$(fileName, InStrRev(fileName, "\") + 1) & """" & vbCrLf & _
  10.     "Content-Type: application/octet-stream" & vbCrLf & vbCrLf & _
  11.     docmContent & vbCrLf & _
  12.     "--" & STR_BOUNDARY & "--"
  13.  

Dieser wird dann an die ASP.NET Seite geschickt.

Quelltext:  Alles auswählen  |  Zeilennummerierung an/aus
  1. With CreateObject("Microsoft.XMLHTTP")
  2.         .Open "POST", url, False
  3.         .SetRequestHeader "Content-Type", "multipart/form-data; boundary=" & STR_BOUNDARY
  4.         .Send pvToByteArray(postData)
  5.         If Not bAsync Then
  6.             pvPostFile = .ResponseText
  7.         End If
  8.     End With
  9.  

Auf der ASP.NET Seite können wir das Word-Dokument aus der Files Auflistung des HttpRequest-Objekts auslesen und weiterverarbeiten.

Word Variablen zur Parameterübergabe

Da die URL der ASP.NET-Anwendung nicht statisch im Word-Dokument hinterlegt werden soll, musste ich eine Lösung finden, bei der die URL durch die Webanwendung in dem Dokument hinterlegt werden kann.

Hier habe ich wieder auf das Open XML SDK zurückgegriffen.

Das SDK bietet die Möglichkeit, in einem Word-Dokument Variablen zu setzen.

Quelltext:  Alles auswählen  |  Zeilennummerierung an/aus
  1. using (var document = WordprocessingDocument.Open(stream, true))
  2. {
  3.     var documentVariables = document.MainDocumentPart.DocumentSettingsPart.Settings.Descendants<DocumentVariables>()
  4.                                     .FirstOrDefault();
  5.     if (documentVariables == null)
  6.     {
  7.         documentVariables = new DocumentVariables();
  8.         var compatibility = document.MainDocumentPart.DocumentSettingsPart.Settings.Descendants<Compatibility>()
  9.                                     .FirstOrDefault();
  10.         compatibility.InsertAfterSelf(documentVariables);
  11.     }
  12.    
  13.     var variable = new DocumentVariable {Name = “URL”, Val = “Value”};
  14.     documentVariables.Append(variable);
  15.    
  16.     document.MainDocumentPart.Document.Save();
  17. }
  18.  

Im Word-Makro kann jetzt problemlos auf die Variable zugegriffen werden. So war es mir möglich die URL dynamisch zu übergeben.

Quelltext:  Alles auswählen  |  Zeilennummerierung an/aus
  1. Dim url As String
  2. url = ActiveDocument.Variables("URL").Value

Fazit

Der Datenaustausch zwischen ASP.NET und VBA funktioniert sehr gut, wenn man weiß, worauf man achten muss. Hat man die ersten Hindernisse überwunden, kommt man schnell zu Ergebnissen. Das Open XML SDK ist hierbei eine große Hilfe gewesen, und wird mittlerweile auch in anderen Bereichen, in denen es um die Erzeugung und Änderung von Word-Dokumenten geht, von mir eingesetzt.