Mithilfe des OpenXML SDKs kann man sehr einfach auf Elemente wie XML oder Mediadaten innerhalb eines Office-Dokumentes zugreifen. Will man zum Beispiel sämtliche Bilder aus einem Word-Dokument extrahieren, so braucht man dazu lediglich Klassen, welche im .Net Framework ab der Version 3 vorhanden sind.
Grundlegend hierfür ist der Aufbau eines OpenXML Dokumentes: das Dokument ist im Prinzip ein Zip-Dokument, welches der Open Packaging Convention entspricht. Der Namespace System.IO.Packaging enthält hierfür die Klassen, welche wir für die Behandlung von OpenXML Dokumenten benötigen. Damit ein OpenXML-Beispiel auch Sinn macht benötigen wir zu erst ein gültiges Dokument, wo einige Bilder drinnen sind.
Damit man die Packaging-Funktionalität verwenden kann wird eine Referenz auf “WindowsBase” benötigt. Ferner werden noch Usings für System.IO und System.IO.Packaging benötigt.
using System.IO.Packaging;
using System.IO;
Ein OpenXML-Package ist in verschiedene Ordner gegliedert. Wenn man sich alle Dateien anzeigen lässt, so kann man die Dateien anhand des Mime Types unterscheiden. Damit wir JPEG Dateien filtern können, muss lediglich auf “image/jpeg” überprüft werden. Hierfür erstellen wir uns eine kleine Hilfsfunktion, welche den Mime-Type überprüft.
In dieser Hilfsfunktion wird ein PackagePart (dieser PackagePart enthält jeweils eine Datei) auf einen MimeType überprüft. Wenn es sich hierbei um ein Bild handelt wird “true” zurück gegeben.
private static bool IsMimeType(PackagePart item, MimeTypeEnum mimeType)
{
switch (item.ContentType)
{
case "image/jpeg":
if (mimeType == MimeTypeEnum.JpegImage) return true;
else return false;
break;
default:
return false;
break;
}
}
Danach erstellen wir uns eine Funktion, welche den Stream des Packageparts in einen anderen Stream schreibt. Dies wird benötigt, da wir jedes Bild in einer Datei ausgeben wollen.
Die CopyStream-Methode braucht einen Input und Output-Stream. hierbei wird vom inputStream gelesen und in den outputStream geschrieben.
private static void CopyStream(Stream inputStream, Stream outputStream)
{
byte[] streamBuffer = new byte[32768];
while (true)
{
int read = inputStream.Read(streamBuffer, 0, streamBuffer.Length);
if (read <= 0) return;
outputStream.Write(streamBuffer, 0, read);
}
}
Nun können wir uns an die Methode machen, welche uns die Grafiken abspeichert.
Hierfür wird ein Pfad als Parameter benötigt. Dieser Pfad zeigt auf unser OpenXML-Dokument. Ein “Package” stellt nun dieses OpenXML-Dokument dar. Will man das Dokument öffnen, so muss man dies mit der statischen Methode “ZipPackage.Open” machen.
Alle Dokumente, welche in einem Zip-Package (OpenXML-Dokument) vorhanden sind, können mit der “GetParts()”-Methode abgerufen werden. Hierbei bekommt man nun wieder ein Objekt vom Typ”PackagePart” zurück. Dieses Objekt wird nun mit der vorher erstellten Methode “IsMimeType” überprüft. Wenn es sich hierbei um ein Bild handelt, wird ein Pfad (mit System.IO.Path.Combine) erstellt. Der Inhalt des Packages wird mit GetStream() in die Datei geschrieben. Zu Schluss muss die Datei und das Package auch noch geschlossen werden.
private static void ListAll(string fileName)
{
Package ooxmlfile = ZipPackage.Open(fileName);
FileStream ms;
string path = string.Empty;
foreach (var itm in ooxmlfile.GetParts())
{
if (IsMimeType(itm, MimeTypeEnum.JpegImage))
{
path = System.IO.Path.Combine(@"C:\b\", string.Format("{0}.jpg", Guid.NewGuid()));
ms = new FileStream(path,FileMode.CreateNew);
CopyStream(itm.GetStream(), ms);
ms.Close();
}
}
ooxmlfile.Close();
}
Dies ist eine sehr einfache Möglichkeit um Dateien innerhalb eines OpenXML-Packages anzusprechen.