2

We are working with SharePoint 2013.

Is it possible in a Document Library in the List view to download several (selected) files at once?

I did not find a corresponding button or control in the Ribbon or in the context menu.

The normal use case would be to retain the filenames and select only one target directory, where all the files are saved. Maybe this could be done with a workflow?

6 Answers 6

5

I think the best option is using the Open with Windows Explorer, you can copy multiple documents.

Another option is, Using the 3rd party add-on, Download Multiple Documents. it is free.

Lastly, you can use the PowerShell script to download multiple files.check this

0
1

Why not Sync your document library to Windows explorer.

When you then need to access any documents they will be there on your system already and still have connectivity to SharePoint.

Go to your document library and click the sync button

Sync Library

4
  • I don't see those buttons Upload and Sync next to the New button in our Document Libraries. Is this a feature which has to be activated in SP 2013?
    – mBBe
    Commented Mar 18, 2016 at 13:07
  • Are you using the Online version or On Premise? Commented Mar 18, 2016 at 16:18
  • we have our own "private" SharePoint Server
    – mBBe
    Commented Mar 21, 2016 at 9:21
  • hi mBBe, what James is asking, whether you are using on-premises of sp 2013 or sharepoint online- which is cloud version of SP. upload n sync new symbols/icons were NOT available in SP 2013 ON-PREMISE version. its introduced in SP 2016 on-premises version ONLY. so i think, you are using on-premises version of SP 2013 and not cloud[office 265]
    – samolpp2
    Commented Mar 21, 2016 at 11:03
1

James' sync solution applies in Online when there's availability for OneDrive sync but in on-prem you can use the "Open with Explorer" from tool ribbon Open with Explorer in ribbon

1
  • You can use OneDrive sync also onprem Commented Mar 18, 2016 at 12:46
1

You can use JQuery to achive this.

JSZip helps you to zip multiple files and then can be downloaded to your machine

_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 JQuery 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>

https://joeldsouzasite.wordpress.com/2015/12/06/download-selected-files-as-zip-file-using-javascript/

2
  • So do I save these to files as .js files and save them in my team site then reference them in the script editor web part? Commented Aug 18, 2016 at 19:21
  • Sure, you can do that, its best that you put it in a master page, that's what is module is for, so it can apply to all the pages having list views Commented Aug 27, 2016 at 13:37
0

(function (global, factory) { if (typeof define === "function" && define.amd) { define([], factory); } else if (typeof exports !== "undefined") { factory(); } else { var mod = { exports: {} }; factory(); global.FileSaver = mod.exports; } })(this, function () { "use strict";

/*
* FileSaver.js
* A saveAs() FileSaver implementation.
*
* By Eli Grey, http://eligrey.com
*
* License : https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md (MIT)
* source  : http://purl.eligrey.com/github/FileSaver.js
*/
// The one and only way of getting global scope in all environments
// https://stackoverflow.com/q/3277182/1008999
var _global = typeof window === 'object' && window.window === window ? window : typeof self === 'object' && self.self === self ? self : typeof global === 'object' && global.global === global ? global : void 0;

function bom(blob, opts) {
    if (typeof opts === 'undefined') opts = {
        autoBom: false
    }; else if (typeof opts !== 'object') {
        console.warn('Deprecated: Expected third argument to be a object');
        opts = {
            autoBom: !opts
        };
    } // prepend BOM for UTF-8 XML and text/* types (including HTML)
    // note: your browser will automatically convert UTF-16 U+FEFF to EF BB BF

    if (opts.autoBom && /^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)) {
        return new Blob([String.fromCharCode(0xFEFF), blob], {
            type: blob.type
        });
    }

    return blob;
}

function download(url, name, opts) {
    var xhr = new XMLHttpRequest();
    xhr.open('GET', url);
    xhr.responseType = 'blob';

    xhr.onload = function () {
        saveAs(xhr.response, name, opts);
    };

    xhr.onerror = function () {
        console.error('could not download file');
    };

    xhr.send();
}

function corsEnabled(url) {
    var xhr = new XMLHttpRequest(); // use sync to avoid popup blocker

    xhr.open('HEAD', url, false);

    try {
        xhr.send();
    } catch (e) { }

    return xhr.status >= 200 && xhr.status <= 299;
} // `a.click()` doesn't work for all browsers (#465)


function click(node) {
    try {
        node.dispatchEvent(new MouseEvent('click'));
    } catch (e) {
        var evt = document.createEvent('MouseEvents');
        evt.initMouseEvent('click', true, true, window, 0, 0, 0, 80, 20, false, false, false, false, 0, null);
        node.dispatchEvent(evt);
    }
}

var saveAs = _global.saveAs || ( // probably in some web worker
typeof window !== 'object' || window !== _global ? function saveAs() { }
/* noop */
// Use download attribute first if possible (#193 Lumia mobile)
: 'download' in HTMLAnchorElement.prototype ? function saveAs(blob, name, opts) {
    var URL = _global.URL || _global.webkitURL;
    var a = document.createElement('a');
    name = name || blob.name || 'download';
    a.download = name;
    a.rel = 'noopener'; // tabnabbing
    // TODO: detect chrome extensions & packaged apps
    // a.target = '_blank'

    if (typeof blob === 'string') {
        // Support regular links
        a.href = blob;

        if (a.origin !== location.origin) {
            corsEnabled(a.href) ? download(blob, name, opts) : click(a, a.target = '_blank');
        } else {
            click(a);
        }
    } else {
        // Support blobs
        a.href = URL.createObjectURL(blob);
        setTimeout(function () {
            URL.revokeObjectURL(a.href);
        }, 4E4); // 40s

        setTimeout(function () {
            click(a);
        }, 0);
    }
} // Use msSaveOrOpenBlob as a second approach
: 'msSaveOrOpenBlob' in navigator ? function saveAs(blob, name, opts) {
    name = name || blob.name || 'download';

    if (typeof blob === 'string') {
        if (corsEnabled(blob)) {
            download(blob, name, opts);
        } else {
            var a = document.createElement('a');
            a.href = blob;
            a.target = '_blank';
            setTimeout(function () {
                click(a);
            });
        }
    } else {
        navigator.msSaveOrOpenBlob(bom(blob, opts), name);
    }
} // Fallback to using FileReader and a popup
: function saveAs(blob, name, opts, popup) {
    // Open a popup immediately do go around popup blocker
    // Mostly only available on user interaction and the fileReader is async so...
    popup = popup || open('', '_blank');

    if (popup) {
        popup.document.title = popup.document.body.innerText = 'downloading...';
    }

    if (typeof blob === 'string') return download(blob, name, opts);
    var force = blob.type === 'application/octet-stream';

    var isSafari = /constructor/i.test(_global.HTMLElement) || _global.safari;

    var isChromeIOS = /CriOS\/[\d]+/.test(navigator.userAgent);

    if ((isChromeIOS || force && isSafari) && typeof FileReader !== 'undefined') {
        // Safari doesn't allow downloading of blob URLs
        var reader = new FileReader();

        reader.onloadend = function () {
            var url = reader.result;
            url = isChromeIOS ? url : url.replace(/^data:[^;]*;/, 'data:attachment/file;');
            if (popup) popup.location.href = url; else location = url;
            popup = null; // reverse-tabnabbing #460
        };

        reader.readAsDataURL(blob);
    } else {
        var URL = _global.URL || _global.webkitURL;
        var url = URL.createObjectURL(blob);
        if (popup) popup.location = url; else location.href = url;
        popup = null; // reverse-tabnabbing #460

        setTimeout(function () {
            URL.revokeObjectURL(url);
        }, 4E4); // 40s
    }
});
_global.saveAs = saveAs.saveAs = saveAs;

if (typeof module !== 'undefined') {
    module.exports = saveAs;
}

});

var JSZipUtils = {}; // just use the responseText with xhr1, response with xhr2. // The transformation doesn't throw away high-order byte (with responseText) // because JSZip handles that case. If not used with JSZip, you may need to // do it, see https://developer.mozilla.org/En/Using_XMLHttpRequest#Handling_binary_data

JSZipUtils._getBinaryFromXHR = function (xhr) { // for xhr.responseText, the 0xFF mask is applied by JSZip return xhr.response || xhr.responseText; };

// taken from jQuery function createStandardXHR() { try { return new window.XMLHttpRequest(); } catch (e) { } }

function createActiveXHR() { try { return new window.ActiveXObject("Microsoft.XMLHTTP"); } catch (e) { } }

// Create the request object var createXHR = window.ActiveXObject ? /* Microsoft failed to properly * implement the XMLHttpRequest in IE7 (can't request local files), * so we use the ActiveXObject when it is available * Additionally XMLHttpRequest can be disabled in IE7/IE8 so * we need a fallback. */ function () { return createStandardXHR() || createActiveXHR(); } : // For all other browsers, use the standard XMLHttpRequest object createStandardXHR;

JSZipUtils.getBinaryContent = function (path, callback, progress) { /* * Here is the tricky part : getting the data. * In firefox/chrome/opera/... setting the mimeType to 'text/plain; charset=x-user-defined' * is enough, the result is in the standard xhr.responseText. * cf https://developer.mozilla.org/En/XMLHttpRequest/Using_XMLHttpRequest#Receiving_binary_data_in_older_browsers * In IE <= 9, we must use (the IE only) attribute responseBody * (for binary data, its content is different from responseText). * In IE 10, the 'charset=x-user-defined' trick doesn't work, only the * responseType will work : * http://msdn.microsoft.com/en-us/library/ie/hh673569%28v=vs.85%29.aspx#Binary_Object_upload_and_download * * I'd like to use jQuery to avoid this XHR madness, but it doesn't support * the responseType attribute : http://bugs.jquery.com/ticket/11461 */ try {

    var xhr = createXHR();

    xhr.open('GET', path, true);

    // recent browsers
    if ("responseType" in xhr) {
        xhr.responseType = "arraybuffer";
    }

    // older browser
    if (xhr.overrideMimeType) {
        xhr.overrideMimeType("text/plain; charset=x-user-defined");
    }

    xhr.onreadystatechange = function (evt) {
        var file, err;
        // use `xhr` and not `this`... thanks IE
        if (xhr.readyState === 4) {
            if (xhr.status === 200 || xhr.status === 0) {
                file = null;
                err = null;
                try {
                    file = JSZipUtils._getBinaryFromXHR(xhr);
                }
                catch (e) {
                    err = new Error(e);
                }
                callback(err, file);
            }
            else {
                callback(new Error("Ajax error for " + path + " : " + this.status + " " + this.statusText), null);
            }
        }
    };
    if (progress) xhr.onprogress = progress;
    xhr.send();


    return xhr;

}
catch (e) {
    callback(new Error(e), null);
}

};

function compressed_img(urls, filename) { var zip = new JSZip(); var count = 0; var name = filename + ".zip"; urls.forEach(function (url, i) {

    JSZipUtils.getBinaryContent(url, function (err, data) {
        if (err) {
            throw err;
        }
       
        var fname = url.substr(url.lastIndexOf('/') + 1); //"file_" + i + ".docx";

        zip.file(fname, data, {
            binary: true
        });
        count++;
        if (count == urls.length) {
            zip.generateAsync({
                type: 'blob'
            }).then(function (content) {
                saveAs(content, name);
            });
        }
    }, function (e) {
        p[e.target.responseURL] = e;
        var total = 0, prog = 0;
        for (prop in p) {
            total += p[prop].total;
            prog += p[prop].loaded;
        }
        console.log(prog / total);
        p.value = prog / total;
    });
});

}

var p = {};

//_spBodyOnLoadFunctionNames.push("AddZipIcon" ); function AddZipIcon() { // for SP online $(".ms-qcb-root ul li:nth-child(3)" ).each(function () { $(this).first().before('' + '<a 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" accesskey=" z" onclick=" ConvertToZip()" >Zip') }); } function CheckDownloadZip() { return true; } function ConvertToZip() { var seldocs = GetSelectedItemsDocsURLs(); if(seldocs != null) { var dialog = SP.UI.ModalDialog.showWaitScreenWithNoClose('Creating Zip with selected files', 'Please wait while the files are added to zip...');

// alert("packaging.."); DownloadPackage(seldocs); dialog.close(0); }

} function GetSelectedItemsDocsURLs() { var tempurls = []; var items = SP.ListOperation.Selection.getSelectedItems(ctx); if (items.length== 0) { alert("Please select an item from the list" ); return null; } else { for (var i in items) { var getFileName = _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists('" + SP.ListOperation.Selection.getSelectedList()+ "')/items(" + items[i].id + ")/?$select=EncodedAbsUrl" ; $.ajax({ url: getFileName, type: "GET" , headers: { "accept" : "application/json;odata=verbose" }, success: function (listData) { tempurls.push(listData.d.EncodedAbsUrl); // filename = fileURL.substr(fileURL.lastIndexOf('/') + 1); }, error: function (error) { console.log(JSON.stringify(error)) }, async: false });

} } return tempurls; } function DownloadPackage(urls) { var filename = "selecteddocs"; //The function is called compressed_img(urls, filename);

}

0

the above exactly will not work we need to give as below

the above exactly will not work we need to give as below and call the Function from Custom Action Either from Sp designer Custom Ribbon Action or from Visual studio Custom Action like

javascript:ConvertToZip();
(function (global, factory) {
    if (typeof define === "function" && define.amd) {
        define([], factory);
    } else if (typeof exports !== "undefined") {
        factory();
    } else {
        var mod = {
            exports: {}
        };
        factory();
        global.FileSaver = mod.exports;
    }
})(this, function () {
    "use strict";

    /*
    * FileSaver.js
    * A saveAs() FileSaver implementation.
    *
    * By Eli Grey, http://eligrey.com
    *
    * License : https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md (MIT)
    * source  : http://purl.eligrey.com/github/FileSaver.js
    */
    // The one and only way of getting global scope in all environments
    // https://stackoverflow.com/q/3277182/1008999
    var _global = typeof window === 'object' && window.window === window ? window : typeof self === 'object' && self.self === self ? self : typeof global === 'object' && global.global === global ? global : void 0;

    function bom(blob, opts) {
        if (typeof opts === 'undefined') opts = {
            autoBom: false
        }; else if (typeof opts !== 'object') {
            console.warn('Deprecated: Expected third argument to be a object');
            opts = {
                autoBom: !opts
            };
        } // prepend BOM for UTF-8 XML and text/* types (including HTML)
        // note: your browser will automatically convert UTF-16 U+FEFF to EF BB BF

        if (opts.autoBom && /^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)) {
            return new Blob([String.fromCharCode(0xFEFF), blob], {
                type: blob.type
            });
        }

        return blob;
    }

    function download(url, name, opts) {
        var xhr = new XMLHttpRequest();
        xhr.open('GET', url);
        xhr.responseType = 'blob';

        xhr.onload = function () {
            saveAs(xhr.response, name, opts);
        };

        xhr.onerror = function () {
            console.error('could not download file');
        };

        xhr.send();
    }

    function corsEnabled(url) {
        var xhr = new XMLHttpRequest(); // use sync to avoid popup blocker

        xhr.open('HEAD', url, false);

        try {
            xhr.send();
        } catch (e) { }

        return xhr.status >= 200 && xhr.status <= 299;
    } // `a.click()` doesn't work for all browsers (#465)


    function click(node) {
        try {
            node.dispatchEvent(new MouseEvent('click'));
        } catch (e) {
            var evt = document.createEvent('MouseEvents');
            evt.initMouseEvent('click', true, true, window, 0, 0, 0, 80, 20, false, false, false, false, 0, null);
            node.dispatchEvent(evt);
        }
    }

    var saveAs = _global.saveAs || ( // probably in some web worker
    typeof window !== 'object' || window !== _global ? function saveAs() { }
    /* noop */
    // Use download attribute first if possible (#193 Lumia mobile)
    : 'download' in HTMLAnchorElement.prototype ? function saveAs(blob, name, opts) {
        var URL = _global.URL || _global.webkitURL;
        var a = document.createElement('a');
        name = name || blob.name || 'download';
        a.download = name;
        a.rel = 'noopener'; // tabnabbing
        // TODO: detect chrome extensions & packaged apps
        // a.target = '_blank'

        if (typeof blob === 'string') {
            // Support regular links
            a.href = blob;

            if (a.origin !== location.origin) {
                corsEnabled(a.href) ? download(blob, name, opts) : click(a, a.target = '_blank');
            } else {
                click(a);
            }
        } else {
            // Support blobs
            a.href = URL.createObjectURL(blob);
            setTimeout(function () {
                URL.revokeObjectURL(a.href);
            }, 4E4); // 40s

            setTimeout(function () {
                click(a);
            }, 0);
        }
    } // Use msSaveOrOpenBlob as a second approach
    : 'msSaveOrOpenBlob' in navigator ? function saveAs(blob, name, opts) {
        name = name || blob.name || 'download';

        if (typeof blob === 'string') {
            if (corsEnabled(blob)) {
                download(blob, name, opts);
            } else {
                var a = document.createElement('a');
                a.href = blob;
                a.target = '_blank';
                setTimeout(function () {
                    click(a);
                });
            }
        } else {
            navigator.msSaveOrOpenBlob(bom(blob, opts), name);
        }
    } // Fallback to using FileReader and a popup
    : function saveAs(blob, name, opts, popup) {
        // Open a popup immediately do go around popup blocker
        // Mostly only available on user interaction and the fileReader is async so...
        popup = popup || open('', '_blank');

        if (popup) {
            popup.document.title = popup.document.body.innerText = 'downloading...';
        }

        if (typeof blob === 'string') return download(blob, name, opts);
        var force = blob.type === 'application/octet-stream';

        var isSafari = /constructor/i.test(_global.HTMLElement) || _global.safari;

        var isChromeIOS = /CriOS\/[\d]+/.test(navigator.userAgent);

        if ((isChromeIOS || force && isSafari) && typeof FileReader !== 'undefined') {
            // Safari doesn't allow downloading of blob URLs
            var reader = new FileReader();

            reader.onloadend = function () {
                var url = reader.result;
                url = isChromeIOS ? url : url.replace(/^data:[^;]*;/, 'data:attachment/file;');
                if (popup) popup.location.href = url; else location = url;
                popup = null; // reverse-tabnabbing #460
            };

            reader.readAsDataURL(blob);
        } else {
            var URL = _global.URL || _global.webkitURL;
            var url = URL.createObjectURL(blob);
            if (popup) popup.location = url; else location.href = url;
            popup = null; // reverse-tabnabbing #460

            setTimeout(function () {
                URL.revokeObjectURL(url);
            }, 4E4); // 40s
        }
    });
    _global.saveAs = saveAs.saveAs = saveAs;

    if (typeof module !== 'undefined') {
        module.exports = saveAs;
    }
});

var JSZipUtils = {};
// just use the responseText with xhr1, response with xhr2.
// The transformation doesn't throw away high-order byte (with responseText)
// because JSZip handles that case. If not used with JSZip, you may need to
// do it, see https://developer.mozilla.org/En/Using_XMLHttpRequest#Handling_binary_data

JSZipUtils._getBinaryFromXHR = function (xhr) {
    // for xhr.responseText, the 0xFF mask is applied by JSZip
    return xhr.response || xhr.responseText;
};

// taken from jQuery
function createStandardXHR() {
    try {
        return new window.XMLHttpRequest();
    }
    catch (e) { }
}

function createActiveXHR() {
    try {
        return new window.ActiveXObject("Microsoft.XMLHTTP");
    }
    catch (e) { }
}

// Create the request object
var createXHR = window.ActiveXObject ?
    /* Microsoft failed to properly
     * implement the XMLHttpRequest in IE7 (can't request local files),
     * so we use the ActiveXObject when it is available
     * Additionally XMLHttpRequest can be disabled in IE7/IE8 so
     * we need a fallback.
     */
    function () {
        return createStandardXHR() || createActiveXHR();
    } :
    // For all other browsers, use the standard XMLHttpRequest object
    createStandardXHR;



JSZipUtils.getBinaryContent = function (path, callback, progress) {
    /*
     * Here is the tricky part : getting the data.
     * In firefox/chrome/opera/... setting the mimeType to 'text/plain; charset=x-user-defined'
     * is enough, the result is in the standard xhr.responseText.
     * cf https://developer.mozilla.org/En/XMLHttpRequest/Using_XMLHttpRequest#Receiving_binary_data_in_older_browsers
     * In IE <= 9, we must use (the IE only) attribute responseBody
     * (for binary data, its content is different from responseText).
     * In IE 10, the 'charset=x-user-defined' trick doesn't work, only the
     * responseType will work :
     * http://msdn.microsoft.com/en-us/library/ie/hh673569%28v=vs.85%29.aspx#Binary_Object_upload_and_download
     *
     * I'd like to use jQuery to avoid this XHR madness, but it doesn't support
     * the responseType attribute : http://bugs.jquery.com/ticket/11461
     */
    try {

        var xhr = createXHR();

        xhr.open('GET', path, true);

        // recent browsers
        if ("responseType" in xhr) {
            xhr.responseType = "arraybuffer";
        }

        // older browser
        if (xhr.overrideMimeType) {
            xhr.overrideMimeType("text/plain; charset=x-user-defined");
        }

        xhr.onreadystatechange = function (evt) {
            var file, err;
            // use `xhr` and not `this`... thanks IE
            if (xhr.readyState === 4) {
                if (xhr.status === 200 || xhr.status === 0) {
                    file = null;
                    err = null;
                    try {
                        file = JSZipUtils._getBinaryFromXHR(xhr);
                    }
                    catch (e) {
                        err = new Error(e);
                    }
                    callback(err, file);
                }
                else {
                    callback(new Error("Ajax error for " + path + " : " + this.status + " " + this.statusText), null);
                }
            }
        };
        if (progress) xhr.onprogress = progress;
        xhr.send();


        return xhr;

    }
    catch (e) {
        callback(new Error(e), null);
    }
};

function compressed_img(urls, filename) {
    var zip = new JSZip();
    var count = 0;
    var name = filename + ".zip";
    urls.forEach(function (url, i) {

        JSZipUtils.getBinaryContent(url, function (err, data) {
            if (err) {
                throw err;
            }
           
            var fname = url.substr(url.lastIndexOf('/') + 1); //"file_" + i + ".docx";

            zip.file(fname, data, {
                binary: true
            });
            count++;
            if (count == urls.length) {
                zip.generateAsync({
                    type: 'blob'
                }).then(function (content) {
                    saveAs(content, name);
                });
            }
        }, function (e) {
            p[e.target.responseURL] = e;
            var total = 0, prog = 0;
            for (prop in p) {
                total += p[prop].total;
                prog += p[prop].loaded;
            }
            console.log(prog / total);
            p.value = prog / total;
        });
    });
}

var p = {};


//_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" >' +
'<a 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" 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="https://" /></span><span class=" ms-qcb-glyph ">Zip</span></a></li>')
});
}
function CheckDownloadZip()
{
    return true;
}
function ConvertToZip()
{
 var seldocs = GetSelectedItemsDocsURLs();
 if(seldocs != null)
 {
 var dialog = SP.UI.ModalDialog.showWaitScreenWithNoClose('Creating Zip with selected files', 'Please wait while the files are added to zip...');

// alert("packaging..");
 DownloadPackage(seldocs);
 dialog.close(0);
 }
 
}
function GetSelectedItemsDocsURLs()
{
var tempurls = [];
var items = SP.ListOperation.Selection.getSelectedItems(ctx);
if (items.length== 0) {
alert("Please select an item from the list" );
return null;
}
else
{
for (var i in items)
{
var getFileName = _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists('"  + SP.ListOperation.Selection.getSelectedList()+ "')/items("  + items[i].id + ")/?$select=EncodedAbsUrl" ;
$.ajax({
url: getFileName,
type: "GET" ,
headers: {
"accept" : "application/json;odata=verbose"
},
success: function (listData) {
tempurls.push(listData.d.EncodedAbsUrl);
// filename = fileURL.substr(fileURL.lastIndexOf('/') + 1);
},
error: function (error) {
console.log(JSON.stringify(error))
},
async: false
});

}
}
 return tempurls;
}
function DownloadPackage(urls)
{
var filename = "selecteddocs";
//The function is called
compressed_img(urls, filename);

}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.