Download files as Zip File in SharePoint

Download files as Zip File in SharePoint
4 votes, 5.00 avg. rating (98% score)

Introduction

In this post we will see how to download selected document library items as zip file. The zip file creation api is from open source code of icsharpcode.net

Skill Level – Medium

Download files as Zip

When I am working on this requirement, I happened to check icharpcode.net which was very helpful with its api to create zip file.
The next step is to get the selected document library items and just call the api to create zip file. We need to provide one button in ribbon so that users can click it to save the zip file. In the button click we will have the code to read selected items and generate zip file.

The same logic I found in this site http://www.deviantpoint.com/post/2010/05/08/SharePoint-2010-Download-as-Zip-File-Custom-Ribbon-Action.aspx. But, download zip is not working for subsites and also to the sites that does not have managed path.

As many users are using that code, I am only modifying the code and maintain the credibility to Deviantpoint.com. The feature will still have the same name ‘DeviantPoint Download Zip Feature’ and the new code will be working for subsites and also for the sites that does not have managed path.

Following are the main methods to download as zip file, other code is just to create ribbon button and call these methods when button is clicked

		using (MemoryStream ms = new MemoryStream())
		{
			using (ZipFileBuilder builder = new ZipFileBuilder(ms))
			{
				foreach (int id in itemsIDs)
				{
					SPListItem item = library.GetItemById(id);
					if (item.IsFolder())
						AddFolder(builder, item.Folder, string.Empty);
					else
						AddFile(builder, item.File, string.Empty);
				}

				builder.Finish();
				WriteStreamToResponse(ms);
			}
		}

		private static void AddFile(ZipFileBuilder builder, SPFile file, string folder)
        {
            using (Stream fileStream = file.OpenBinaryStream())
            {
                builder.Add(folder + "\\" + file.Name, fileStream);
                fileStream.Close();
            }
        }

        private void AddFolder(ZipFileBuilder builder, SPFolder folder, string parentFolder)
        {
            string folderPath = parentFolder == string.Empty ? folder.Name : parentFolder + "\\" +folder.Name;
            builder.AddDirectory(folderPath);

            foreach (SPFile file in folder.Files)
            {
                AddFile(builder, file, folderPath);
            }

            foreach (SPFolder subFolder in folder.SubFolders)
            {
                AddFolder(builder, subFolder, folderPath);
            }
        }

        private void WriteStreamToResponse(MemoryStream ms)
        {
            if (ms.Length > 0)
            {
                string filename = DateTime.Now.ToFileTime().ToString() + ".zip";
                Response.Clear();
                Response.ClearHeaders();
                Response.ClearContent();
                Response.AddHeader("Content-Length", ms.Length.ToString());
                Response.AddHeader("Content-Disposition", "attachment; filename=" + filename);
                Response.ContentType = "application/octet-stream";

                byte[] buffer = new byte[65536];
                ms.Position = 0;
                int num;
                do
                {
                    num = ms.Read(buffer, 0, buffer.Length);
                    Response.OutputStream.Write(buffer, 0, num);
                }

                while (num > 0);

                Response.Flush();
            }
        }

ZipFileBuilder is the class file that is created to call the Zip api and it is available in the source code
‘itemsIDs’ is the array of selected items of the document library that should be filled. When Download button is clicked, it is this array we fill.

If you do not want to use Zip file code to download, then write object model code to download files in the download button click event.

To summarize,

1) Download the code
2) Deploy the wsp ( Site collection level feature ‘DeviantPoint Download Zip Feature’ will be created)
3) Activate the sitecollection feature ‘DeviantPoint Download Zip Feature’
(Tip- siteurl/_layouts/ManageFeatures.aspx?Scope=Site will show you sitecollection features)
4) ‘Download as Zip’ button will be available in the ribbon to use

Click to Download Source code

Conclusion

This feature is very useful as we do not have default multiple documents download feature in SharePoint which can be archived with this. Happy Coding

August 11, 2013 · Adi · 12 Comments
Tags: , , , , ,  · Posted in: C#, Sharepoint 2007, Sharepoint 2010, SharePoint 2013

12 Responses

  1. Yi - February 11, 2014

    thank you for this blog. I’ve tried it with sharepoint 2013, but it does not work. Is this solution only for sharepoint 2010?

    Thanks and best regards,
    Yi

  2. Adi - February 14, 2014

    Hello Yi,

    I really did not try this in SP 2013 but let me try and get back to you. If any changes, I will post the code and that should help you :)

    Regards,
    Adi

  3. Frank - February 19, 2014

    Hi,

    I deplaoyed the solution and it works great on our SP2010 environment, on subsites as well. But unfortunately only for site admin users :-( What to be done to make simple “members” work with it?

    Regards
    Frank

  4. Adi - February 19, 2014

    Hi Frank,

    If users has permission on the list to view, download should work automatically.
    SPList list = SPContext.Current.Web.GetList(docLibUrl);

    In your case if you are unable to download the data, that means the user has no permission on the list. May be you can try keeping the code in run with elevated permission, but note that with this change if normal users who does not have permission on the list are able to download the data.

    Let me know if you want further help or info.

    Regards,
    Adi

  5. Jonik - March 14, 2014

    Hi,
    I have the same problem as Frank. Have you looked at the problem?

    From the log:
    Unexpected System.NullReferenceException: Object reference not set to an instance of an object…. System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) at System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) at System.Web.UI.Control.OnLoad(EventArgs e) at Microsoft.SharePoint.WebControls.UnsecuredLayoutsPageBase.OnLoad(EventArgs e) at Microsoft.SharePoint.WebControls.LayoutsPageBase.OnLoad(EventArgs e) at System.Web.UI.Control.LoadRecursive() at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsync… 77833015-5825-4f34-a4da-6d79aaa36757
    03/14/2014 09:19:03.43* w3wp.exe (0x0F54) 0x1E40 SharePoint Foundation Runtime tkau Unexpected …Point, Boolean includeStagesAfterAsyncPoint) 77833015-5825-4f34-a4da-6d79aaa36757

  6. Adi - March 15, 2014

    Hi Jonik,

    It is certainly permission issue. Please check my answer to Frank if it resolves your issue.
    Let me know if you are still stuck.

    Regards,
    Adi

  7. Jonik - March 18, 2014

    Hi Adi,

    I’m sure the user has Reading permissions – It’s the same permissions on the Library as on the site…
    Hoped to get it solved without use of elevated permissions :-)

  8. Ignacio - March 26, 2014

    Hello,

    Great code, helped me a lot!

    Thanks and best regards!

    Ignacio

  9. Luke - March 31, 2014

    Hi,

    how do I deploy the solution if it is a source code, not a wsp package.

    I retrieved a wsp file from a source code and attempted deployment but had a :”Unexpected System.NullReferenceException: Object reference not set to an instance of an object…” as Jonik above. Help much appreciated…

  10. Tanuj - April 19, 2014

    hi,

    I want to use the code but ZipFileBuilder is not there.. what to do..

  11. Adi - April 27, 2014

    Hi Tanuj,

    Download the code from http://adicodes.com/download/AdiCodes_DownloadZip.zip

    In the zip file, you will see folder ‘Classes’ which contains the ‘ZipBuilder.cs’ file that has ZipFileBuilder class. May be the class name and file name are different so you got confused :)

    Thanks and Regards,
    Adi

  12. Adi - April 27, 2014

    If you want to deploy without wsp, try copying the dll to GAC in all the Web Front End servers.

    Regards,
    Adi

Leave a Reply

What is 12 + 12 ?
Please leave these two fields as-is:
IMPORTANT! To be able to proceed, you need to solve the following simple math (so we know that you are a human) :-)