Download attachments of selected records of a table as a zip with record number appended

Harika Thota
Tera Expert

Hi,

I have a requirement to append file number to the file name in the zip.

below is code.

 

Any leads are appreciated.

UI Action:

function downloadZip() {

    var selectedAttachments = g_list.getChecked(); // If used in list
    if (!selectedAttachments || selectedAttachments.length === 0) {
        alert("No attachments selected.");
        return;
    }
   
    var ga = new GlideAjax('AttachmentZipAjax');
    ga.addParam('sysparm_name', 'getZippedAttachments');
    ga.addParam('sysparm_attachment_ids', selectedAttachments);
    ga.getXMLAnswer(function(response) {
        var base64Zip = response;
        var blob = b64toBlob(base64Zip, 'application/zip');
        var url = URL.createObjectURL(blob);
        var a = document.createElement('a');
        a.href = url;
        a.download = 'attachments.zip';
        a.click();
        URL.revokeObjectURL(url);
    });
}

// Helper to convert Base64 to Blob
function b64toBlob(b64Data, contentType, sliceSize) {
    contentType = contentType || '';
    sliceSize = sliceSize || 512;

    var byteCharacters = atob(b64Data);
    var byteArrays = [];

    for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
        var slice = byteCharacters.slice(offset, offset + sliceSize);
        var byteNumbers = new Array(slice.length);

        for (var i = 0; i < slice.length; i++) {
            byteNumbers[i] = slice.charCodeAt(i);
        }

        var byteArray = new Uint8Array(byteNumbers);
        byteArrays.push(byteArray);
    }

    return new Blob(byteArrays, {
        type: contentType
    });
}

Script include:

var AttachmentZipAjax = Class.create();
AttachmentZipAjax.prototype = Object.extendsObject(AbstractAjaxProcessor, {

	getZippedAttachments: function () {
        var ids = this.getParameter('sysparm_attachment_ids');
		//gs.log('Harika AttachmentZipAjax'+ ids);
        if (!ids) return '';
        var zipHelper = new AttachmentZipHelper();
        return zipHelper.zipSelectedAttachments(ids);
    },

    type: 'AttachmentZipAjax'
});

Script include 2:

var AttachmentZipHelper = Class.create();
AttachmentZipHelper.prototype = Object.extendsObject(AbstractAjaxProcessor, {

    zipSelectedAttachments: function(attachmentSysIds) {

        var zip = new Packages.java.util.zip.ZipOutputStream(new Packages.java.io.ByteArrayOutputStream());

        var gr = new GlideRecord('sys_attachment');
        gr.addQuery('table_sys_id', 'IN', attachmentSysIds);
        gr.query();

        var byteStream = new Packages.java.io.ByteArrayOutputStream();
        var zipOut = new Packages.java.util.zip.ZipOutputStream(byteStream);

        while (gr.next()) {
    
                var bin = new GlideSysAttachment().getBytes(gr);
			
                var entry = new Packages.java.util.zip.ZipEntry(gr.getValue('file_name'));
			
                zipOut.putNextEntry(entry);
                zipOut.write(bin, 0, bin.length);
                zipOut.closeEntry();
            }
        zipOut.close();
        return GlideStringUtil.base64Encode(byteStream.toByteArray());
			}
    },
    type: 'AttachmentZipHelper'
});

Thanks,

Harika

 

 

1 ACCEPTED SOLUTION

Harika Thota
Tera Expert

Thanks for the response.

 

I got the solution to append the record number to the file name in zip

 

script include

var AttachmentZipHelper = Class.create();
AttachmentZipHelper.prototype = Object.extendsObject(AbstractAjaxProcessor, {

    zipSelectedAttachments: function(attachmentSysIds) {
        //    gs.log('Harika Helper' + attachmentSysIds);
        var zip = new Packages.java.util.zip.ZipOutputStream(new Packages.java.io.ByteArrayOutputStream());

        var gr = new GlideRecord('sys_attachment');
        gr.addQuery('table_sys_id', 'IN', attachmentSysIds);
        gr.query();

        var byteStream = new Packages.java.io.ByteArrayOutputStream();
        var zipOut = new Packages.java.util.zip.ZipOutputStream(byteStream);

        while (gr.next()) {
            // gs.log('Harika Helper21');
            var gr1 = new GlideRecord('u_wealth_management_task');
             gr1.addQuery('sys_id', gr.table_sys_id);
             gr1.query();
             if (gr1.next()) {
            // Optional: prepend record number
            
                //fileName = gr.getValue('file_name') + '_' + gr1.number;
				fileName =  gr1.number + '_' + gr.getValue('file_name');
        
            var bin = new GlideSysAttachment().getBytes(gr);
            var entry = new Packages.java.util.zip.ZipEntry(fileName);
           // gs.log('Harika Helper21 ' + entry);
            zipOut.putNextEntry(entry);
            zipOut.write(bin, 0, bin.length);
            zipOut.closeEntry();
        }
	}
        zipOut.close();
        return GlideStringUtil.base64Encode(byteStream.toByteArray());

    },
    type: 'AttachmentZipHelper'
});

View solution in original post

9 REPLIES 9

dougmoto
Tera Contributor

Try modifying the zipSelectedAttachments function:

 

var i = 1;

 while (gr.next()) {
    
                var bin = new GlideSysAttachment().getBytes(gr);
			
                var entry = new Packages.java.util.zip.ZipEntry(gr.getValue('file_name') + "_" + i.toString());
			
                zipOut.putNextEntry(entry);
                zipOut.write(bin, 0, bin.length);
                zipOut.closeEntry();

                i++;
            }

 

folusho
Tera Guru

HI, can you explain what you mean by "file number"? Also what error are you getting?

Hi,

I wanted to append record number to file name because we have duplicate filenames and it gives me an error.

HarikaThota_1-1746625355859.png

I wanted to add to the highlighted part.

This is the error I got when I tried to add record number to it:

HarikaThota_2-1746625452199.png

Thanks,

Harika

 

 

 

 

Ankur Bawiskar
Tera Patron
Tera Patron

@Harika Thota 

I assume you are able to generate a zip file, how is it looking now?

the zip file generated has what name?

what's your requirement actually?

If my response helped please mark it correct and close the thread so that it benefits future readers.

Regards,
Ankur
Certified Technical Architect  ||  9x ServiceNow MVP  ||  ServiceNow Community Leader