Iam really enjoying being here at Knowledge 10 and meeting so many of you who read our posts.  I have been busy in one-on-one sessions hearing requests and helping come up with answers.  One of our readers wanted to know how they would go about downloading all of the attachments on a record as a zip file.  Another reader wanted to know how to send attachments as a zip file via a web service.  I believe this post should help solve both questions.

The challenge we will solve in this post is this: if a record has any attachments, we will add a button to the form that allows you to download all of the attachments as a single ZIP file.

Step 1: Create a UI action on the task table

Name:Save Attachments as ZIP
Condition:

current.hasAttachments();

Script:

action.setRedirectURL('exportAttachmentsToZip.do?sysparm_sys_id=' + current.sys_id + '&sysparm_table=' + current.getTableName());

The only real secret to the above code is the setRedirectURL. This allows us to call a processor in our system that will popup a download dialog to download the zip file. The exportAttachmentsToZip processor does not yet exist in the system and will need to be created. Processors are found under System Definition->Processors.

Step 2: Create an exportAttachmentsToZip processor
Create a new processor. Processors are found under System Definition->Processors.
Name: exportAttachmentsToZip
Type: script
Path: exportAttachmentsToZip
Script:

var sysid = g_request.getParameter('sysparm_sys_id');
var table = g_request.getParameter('sysparm_table');

var theRecord = new GlideRecord(table);
theRecord.addQuery('sys_id', sysid);
theRecord.query();
theRecord.next();

var zipName = 'attachments.zip';

var StringUtil = GlideStringUtil;

var gr = new GlideRecord('sys_attachment');
gr.addQuery('table_sys_id', theRecord.sys_id);
gr.addQuery('table_name', theRecord.getTableName());
gr.query();

if (gr.hasNext()){
    g_response.setHeader('Pragma', 'public');
    g_response.addHeader('Cache-Control', 'max-age=0');
    g_response.setContentType('application/octet-stream');
    g_response.addHeader('Content-Disposition', 'attachment;filename=' + zipName);
    var out = new Packages.java.util.zip.ZipOutputStream(g_response.getOutputStream());
    var count=0;
    while (gr.next()){
        var sa = new GlideSysAttachment();
        var binData = sa.getBytes(gr);
       
        var file = gr.file_name;
        addBytesToZip(out, zipName, file, binData);
        count ++;
    }
    // Complete the ZIP file
    out.close();
}

function addBytesToZip (out, dir, file, stream){
    // Add ZIP entry to output stream.
    out.putNextEntry(new Packages.java.util.zip.ZipEntry(file));
    out.write(stream, 0, stream.length);
    out.closeEntry();
}

That’s all there is to it. The result will appear like the following screen shot.

This code could be slightly tweaked to send the ZIP file as a web service. Remember, though, that if you do this, you will need to base64 encode the binary data before sending it over.