When salesforce is as easy as telling 1, 2, 3 it is also as tough as cooking Biryani(tough for bachelor's). I found it difficult when I want to download Selected Records PDF(Invoice PDF) from List view of the Object. Hopefully I solved so I thought it would be nice to help others for the same scenario. so,
HOW TO DOWNLOAD PDF'S AS ZIP FILE FROM LIST VIEW OF THE OBJECT
Here am using INVOICE object, api name is Invoice__c.
- First create visualforce page that render as pdf for help refer Create PDF with Salesforce
- (Optional) Add visualforce custom button to detail page of the record for help refer How to add Detail Page Visualforce button.
- Create Apex class that returns a error messages as JSON Format
public class DownloadInvoiceResponse {
//Normal Status Code
private static String API_STATUS_NORMAL = '200';
//Error Status Code
private static String API_STATUS_ERROR = '400';
// Normal JSON Response
public static string normalJson( Object respData ) {
Map<String, Object> response = new Map<String, Object>();
response.put('status', API_STATUS_NORMAL);
if( respData != null )
response.put('data', respData);
return json.serialize( response );
}
// Error JSON Response
Public static String errorJson( String message ) {
Map<String, Object> response = new Map<String, Object>();
response.put('status', API_STATUS_ERROR );
if( message != null )
response.put('error', message);
return json.serialize( response );
}
}
//Normal Status Code
private static String API_STATUS_NORMAL = '200';
//Error Status Code
private static String API_STATUS_ERROR = '400';
// Normal JSON Response
public static string normalJson( Object respData ) {
Map<String, Object> response = new Map<String, Object>();
response.put('status', API_STATUS_NORMAL);
if( respData != null )
response.put('data', respData);
return json.serialize( response );
}
// Error JSON Response
Public static String errorJson( String message ) {
Map<String, Object> response = new Map<String, Object>();
response.put('status', API_STATUS_ERROR );
if( message != null )
response.put('error', message);
return json.serialize( response );
}
}
4. Create a Apex class with WEBSERVICE Method to return List of pdf's as JSON format
global class DownloadInvoice
{
private static String API_STATUS_NORMAL = '200';
webService static string getAttachmentByParentId(string sfdcId)
{
List<id> ids = new List<id>();
if(string.isempty(sfdcId)) {
return DownloadInvoiceResponse.errorJson('Parameter sfdcId is required.');
}
string[] idsArray = sfdcId.split(',');
for(integer i=0; i<idsArray.size();i++)
{
ids.add(idsArray[i]);
}
List<Invoice__c> invList = New List<Invoice__c>();
invList = [Select id, name, Print_Invoice__c,Account__r.name from Invoice__c where ID IN: ids];
List<Attachment> attInsert = new List<Attachment>();
if(invList.size() > 0){
for(Invoice__c invc : invList){
//pdf file
PageReference pdf = new PageReference('/apex/InvoicePDF?id='+invc.id);
Attachment attach = new Attachment();
if (attach == null) attach = new Attachment();
Blob body;
try {
body = pdf.getContentAsPDF();
}
catch (VisualforceException e) {
String msg2 = e.getMessage();
return DownloadInvoiceResponse.errorJson( msg2 );
}
attach.Body = body;
attach.name= invc.name+'.PDF';
attach.IsPrivate = false;
attach.ParentId = invc.id;
attach.contentType = 'application/pdf';
attInsert.add(attach);
}
}
Insert attInsert;
set<String> remainingsIdsSet=new set<String>();
List<attachment> attachmentList = new List<attachment>();
for(attachment att: attInsert) {
String parentId=att.ParentId;
remainingsIdsSet.add(parentId);
}
String remainingIds=null;
List<String> remainingIdList=new List<String>(remainingsIdsSet);
for(integer i=0;i<remainingIdList.size();i++){
if(i==0){
remainingIds=remainingIdList.get(i);
}else{
remainingIds=remainingIds+','+remainingIdList.get(i);
}
}
List<Object> dataList = new List<Object>();
for(Attachment at :attachmentList)
{
Map<String, String> atMap = new Map<String, String>();
atMap.put( 'Name', at.Name );
atMap.put( 'Body', EncodingUtil.base64Encode( at.body ));
datalist.add( atMap );
}
Map<String, Object> response = new Map<String, Object>();
response.put('status', API_STATUS_NORMAL);
if( datalist != null ){
response.put('data',datalist);
response.put('id', remainingIds);
}
return json.serialize( response );
}
{
private static String API_STATUS_NORMAL = '200';
webService static string getAttachmentByParentId(string sfdcId)
{
List<id> ids = new List<id>();
if(string.isempty(sfdcId)) {
return DownloadInvoiceResponse.errorJson('Parameter sfdcId is required.');
}
string[] idsArray = sfdcId.split(',');
for(integer i=0; i<idsArray.size();i++)
{
ids.add(idsArray[i]);
}
List<Invoice__c> invList = New List<Invoice__c>();
invList = [Select id, name, Print_Invoice__c,Account__r.name from Invoice__c where ID IN: ids];
List<Attachment> attInsert = new List<Attachment>();
if(invList.size() > 0){
for(Invoice__c invc : invList){
//pdf file
PageReference pdf = new PageReference('/apex/InvoicePDF?id='+invc.id);
Attachment attach = new Attachment();
if (attach == null) attach = new Attachment();
Blob body;
try {
body = pdf.getContentAsPDF();
}
catch (VisualforceException e) {
String msg2 = e.getMessage();
return DownloadInvoiceResponse.errorJson( msg2 );
}
attach.Body = body;
attach.name= invc.name+'.PDF';
attach.IsPrivate = false;
attach.ParentId = invc.id;
attach.contentType = 'application/pdf';
attInsert.add(attach);
}
}
Insert attInsert;
set<String> remainingsIdsSet=new set<String>();
List<attachment> attachmentList = new List<attachment>();
for(attachment att: attInsert) {
String parentId=att.ParentId;
remainingsIdsSet.add(parentId);
}
String remainingIds=null;
List<String> remainingIdList=new List<String>(remainingsIdsSet);
for(integer i=0;i<remainingIdList.size();i++){
if(i==0){
remainingIds=remainingIdList.get(i);
}else{
remainingIds=remainingIds+','+remainingIdList.get(i);
}
}
List<Object> dataList = new List<Object>();
for(Attachment at :attachmentList)
{
Map<String, String> atMap = new Map<String, String>();
atMap.put( 'Name', at.Name );
atMap.put( 'Body', EncodingUtil.base64Encode( at.body ));
datalist.add( atMap );
}
Map<String, Object> response = new Map<String, Object>();
response.put('status', API_STATUS_NORMAL);
if( datalist != null ){
response.put('data',datalist);
response.put('id', remainingIds);
}
return json.serialize( response );
}
5. Add webservice method to save the file to Document
webService static String saveToDocument( String zipFileData, String fileName ){
try{
String userId = UserInfo.getUserId();
List<Document> docList = [SELECT Id, Name, FolderId, Body FROM Document WHERE Name = :fileName AND FolderId = :userId];
Document doc = new Document();
if( docList == null || docList.size() == 0 ) {
doc.Name = fileName;
doc.FolderId = UserInfo.getUserId();
doc.Body = EncodingUtil.base64Decode( zipFileData );
insert doc;
}
else {
doc = docList.get(0);
doc.Body = EncodingUtil.base64Decode( zipFileData );
update doc;
}
return DownloadInvoiceResponse.normalJson( doc.Id );
} catch ( Exception ex ) {
return DownloadInvoiceResponse.errorJson( ex.getMessage() );
}
}
try{
String userId = UserInfo.getUserId();
List<Document> docList = [SELECT Id, Name, FolderId, Body FROM Document WHERE Name = :fileName AND FolderId = :userId];
Document doc = new Document();
if( docList == null || docList.size() == 0 ) {
doc.Name = fileName;
doc.FolderId = UserInfo.getUserId();
doc.Body = EncodingUtil.base64Decode( zipFileData );
insert doc;
}
else {
doc = docList.get(0);
doc.Body = EncodingUtil.base64Decode( zipFileData );
update doc;
}
return DownloadInvoiceResponse.normalJson( doc.Id );
} catch ( Exception ex ) {
return DownloadInvoiceResponse.errorJson( ex.getMessage() );
}
}
5. Now Goto,
- View fields of the object.
- Scroll down to Custom Buttons, Links and Actions.
- Click on New.
- Create a new List Button.
- Select Onclick Javascrip from DropDown.
- Now Place below Javascript that calls the webservice methods.
{!REQUIRESCRIPT("/resource/jqueryInvoice")}
{!REQUIRESCRIPT("/resource/JSzipfileInvoice")}
{!REQUIRESCRIPT("/soap/ajax/30.0/connection.js")}
{!REQUIRESCRIPT("/soap/ajax/30.0/apex.js")}
var records = {!GetRecordIds($ObjectType.Invoice__c)};
var newRecords = [];
var SelectedIds='';
var fileDatafinal;
for(var i=0;i < records.length; i++)
{
SelectedIds+=records[i]+",";
}
SelectedIds=SelectedIds.substring(0,SelectedIds.length - 1);
if(SelectedIds.length > 0){
alert(' Please wait until end of the process ');
var response = sforce.apex.execute("DownloadInvoice","getAttachmentByParentId", {sfdcId:SelectedIds});
var respObj = JSON.parse(response);
if( respObj['status'] != '200' )
{
alert( respObj['error'] );
}
else
{
var fileData = respObj['data'];
SelectedIds=respObj['id'];
downloadZip(fileData);
}
}
else
{
alert('Please select atleast one record');
}
function downloadZip( fileData) {
var fileName = 'Attachments.zip';
var zip = new JSZip();
for( var k in fileData ) {
zip.file(fileData[k]['Name'], fileData[k]['Body'].toString(),{base64: true});
}
content = zip.generate();
response = sforce.apex.execute("DownloadInvoice","saveToDocument",{zipFileData:content, fileName:fileName});
var fileObj = JSON.parse(response);
if( fileObj['status'] != '200' ) {
alert( fileObj['error'] );
return;
}
var docId = fileObj['data'];
alert('Please confirm to download Zip file');
window.location = '/servlet/servlet.FileDownload?file=' + docId;
try {
for (var n=0; n<records.length; n++){
var sv = new sforce.SObject("Invoice__c");
sv.id = records[n];
newRecords.push(sv);
}
result = sforce.connection.update(newRecords);
}
catch (e) {
alert(e);
}
}
{!REQUIRESCRIPT("/resource/JSzipfileInvoice")}
{!REQUIRESCRIPT("/soap/ajax/30.0/connection.js")}
{!REQUIRESCRIPT("/soap/ajax/30.0/apex.js")}
var records = {!GetRecordIds($ObjectType.Invoice__c)};
var newRecords = [];
var SelectedIds='';
var fileDatafinal;
for(var i=0;i < records.length; i++)
{
SelectedIds+=records[i]+",";
}
SelectedIds=SelectedIds.substring(0,SelectedIds.length - 1);
if(SelectedIds.length > 0){
alert(' Please wait until end of the process ');
var response = sforce.apex.execute("DownloadInvoice","getAttachmentByParentId", {sfdcId:SelectedIds});
var respObj = JSON.parse(response);
if( respObj['status'] != '200' )
{
alert( respObj['error'] );
}
else
{
var fileData = respObj['data'];
SelectedIds=respObj['id'];
downloadZip(fileData);
}
}
else
{
alert('Please select atleast one record');
}
function downloadZip( fileData) {
var fileName = 'Attachments.zip';
var zip = new JSZip();
for( var k in fileData ) {
zip.file(fileData[k]['Name'], fileData[k]['Body'].toString(),{base64: true});
}
content = zip.generate();
response = sforce.apex.execute("DownloadInvoice","saveToDocument",{zipFileData:content, fileName:fileName});
var fileObj = JSON.parse(response);
if( fileObj['status'] != '200' ) {
alert( fileObj['error'] );
return;
}
var docId = fileObj['data'];
alert('Please confirm to download Zip file');
window.location = '/servlet/servlet.FileDownload?file=' + docId;
try {
for (var n=0; n<records.length; n++){
var sv = new sforce.SObject("Invoice__c");
sv.id = records[n];
newRecords.push(sv);
}
result = sforce.connection.update(newRecords);
}
catch (e) {
alert(e);
}
}
That's it Happy Downloading.
You can download the jqueryInvoice and JSzipfileInvoice here. Click On Download
Hope this helps you.
See you next time. Thanks!!.
How many files can be downloaded at a time? Can we face heap size or CPU timeout error if many files?
ReplyDelete