17 | To add the Export to excel button follow the below setps, below example for 'Account' object
18 |
19 |
Go to Setup –> Accounts –> Buttons, Links and Actions
20 |
Click ‘New Button or Link'
21 |
Enter Label, Name and select display type as ‘List Button’
22 |
Content source as “Onclick Javascript” and paste the below code
23 |
24 |
25 | ```
26 | //Getting List Name
27 | var listview = document.getElementsByName('fcf')[0];
28 | var listName = listview.options[listview.selectedIndex].text;
29 | //Getting List Id
30 | var listId = document.getElementsByName("fcf")[0].value;
31 | var ObjectName = 'Account'; //Action : Enter the Object API Name
32 | //Passing ListId,ObjectName and ListName to Visualforce page
33 | window.open("apex/exportStandardListView?Object="+ObjectName+"&listid="+listId+"&listName="+listName,"myWindow");
34 | ```
35 |
36 |
Remote Site settings
37 |
38 |
Go to Setup->Remote Site –> New
39 |
Add the Name and in the URL enter the domain name of your org
40 |
Then click save
41 |
42 |
--------------------------------------------------------------------------------
/src/classes/listviewApiTest.cls:
--------------------------------------------------------------------------------
1 | @isTest
2 | private class listviewApiTest {
3 |
4 | @isTest static void testAllAccountList() {
5 |
6 | List testAccounts = new List();
7 | for(integer i=0; i<100 ; i++){
8 | Account acc = new Account();
9 | acc.Name = 'Test Account'+ i;
10 | testAccounts.add(acc);
11 | }
12 | insert testAccounts;
13 | Test.StartTest();
14 | Test.setMock(HttpCalloutMock.class, new MockHttpResponseGenerator());
15 | PageReference pageRef = Page.exportStandardListView;
16 | Test.setCurrentPage(pageRef);
17 | listviewAPI listviewAPIctrl = new listviewAPI();
18 | pageRef.getParameters().put('listid', 'ert322144');
19 | pageRef.getParameters().put('Object', 'Account');
20 | pageRef.getParameters().put('listName', 'All Account');
21 | listviewAPIctrl.fetchListviewRecords();
22 | Test.StopTest();
23 | system.assertEquals(listviewAPIctrl.fileName,'Account_All_Account_'+Datetime.now().format());
24 | system.assertEquals(listviewAPIctrl.columnName[0],'Account Name');
25 |
26 | }
27 |
28 | @isTest static void testAllAccountList_error() {
29 |
30 | List testAccounts = new List();
31 | for(integer i=0; i<100 ; i++){
32 | Account acc = new Account();
33 | acc.Name = 'Test Account'+ i;
34 | testAccounts.add(acc);
35 | }
36 | insert testAccounts;
37 | Test.StartTest();
38 | Test.setMock(HttpCalloutMock.class, new MockHttpResponseGenerator());
39 | PageReference pageRef = Page.exportStandardListView;
40 | Test.setCurrentPage(pageRef);
41 | listviewAPI listviewAPIctrl = new listviewAPI();
42 | pageRef.getParameters().put('listid', '');
43 | pageRef.getParameters().put('Object', '');
44 | listviewAPIctrl.fetchListviewRecords();
45 | Test.StopTest();
46 | system.assertNotEquals(listviewAPIctrl.fileName,'Account_All_Account_'+Datetime.now().format());
47 |
48 | }
49 | }
--------------------------------------------------------------------------------
/src/classes/listviewAPI.cls:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2014 Karanraj
3 | All rights reserved.
4 | Redistribution and use in source and binary forms, with or without
5 | modification, are permitted provided that the following conditions
6 | are met:
7 | 1. Redistributions of source code must retain the above copyright
8 | notice, this list of conditions and the following disclaimer.
9 | 2. Redistributions in binary form must reproduce the above copyright
10 | notice, this list of conditions and the following disclaimer in the
11 | documentation and/or other materials provided with the distribution.
12 | 3. The name of the author may not be used to endorse or promote products
13 | derived from this software without specific prior written permission.
14 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
15 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 | */
25 |
26 | /**
27 | @Description: Visualforce controller for the page to export the records directly from list view
28 | @Author: Karanraj(@karanrajs)
29 | **/
30 |
31 | public with sharing class listviewAPI {
32 |
33 | public List fields {get;set;}
34 | public List columnName {get;set;}
35 | public List recordList {get;set;}
36 | public List> allRecords {get;set;}
37 | public List parserCol{get;set;}
38 | public String fileName {get;set;}
39 | public List columns;
40 |
41 | public void fetchListviewRecords() {
42 |
43 | columnName = new List();
44 | fields = new List();
45 | parserCol = new List();
46 | recordList = new List();
47 | allRecords = new List>();
48 | try{
49 | String listid = apexpages.currentpage().getparameters().get('listid');
50 | String ObjectName = apexpages.currentpage().getparameters().get('Object');
51 | String listName = apexpages.currentpage().getparameters().get('listName');
52 | fileName = ObjectName +'_'+listName.replace(' ','_') +'_'+ Datetime.now().format();
53 | //Http callout
54 | HttpRequest req = new HttpRequest();
55 | req.setHeader('Authorization', 'Bearer ' + UserInfo.getSessionID());
56 | req.setHeader('Content-Type', 'application/json');
57 | String domainUrl=URL.getSalesforceBaseUrl().toExternalForm();
58 | system.debug('********domainUrl:'+domainUrl);
59 | String endpointUrl = domainUrl+'/services/data/v32.0/sobjects/' +(ObjectName=='Person_Account'?'Account':ObjectName)+'/listviews/'+listid+'/describe';
60 | system.debug('domain URL' + endpointUrl);
61 | req.setEndpoint(endpointUrl);
62 | req.setMethod('GET');
63 | Http h = new Http();
64 | HttpResponse res = h.send(req);
65 | Map root = (Map)JSON.deserializeUntyped(res.getBody());
66 | //Nested list logic to overcome collection limit
67 | for(Sobject sobj : Database.query((string)root.get('query'))){
68 | recordList.add(sobj);
69 | if(recordList.size() == 10000){
70 | allRecords.add(recordList);
71 | recordList = new List();
72 | }
73 | }
74 |
75 | if(recordList != null && !recordList.isEmpty())
76 | allRecords.add(recordList);
77 |
78 | //Parsing JSON string to get the column details
79 | JSONParser parser = JSON.createParser(res.getBody());
80 | while (parser.nextToken() != null){
81 | if(parser.getCurrentToken() == JSONToken.START_ARRAY) {
82 | while (parser.nextToken() != null) {
83 | if(parser.getCurrentToken() == JSONToken.START_OBJECT) {
84 | listviewAPI.Columns le = (listviewAPI.Columns)parser.readValueAs(listviewAPI.Columns.class);
85 | parserCol.add(le);
86 |
87 | }
88 | }
89 | }
90 | }
91 |
92 | for(listviewAPI.Columns lc : parserCol){
93 | if(lc.hidden == false && lc.fieldNameOrPath != Null){
94 | fields.add(lc.fieldNameOrPath);
95 | columnName.add(lc.label);
96 | }
97 | }
98 | }catch(Exception ex){
99 | Apexpages.addMessage(new ApexPages.Message(ApexPages.Severity.INFO,''+'There is some problem occurred, verify object name in the custom button code"'));
100 | }
101 |
102 | }
103 |
104 | public class Columns {
105 |
106 | public String ascendingLabel;
107 | public String descendingLabel;
108 | public String fieldNameOrPath;
109 | public Boolean hidden;
110 | public String label;
111 | public String selectListItem;
112 | public String sortDirection;
113 | public Integer sortIndex;
114 | public Boolean sortable;
115 | public String type;
116 | }
117 | }
--------------------------------------------------------------------------------