ZIP Datei beim SharePoint-Upload automatisch entpacken

Manchmal ist es wünschenswert, dass Benutzer eine Zip-Datei auf SharePoint hochladen können, diese Datei sofort beim Upload entpackt wird und der Inhalt in einen Ordner geschrieben wird.

Mit .NET 4.5 wird eine ZipArchive Klasse im Namespace System.IO.Compression geliefert. Da SharePoint 2013 diese .NET Version verwendet, ist es ein leichtes einen Event Receiver für einen Fileupload zu schreiben der genau diese Aufgabe erfüllt. Die ZipDatei, die hochgeladen wird, wird entpackt und der Inhalt in einem neuen Ordner abgelegt.

Zur einfacheren Lesbarkeit habe ich EventReceiver und das Entpacken der Datei in 2 Klassen getrennt codiert.

Teil 1: der Eventreceiver:

   1:      public class ZipUploadEventReceiver : SPItemEventReceiver
   2:      {
   3:          /// <summary>
   4:          /// An item was added.
   5:          /// </summary>
   6:          public override void ItemAdded(SPItemEventProperties properties)
   7:          {            
   8:              if (properties.ListItem == null)
   9:                  return;
  10:   
  11:              SPFile file = properties.ListItem.File;
  12:              if (file == null)
  13:                  return;
  14:   
  15:              if (file.Name.EndsWith(".zip"))
  16:              {
  17:                  ZipToFolder.ConvertToFolder(file, properties.List);
  18:              }
  19:              properties.Status = SPEventReceiverStatus.CancelNoError;
  20:          }
  21:      }

Es ist ein ItemAdded Receiver der für Documentbibliotheken registriert wird. Im ItemAdding ist es leider zu früh, da zu diesem Zeitpunkt die Datei noch nicht zur Verfügung steht. Daher wurde der Weg gewählt, zunächst den Upload abzuwarten und nach dem Entpacken die Datei zu löschen. Diese Vorgangsweise hat nebenbei den positiven Effekt, dass der Eventreceiver weiter asynchron ablaufen kann.

in Zeile 17 wird der zweite Teil aufgerufen. Hier wird das SPFile und das SPList-Objekt übergeben.

   1:      class ZipToFolder
   2:      {
   3:          public static void ConvertToFolder(SPFile zipfile, SPList DocBib)
   4:          {
   5:              string folderName = zipfile.Name.Substring(0, zipfile.Name.Length - 4);
   6:   
   7:              Stream str = zipfile.OpenBinaryStream();
   8:              ZipArchive arch = new ZipArchive(str);
   9:              foreach (ZipArchiveEntry e in arch.Entries)
  10:              {
  11:                  
  12:                  string targetFolderUrl = folderName + "/" + e.FullName;
  13:                  string[] folders = targetFolderUrl.Split('/');
  14:                  SPFolder lastFolder = DocBib.RootFolder;
  15:                  for (int i = 0; i < folders.Count()-1; i++)
  16:                  {
  17:                      lastFolder = lastFolder.SubFolders.Add(folders[i]);
  18:                  }
  19:   
  20:                  string fileUrl = DocBib.RootFolder.ServerRelativeUrl +"/"+ folderName + "/" + e.FullName;
  21:   
  22:                  SPFile newFile = DocBib.RootFolder.Files.Add(fileUrl, e.Open());
  23:                  newFile.Update();
  24:              }
  25:              zipfile.Delete();
  26:          }
  27:      }

Der Dateiname der ZIP Datei soll der Ordnername werden. in Zeile 7 wird die Datei als Binärstream geöffnet und in Zeile 8 eine Instanz der ZipArchive Klasse von dem Stream gebildet.

Das Foreach durch die einzelnen Entrys ermöglicht den Zugriff auf jedes Element im ZipFile. Da im ZipEntry jeweils der gesamte Pfad zum Element liegt kann so der Ziel Pfad (die URL der Datei) aufgebaut werden.

Leider muss die Ordnerstruktur in SharePoint bereits angelegt sein, bevor die Datei hochgeladen werden kann. Daher wird in den Zeilen 15-18 die Struktur angelegt.

In 22 wird die Datei in SharePoint hochgeladen. Die Add-Methode erwartet die URL der Datei und den Dateiinhalt als Stream welcher von der Open() Methode des Entries geliefert wird.

Zuletzt wird in 25 noch die bereits entpackte Datei gelöscht.

Kommentare sind geschlossen