I get a requirement where user needs to download the selected files from the SharePoint Document Library by zipping all of them. This I wanted to tr purely using JavaScript.
After surfing the internet I found this useful tool called as JSZip
And then i implemented the code below:
ConvertToZip.js:
_spBodyOnLoadFunctionNames.push(“AddZipIcon”);
function AddZipIcon() {
// for SP online
$(“.ms-qcb-root ul li:nth-child(3)”).each(function () {
$(this).first().before(‘<li class=”ms-qcb-item”>’ +
‘<button class=”ms-qcb-button ms-qcb-buttons-alignmentfix js-listview-qcbUploadButton js-callout-body js-qcb-button ms-qcb-glyph” type=”button”‘ +
‘title=”Select files and download as a zip file” role=”button” accesskey=”z” onclick=”ConvertToZip()”><span class=”ms-qcb-glyph ms-listview-glyph-withmargin ms-listview-sync-glyph ms-core-form-heading”><img style=”height:20px;width:25px;” src=”‘ + _spPageContextInfo.webServerRelativeUrl + ‘/SiteAssets/ZipDownloader/zip.png”/></span><span class=”ms-qcb-glyph “>Zip</span></button></li>’)
});
}
function ConvertToZip() {
SP.SOD.executeFunc(‘sp.js’, ‘SP.ClientContext’, Convert);
}
function Convert() {
var count = SP.ListOperation.Selection.getSelectedItems(ctx).length;
if (count == 0) {
alert(“Please select an item from the list”);
return false;
}
SP.UI.ModalDialog.showWaitScreenWithNoClose(‘Converting to Zip’, ‘Please wait while the files are added to zip…’);
var zip = new JSZip();
var filename;
var folderName;
var contentType;
var isFolder;
var deferreds = [];
var ctx = SP.ClientContext.get_current();
var items = SP.ListOperation.Selection.getSelectedItems(ctx);
var ctx = GetCurrentCtx();
var title = ctx.ListTitle;
for (var i in items) {
//Get Content Type
var getContentType = _spPageContextInfo.webServerRelativeUrl + “/_api/web/lists/getByTitle(‘” + title + “‘)/items(” + items[i].id + “)/?$select=ContentType/Name&$expand=ContentType”;
$.ajax({
url: getContentType,
type: “GET”,
headers: {
“accept”: “application/json;odata=verbose”
},
success: function (listData) {
contentType = listData.d.ContentType.Name;
},
error: function (error) {
console.log(JSON.stringify(error))
},
async: false
});
//End here
if (contentType != ‘Folder’) { //get file information
isFolder = 0;
var getFileName = _spPageContextInfo.webServerRelativeUrl + “/_api/web/lists/getByTitle(‘” + title + “‘)/items(” + items[i].id + “)/?$select=EncodedAbsUrl”;
$.ajax({
url: getFileName,
type: “GET”,
headers: {
“accept”: “application/json;odata=verbose”
},
success: function (listData) {
fileURL = listData.d.EncodedAbsUrl; //_spPageContextInfo.webServerRelativeUrl+”/”+title+”/”+
filename = fileURL.substr(fileURL.lastIndexOf(‘/’) + 1);
},
error: function (error) {
console.log(JSON.stringify(error))
},
async: false
});
deferreds.push(deferredAddZip(fileURL, filename, zip, isFolder, folderName));
} else { //get folder name
var folderURL;
isFolder = 1;
var getFolderName = _spPageContextInfo.webServerRelativeUrl + “/_api/web/lists/getByTitle(‘” + title + “‘)/items(” + items[i].id + “)/?$select=EncodedAbsUrl”
$.ajax({
url: getFolderName,
type: “GET”,
headers: {
“accept”: “application/json;odata=verbose”
},
success: function (listData) {
folderURL = listData.d.EncodedAbsUrl.replace(/^.*\/\/[^\/]+/, ”);
folderName = listData.d.EncodedAbsUrl.substr(listData.d.EncodedAbsUrl.lastIndexOf(‘/’) + 1);
},
error: function (error) {
console.log(JSON.stringify(error))
},
async: false
});
//get files from folder
var getFilesFromFolder = _spPageContextInfo.webServerRelativeUrl + “/_api/web/GetFolderByServerRelativeUrl(‘” + folderURL + “‘)/Files”;
$.ajax({
url: getFilesFromFolder,
type: “GET”,
headers: {
“accept”: “application/json;odata=verbose”
},
success: function (listData) {
listData.d.results.forEach(function (element) {
fileURL = folderURL + “/” + element.Name;
filename = element.Name;
deferreds.push(deferredAddZip(fileURL, filename, zip, isFolder, folderName));
});
},
error: function (error) {
console.log(JSON.stringify(error))
},
async: false
});
}
}
//save zip file
$.when.apply($, deferreds).done(function () {
var blob = zip.generate({
type: “blob”
});
saveAs(blob, title + “.zip”);
SP.UI.ModalDialog.commonModalDialogClose(SP.UI.DialogResult.cancel);
});
}
//handle binary content and add to zip object
function deferredAddZip(url, filename, zip, isFolder, folderName) {
var deferred = $.Deferred(); //for synchronous calls
JSZipUtils.getBinaryContent(url, function (err, data) {
if (err) {
deferred.reject(err);
} else {
if (isFolder != 1) {
zip.file(filename, data, {
binary: true
});
} else {
zip.folder(folderName).file(filename, data, {
binary: true
});
}
deferred.resolve(data);
}
});
return deferred;
}
It doesn’t end here, you need to add the below Javascript files and an image of the zip file:
I have added a module:
<?xml version=”1.0″ encoding=”utf-8″?>
<Elements xmlns=”http://schemas.microsoft.com/sharepoint/”&gt;
<Module Name=”ZipDownloader” Url=”SiteAssets”>
<File Path=”ZipDownloader\ConvertToZip.js” Url=”ZipDownloader/ConvertToZip.js” /> //code above
<File Path=”ZipDownloader\FileSaver.js” Url=”ZipDownloader/FileSaver.js” />
<File Path=”ZipDownloader\jszip.min.js” Url=”ZipDownloader/jszip.min.js” />
<File Path=”ZipDownloader\jszip-utils.js” Url=”ZipDownloader/jszip-utils.js” />
<File Path=”ZipDownloader\zip.png” Url=”ZipDownloader/zip.png” />
</Module>
<CustomAction Id=”registerJSZIP” Location=”ScriptLink” Sequence=”400″ Scriptsrc=”~site/SiteAssets/ZipDownloader/jszip.min.js”/>
<CustomAction Id=”registerJSZIPUTIL” Location=”ScriptLink” Sequence=”401″ Scriptsrc=”~site/SiteAssets/ZipDownloader/jszip-utils.js”/>
<CustomAction Id=”registerFileSaver” Location=”ScriptLink” Sequence=”402″ Scriptsrc=”~site/SiteAssets/ZipDownloader/FileSaver.js”/>
<CustomAction Id=”registerConvertToZip” Location=”ScriptLink” Sequence=”403″ Scriptsrc=”~site/SiteAssets/ZipDownloader/ConvertToZip.js”/>
</Elements>
230b10_35beefc25cc44f50a773e11dd25dfede
230b10_0990bfc0f5f44417bf8bdd01d34df1d0
230b10_e96da70499d142628ad07be3e10340da