Zip contents of a document library…


Hi Folks,

So here I am with another very interesting post which is about zipping the contents of a document library and saving them on a network or local location. Actually I am currently working on a huge MOSS based project for Trubiquity, it a huge application with very large number of employees. The basic objective of the application is to facilitate the clients (with multiple teams)  to manage their projects on a central location with all project management functionality, so SharePoint (MOSS) platform was chosen for it and rightly so, because of the fact that we need project management template with some out of the box feature including KPI, dashboards and many more….

Now the scanerio: There was a client request that whenever, he closes a project, he wants to zip the contents of the document library (in future, it may expand to any library) to any downloadable location. So I used SharePoint’s OM (object model) to achieve the functionality as this piece of code will eventually get wrapped inside a web-service so that it can be called from a remote location as well.

First the pre-Req: As the requirement is to zip all files and as document library can consist of multiple folder hierarchies, so first we need to create the same folder structure on any location (may be remote as well) from where  I will zip it. So I have used some J# classes as well to zip the folders.

Now the Solution with code and explanation: So here it is, the solution and code.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using Microsoft.SharePoint;

using System.Collections;
using System.IO;
using java.util.zip;

namespace CloseSiteFeature
{
    public partial class frmMain : Form
    {
        SPSite aSite = new SPSite("http://vm-winserver");
        Hashtable ListsTable = new Hashtable(); // to bind a combo box with a datasource which will be a hashtable in this case.
        bool IsLoaded = false;

        string SavePath = @"\mac-ali3My Shared";
        string RootPath = string.Empty;

        BindingSource bs = new BindingSource();
        SPWeb aWeb;

        public frmMain()
        {
            InitializeComponent();
        }

        private void frmMain_Load(object sender, EventArgs e)
        {
            aWeb = aSite.OpenWeb();

            foreach (SPList aList in aWeb.Lists)
            {
                if (aList.Hidden == false && aList.Title.ToString() != "Form Templates")
                {
                    if (aList.BaseType.ToString() == "DocumentLibrary" && aList.BaseTemplate.ToString() == "DocumentLibrary")
                    {
                        ListsTable.Add(aList.Title.ToString(), aList.RootFolder.ServerRelativeUrl.ToString());
                    }
                }
            }

            bs.DataSource = ListsTable;

            cmbDocLibs.DataSource = bs;
            cmbDocLibs.DisplayMember = "Key";
            cmbDocLibs.ValueMember = "Value";

            IsLoaded = true;
        }

       

        System.IO.DirectoryInfo DirInfo = null;
        SPFolder aFolder;

        private void cmbDocLibs_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (IsLoaded)
            {
                try
                {
                    aFolder = aWeb.Folders[cmbDocLibs.SelectedValue.ToString()];
                    Directory.CreateDirectory(SavePath + aFolder.Name.ToString());
                    DirInfo = new DirectoryInfo(SavePath + aFolder.Name.ToString());
                    RootPath = SavePath + "\" + aFolder.Name.ToString();
                    GetSPFolderContents(aFolder, RootPath);

                    java.io.FileOutputStream fos = new java.io.FileOutputStream(@SavePath + aFolder.Name.ToString() +".zip");
                    java.util.zip.ZipOutputStream zos = new java.util.zip.ZipOutputStream(fos);
                    System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(@SavePath + aFolder.Name.ToString() + "\");
                    ZipDirectory(fos, zos, di, @SavePath + aFolder.Name.ToString() +"\");
                    zos.close();
                    fos.close();
                    zos.flush();
                    fos.flush();

                    MessageBox.Show("Successfully done!");
                }

                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message.ToString());
                }
                finally
                {
                    DirInfo = new DirectoryInfo(SavePath + aFolder.Name.ToString());
                    DirInfo.Delete(true);
                }
            }
        }

        private void ZipDirectory(java.io.FileOutputStream fos, java.util.zip.ZipOutputStream zos,System.IO.DirectoryInfo di,String SRootDir)
        {
            java.io.FileInputStream fis;
            java.util.zip.ZipEntry ze;
            
            //to get file info from the directory
            
            System.IO.FileInfo[] fInfos = di.GetFiles();
            
            foreach(System.IO.FileInfo fInfo in fInfos)
            {
                //Debug.Write(string.Format("Zipping {0}rn", fInfo.FullName));
                //give the zip entry or the folder arrangement for the file
                ze = new java.util.zip.ZipEntry(fInfo.FullName.Substring(SRootDir.LastIndexOf("\") + 1));
                //The DEFLATED method is the one of the methods to zip a file
                ze.setMethod(ZipEntry.DEFLATED);
                zos.putNextEntry(ze);
                //Input stream for the file to zip
                fis = new java.io.FileInputStream(fInfo.FullName);
                //Copy stream is a simple method to read a file input stream (file to zip) and write it to a file output stream(new zip file)
                CopyStream(fis, zos);
                zos.closeEntry();
                fis.close();
            }
            
            //If the directory contains the sub directory the call the same procedure
            
            System.IO.DirectoryInfo[] dinfos = di.GetDirectories();
            
            foreach (System.IO.DirectoryInfo dinfo in dinfos)
            {
                //Debug.Write(string.Format("Zipping directory {0}rn", dinfo.FullName));
                ZipEntry dirEntry = new ZipEntry(dinfo.FullName.Substring(SRootDir.LastIndexOf("\") + 1) + Path.DirectorySeparatorChar);
                zos.putNextEntry(dirEntry);
                ZipDirectory(fos, zos, dinfo, SRootDir);
            }
            
        }

        void CopyStream(java.io.FileInputStream src, java.util.zip.ZipOutputStream dest)
        {
            java.io.InputStreamReader reader = new java.io.InputStreamReader(src);
            java.io.OutputStreamWriter writer = new java.io.OutputStreamWriter(dest);

            while (reader.ready())
                writer.write(reader.read());

            writer.flush();
        }

        private void GetSPFolderContents(SPFolder Folder, string path)
        {
            byte[] binFile;

            foreach (SPFile aFile in Folder.Files)
            {
                binFile = aFile.OpenBinary();
                if (binFile.Length >= 0)
                {
                    FileStream fs = new FileStream(path + "\" + aFile.Name.ToString(), FileMode.OpenOrCreate, FileAccess.Write);
                    fs.Write(binFile, 0, binFile.Length);
                    fs.Close();
                }
            }

            if (Folder.SubFolders.Count > 0)
            {
                foreach (SPFolder subFolder in Folder.SubFolders)
                {
                    if (subFolder.Name != "Forms" && subFolder.ParentFolder.Name.ToString() == path.ToString().Substring(path.LastIndexOf("\") + 1))
                    {
                        DirInfo = new DirectoryInfo(path);
                        DirInfo.CreateSubdirectory(subFolder.Name.ToString());
                        RootPath = path;
                        GetSPFolderContents(subFolder, path + "\" + subFolder.Name.ToString());
                    }
                }
            }
            else
                path = RootPath;
        }
    }
}

Happy SharePointing and please keep me posted so that I can make any further changes/enhancement if required. Thanks

Regards,
Muneeb

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: