Freigeben über


Data Islands - Das Robinson Crusoe-Prinzip

Die Beta 2 von Visual Studio 2005 ist da. Hurra. Das Warten hat ein Ende. Verbunden damit kam auch die Beta von VSTO (Visual Studio Tools für Office). Und die brachte ein paar syntaktische Veränderungen mit sich.

Hin und wieder gibt es die Anforderung, bei einer Server-Applikation (z.B. WebApp) ein Office-Dokument erstellen bzw. mit Daten befüllen zu müssen. Wenn man nicht gleich auf WordprocessingML bzw. SpreadsheetML zurückgreifen will, kommt man schon mal in Versuchung, über das Office-Objektmodell gehen zu wollen. Das dies keine gute Idee ist, erfährt man spätestens, wenn im laufenden Betrieb eine Messagebox erscheint, die keiner wegklicken kann, weil sie keiner sieht.

Ein cooles Feature von VSTO 2.0 sind deshalb Data Islands. Es handelt sich dabei nicht darum, die eigenen sensiblen Daten auf einsamen Inseln unterzubringen, sondern um eine Möglichkeit, Daten in einem Word- oder Excel-Dokument zu speichern. Ist nichts Neues? Eigentlich nicht. Aber die Daten werden nicht direkt im Dokument gespeichert, sondern in einem extra Store, oder Stream des OLE Structured Storage Files. Und das coole daran ist, daß .NET bzw. VSTO Klassen bereitstellt, um auf diese Daten ohne den Umweg über das Office-Objektmodell zugreifen zu können.

Das sieht z.B. so aus: In der Code-behind-Klasse des Dokuments konstruieren wir eine serialisierbare Datenstruktur, ein Dataset oder auch eine Structure:

Public Structure Person
   Dim Name As String
   Dim Age As Byte
   Dim Married As Boolean
   Dim Occupation As String
End Structure

Um diese dann im dokumenteigenen Data Island unterzubringen, deklarieren wir eine Variable mit dem Attribut <cached()>:

<Cached()> Public Programmer As Person

That's it. Beim Speichern des Dokuments wird der Inhalt der Datenstruktur automatisch im Data Island abgelegt. Und zwar in Form von XML.

 

Um die Daten in einer WinForms Applikation wieder ans Tageslicht zu befördern, brauchen wir dort die Struktur erneut. Wir müssen für die spätere Deserialisierung auch noch den XMLType über ein Attribut festlegen. Stimmt der Name der Struktur mit dem derselben im Office-Dokument überein, so können wir das auch weglassen.

<XmlType(

"Person")> Public Structure PersonStruct
Dim Name As String
Dim Age As Byte
Dim Married As Boolean
Dim Occupation As String
End Structure

Um die Daten ohne das Office-Objektmodell zu bekommen, müssen wir den Namespace der Office Tools einbinden:

Imports

Microsoft.VisualStudio.Tools.Applications.Runtime

 

Jetzt können wir das ServerDocument-Objekt benutzen, um die Daten zu holen und zu deserialisieren: 

Using srvDoc As ServerDocument = New ServerDocument(<Pfad zu Office-Dokument>)
Dim serializer As XmlSerializer = New XmlSerializer(GetType(PersonStruct))
Dim xmlData As String = srvDoc.CachedData.HostItems(<ViewName>).CachedData(<DataName>).Xml
Using reader As New StringReader(xmlData)
Dim cachedPerson As PersonStruct = CType(serializer.Deserialize(reader), PersonStruct)
With cachedPerson
' Daten verarbeiten
End With
End Using
End Using

<ViewName> muß noch ersetzt werden mit dem Namen des Views, in dem sich die Daten befinden. Word besitzt by default einen StandardView, dessen Name sich zusammensetzt aus <Namespace der Solution>.ThisDocument. Excel hat einen View für jede Tabelle (Sheet).

<DataName> ist der Name der Variablen, welche im Office Dokument mit dem <cached()> Attribut versehen wurde. In unserem Fall "Programmer"

 

Natürlich kann man die Data Islands auch von außen befüllen. Dazu verwenden wir wieder ein ServerDocument und serialisieren die verwendete Struktur. Das geht dann so:

Dim DataStruct As PersonStruct
With PersonStruct
' Befüllen
End With
Using srvDoc As ServerDocument = New ServerDocument(<Pfad zum Word-Dokument>)
Dim serializer As XmlSerializer = New XmlSerializer(GetType(PersonStruct))
Dim xmlData As New StringBuilder
Using writer As New StringWriter(xmlData)
serializer.Serialize(writer, PersonStruct)
End Using
   srvDoc.CachedData.HostItems(<ViewName>).CachedData(<DataName>).Xml = xmlData.ToString
srvDoc.Save()
End Using

 

Damit ergeben sich völlig neue Möglichkeiten. Ein Office Dokument wird in einer Sharepoint Library abgelegt. Ein Benutzer öffnet das Dokument, wobei der Server die Identität des Benutzers feststellt und das Data Island mit benutzerspezifischen Daten füllt...

Denken Sie jetzt einfach weiter.

Und was hat das jetzt alles mit Robinson Crusoe zu tun? Nichts natürlich. Außer vielleicht, daß auch er am Ende wieder abgeholt wurde ...