In a previous post How to download multiple files in ASP.NET, I explained how to generate multiple documents and offer them as separate downloads in ASP.NET. One of the options I had when looking for a solution to offer multiple downloads, was adding all the documents to 1 single zip archive container, and offer that as download to the user. This solution didn’t completely satisfy the end-users, but is also offered for those who want to use it.

In this post I will explain, how I take the same list of documents, and offer them as a zip archive to download. Starting from the multiple download solution, this only required 1 extra step in the process, namely, creating a zip archive and adding all the documents to it. The rest of the process is as described in the previous post.

The method takes the same argument as when creating separate download links, namely an a list of byte arrays. Each byte array in its turn contains the binary content of the document. I use the SharpZipLib from ICSharpCode, which can be downloaded here: The Zip, GZip, BZip2 and Tar Implementation For .NET. This is what this method looks like:


Private Function ZipDocuments(ByVal reports As IList(Of byte())) As Boolean

' Add documents to 1 ZIP file, and open in browser
Using zipOutMemoryStream As New MemoryStream()
Using zipOutStream As New ZipOutputStream(zipOutMemoryStream)

'Add documents to Zip File.
Dim cnt As Integer = 1
For Each buffer As byte() In reports
Dim entry As New ZipEntry(String.Format("{0}_{1}.pdf", "GeneratedFile", cnt))

zipOutStream.PutNextEntry(entry)
zipOutStream.Write(buffer, 0, buffer.Length)
zipOutStream.CloseEntry()
cnt += 1
Next

zipOutStream.Finish()
zipOutStream.Close()
zipOutMemoryStream.Close()

Dim responseBytes As Byte() = zipOutMemoryStream.ToArray()

'Return Null on Empty Zip File
Const ZIP_FILE_EMPTY As Integer = 22
If responseBytes.Length <= ZIP_FILE_EMPTY Then
Return Nothing
End If

RegisterDocumentDownload(Guid.NewGuid().ToString(), responseBytes, ContentTypes.ZIP)

End Using
End Using
End Function

I first create a (binary) memorystream (zipOutMemoryStream) to contain the content of the zip file (zipOutStream).
Then I loop over the list of documents (or files), create an entry in the zip file (entry as ZipEntry), and write the binary content to the zip entry.
After adding the files to the zip and cleaning up, I can use the same RegisterDocumentDownload() method from the previous post, and the zip archive will be added to the user and opened in the browser.

And that’s it…