Hello Everyone, In this tutorial, I am going provide a working example of creating a zip file using visualforce and apex that helps you to create a zip file of attachment object. In this example, I am using some resource that I provided to download and upload in your salesforce org. to accomplish this tutorial.
After completing this tutorial, you’ll able to:
- Create a zip file of attachment object.
So let's begin,
Resource: Download
To implement this example follow give steps,
Step 1: Download resource and upload as a Static Resource (Your Name>Setup>Static Resource> New) called ZipResource in your Salesforce Org.
Step 2: Open Developer Console, Go to File>New>Apex Class and create an Apex controller called ZipHandler. Replace the following code.
public class ZipHandler { public Integer randomInt{get;set;} //Constructor public ZipHandler(){ randomInt = getRandomNumber(10000); } @RemoteAction public static List<AttachmentWrapper> getAttachments(String sAttachmentIdCSV){ List<String> attachmentIds = sAttachmentIdCSV.split(','); return wrapAttachments([SELECT Id,Name,Body FROM Attachment WHERE Id IN:attachmentIds]); } private static List<AttachmentWrapper> wrapAttachments(List<Attachment> attachments){ List<AttachmentWrapper> wrappers = new List<AttachmentWrapper>(); for(Attachment att : attachments){ wrappers.add(new AttachmentWrapper(att)); } return wrappers; } public class AttachmentWrapper{ public Attachment AttachmentObj; public String base64Body; public AttachmentWrapper(Attachment AttachmentObj){ this.AttachmentObj = AttachmentObj; this.base64Body = EncodingUtil.base64Encode(AttachmentObj.Body); this.AttachmentObj.Body = NULL; } } /* *Random number generator to change the js function name if multiple components used */ private Integer getRandomNumber(Integer size){ Double d = Math.random() * size; return d.intValue(); } }Step 3: Open Developer Console, Go to File>New>Visualforce Component and create a new Visualforce Component called VFZipComponent and replace the following markup in the Visualforce Component.
<apex:component controller="ZipHandler" selfClosing="true"> <apex:attribute name="attachmentIds" type="String" required="true" description="Comma seperated ID of attachment to zip"/> <apex:attribute name="mode" type="String" default="auto" description="Set 'auto' for opening zip window as soon as component is visible,Set 'button' to render a button that will trigger the zip window"/> <apex:attribute name="generatedFileName" type="String" description="Generated zip file name" required="true"/> <apex:includeScript value="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"/> <apex:includeScript value="https://ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"/> <apex:includeScript value="{!URLFOR($Resource.ZipResource, '/jquery.reveal.js')}"/> <apex:includeScript value="{!URLFOR($Resource.ZipResource,'/jszip.js')}"/> <apex:stylesheet value="{!URLFOR($Resource.ZipResource, '/reveal.css')}"/> <style> .statusMessage{ padding:4px; font-weight:bold; font-size:14px; } </style> <script> $(function () { if("{!LOWER(mode)}" != 'button'){ initZip{!randomInt}(); } }); function initZip{!randomInt}(){ $Status{!randomInt} = $("#Status{!randomInt}Message"); $Status{!randomInt}.html('Preparing files for download'); fetchAttachments{!randomInt}(zipAttachments{!randomInt}); $('#myModal').reveal(); } function zipAttachments{!randomInt}(attachments){ $Status{!randomInt} = $("#Status{!randomInt}Message"); $Status{!randomInt}.html('Creating Zip..'); var zip = new JSZip(); $.each(attachments,function(){ zip.file(this.AttachmentObj.Name, this.base64Body, {base64: true}); }); var blobLink = document.getElementById('FileLink{!randomInt}'); try { blobLink.download = "{!generatedFileName}.zip"; blobLink.href = window.URL.createObjectURL(zip.generate({type:"blob"})); } catch(e) { blobLink.innerHTML += " (not supported on this browser)"; console.log(e); } $("#FileLinkDiv{!randomInt}").show(); $("#Status{!randomInt}").hide(); } function fetchAttachments{!randomInt}(callback){ Visualforce.remoting.Manager.invokeAction( '{!$RemoteAction.ZipHandler.getAttachments}','{!attachmentIds}', function(result, event){ if (event.status) { callback(result,event); } }, { buffer: false, escape: true, timeout: 120000 } ); } </script> <apex:outputPanel rendered="{!LOWER(mode) == 'button'}"> <button onclick="initZip{!randomInt}();return false;">Download Files</button> </apex:outputPanel> <div id="myModal" class="reveal-modal"> <center> <h1 style="font-size:18px"> <img src="/img/icon/box32.png" style="vertical-align: bottom"/> Download Files </h1> </center> <br/> <p> <div> <div id="Status{!randomInt}"> <center><apex:image value="/img/loading32.gif"/></center> <center><div id="Status{!randomInt}Message" class="statusMessage"/></center> </div> <div> <br/> <div id="FileLinkDiv{!randomInt}" style="display:none"> <center> <a href="#" id="FileLink{!randomInt}">Click here to download your file</a> </center> </div> </div> </div> </p> <a class="close-reveal-modal">×</a> </div> </apex:component>Step 4: Open Developer Console, Go to File>New>Visualforce Page and create a new Visualforce Page called VFZipAttachment and replace the following markup.
<apex:page showHeader="false" sidebar="false"> <br/> <apex:pageBlock title="Create zip of Attachment files"> <center> <c:VFZipComponent attachmentIds="00P2800000DXTifEAH,00P2800000EVZAgEAP" generatedFileName="MyZip" mode="button"/> </center> </apex:pageBlock> </apex:page>Output:
Parameters
- attachmentIds : Required and accepted comma-separated IDs of attachment to zipping
- generatedFileName : Required and accepted String value to set file name of generated zip.
- mode : Defines the launch mode. If set to "button" the component will display a button to launch the zip window. If set to "auto" the component will launch the zip window as soon as a Visualforce page is opened.
Features
- Can zip multiple files.
- Can zip upto 5mb.
- You can provide your own name for the generated zip files.
See also
- Get IP Address in Visualforce Page
- Set PDF filename in Visualforce Page
- Remote Action in Visualforce Page
Conclusion:
Hope you like this tutorial, for any query or suggestions please feel free to comment.
Thank you.
9 Comments
When I click the button, the files are not downloading. In the apex class, the body is declared to NULL..is that the problem?
ReplyDeleteI think you missed something, I have tried this without any issue.
DeleteIt happens exactly the same. Could you solve it?
DeleteIt can not work in ie 11 :(
ReplyDeleteJust add the body to the query for attachments. That worked for me.
ReplyDeleteHi,
ReplyDeleteThis maybe a silly question, just wondering if this also compressed the file being zipped? I've tried this and is working fine but seems liked it's not compressing the files.
how to create lightning component on these to download the zip file from VF page using component
ReplyDeleteI am getting initZip method not defined. What I am missing? My code is exactly the same.
ReplyDeleteI personally wants you to try File ZIPO once. As it helps you to ZIP files directly from your Salesforce org eliminating the need to follow the tedious standard process. Try it now!
ReplyDeletehttps://filezipo.io/zip-files/
Post a Comment