salesforce 零基礎學習(二十三)數據記錄導出至excel(自定義報表導出)


我們都知道,報表有個功能為導出excel,但是有的時候客戶需求往往標准的報表達不到,比如導出excel,其中本月修改的數據字段標紅,如下圖所示。

這就需要我們去寫VF來實現此功能。

需求:將數據表記錄導出成excel,其中excel內容需要本月修改的數據字段自動標紅顯示。

表:Goods__c,字段如下:

 設計思路:如果導出excel並且需要跟蹤每個字段的修改時間進行校驗是否標紅,則需要有一個表取跟蹤這個表.有兩種方式進行Track。

1.salesforce中提供了Track History功能,即當表字段小於20個情況下,可以通過設置Track History,那樣系統會自動創建相關表的History表,在這個demo中系統會自動創建Goods_History表。詳細Track History知識可以參看以下鏈接:

https://help.salesforce.com/apex/HTFederatedSearchResults#q=Track%20History&t=TopResultTab&sort=relevancy&f:@sflanguage=[en_US]

2.當表的字段超過20個,則通過Track History便無法滿足需求了,這種情況我們需要自己創建一個sObject來和需要track的sObject進行關聯,如下圖所示:

 頁面顯示均使用標准生成的頁面,在Goods__c修改情況下,需要設置Trigger自動插入此條Goods__c記錄對應的GoodsSign__c記錄,如果某個字段有修改,則設置某個字段相對應的Date信息為System.today().

制作步驟:

1.寫GoodsTrigger.Trigger代碼如下所示:

 1 trigger GoodsTrigger on Goods__c (before delete, before update) {
 2     if(trigger.isBefore) {
 3         //get the Schema Information of GoodsSign to check whether current user has access to operate the data
 4         Schema.DescribeSObjectResult goodsSignDescribe = GoodsSign__c.sObjectType.getDescribe();
 5         List<GoodsSign__c> goodsSignList = new List<GoodsSign__c>();
 6         //第一個參數為Goods__c的ID,第二個參數為GoodsSign__c
 7         Map<ID,GoodsSign__c> goodsIdToGoodsSignMap = new Map<ID,GoodsSign__c>();
 8         if(trigger.isUpdate) {
 9             Set<ID> goodsIdSet = new Set<ID>();
10             if(goodsSignDescribe.isCreateable() && goodsSignDescribe.isUpdateable()) {
11                 List<Goods__c> goodsNewList = trigger.new;
12                 List<Goods__c> goodsOldList = trigger.old;
13                 for(Goods__c goods : goodsNewList) {
14                     goodsIdSet.add(goods.Id);
15                 }
16                 String fetchGoodsSignByGoodsId = 'SELECT CreatedById, CreatedDate,' +
17                     ' IsDeleted, GoodsBrandDate__c, GoodsCostPriceDate__c,' +
18                     ' GoodsDescribeDate__c, GoodsId__c, GoodsNameDate__c,' +
19                     ' GoodsPriceDate__c, Name, LastModifiedById, LastModifiedDate,' +
20                     ' OwnerId, Id, SystemModstamp FROM GoodsSign__c ' + 
21                     ' where GoodsId__c in :goodsIdSet';
22                 List<GoodsSign__c> tempGoodsSignList = Database.query(fetchGoodsSignByGoodsId);
23                 for(GoodsSign__c goodsSign : tempGoodsSignList) {
24                     goodsIdToGoodsSignMap.put(goodsSign.GoodsId__c,goodsSign);
25                 }
26                 for(Integer i=0;i<goodsNewList.size();i++) {
27                     Goods__c goodsNew = goodsNewList.get(i);
28                     Goods__c goodsOld = goodsOldList.get(i);
29                     GoodsSign__c goodsSign = new GoodsSign__c();
30                     Id goodsId = goodsNew.Id;
31                     if(goodsIdToGoodsSignMap.get(goodsId) != null) {
32                         goodsSign = goodsIdToGoodsSignMap.get(goodsId);
33                     }
34                     
35                     if(goodsNew.GoodsName__c != goodsOld.GoodsName__c) {
36                         goodsSign.GoodsNameDate__c = System.today();
37                     }
38                     if(goodsNew.GoodsPrice__c != goodsOld.GoodsPrice__c) {
39                         goodsSign.GoodsPriceDate__c = System.today();
40                     }
41                     if(goodsNew.GoodsCostPrice__c != goodsOld.GoodsCostPrice__c) {
42                         goodsSign.GoodsCostPriceDate__c = System.today();
43                     }
44                     if(goodsNew.GoodsBrand__c != goodsOld.GoodsBrand__c) {
45                         goodsSign.GoodsBrandDate__c = System.today();
46                     }
47                     if(goodsNew.GoodsDescribe__c != goodsOld.GoodsDescribe__c) {
48                         goodsSign.GoodsDescribeDate__c = System.today();
49                     }
50                     if(goodsSign.GoodsId__c == null) {
51                         goodsSign.GoodsId__c = goodsId;
52                     }
53                     goodsSignList.add(goodsSign);
54                  }
55                  if(goodsSignList.size() > 0) {
56                      upsert goodsSignList;
57                  }
58             }
59             
60         } else if(trigger.isDelete) {
61             //cascade delete 
62             if(goodsSignDescribe.isDeletable()) {
63                 List<Goods__c> goodsList = trigger.old;
64                 Set<ID> goodsIdSet = new Set<ID>();
65                 for(Goods__c currentGoods : goodsList) {
66                     if(!goodsIdSet.contains(currentGoods.Id)) {
67                         goodsIdSet.add(currentGoods.Id);
68                     }
69                 }
70                 String fetchGoodsSignByGoodsIdSet = 'SELECT CreatedById, CreatedDate,' +
71                 ' IsDeleted, GoodsBrandDate__c, GoodsCostPriceDate__c, GoodsDescribeDate__c,' +
72                 ' GoodsId__c, GoodsNameDate__c, GoodsPriceDate__c, Name, LastModifiedById,' +
73                 ' LastModifiedDate, OwnerId, Id, SystemModstamp FROM GoodsSign__c' +
74                 ' where GoodsId__c in :goodsIdSet';
75                 List<GoodsSign__c> goodsSignNeedDeleteList = Database.query(fetchGoodsSignByGoodsIdSet);
76                 delete goodsSignNeedDeleteList;
77             }
78         }
79     } 
80 }

 

此Trigger有兩個功能:

1.當進行修改操作並且Goods__c記錄有字段改變時,如果有相對應的GoodsSign__c進行對應,則update此記錄,否則新建記錄,並記錄哪些字段有修改;

2.當進行刪除操作時,如果有相對應的GoodsSign__c進行對應,則級聯刪除。

兩者操作均需要當前用戶有GoodsSign的操作權限。

2.新建一個類用來記錄導出的字段以及導出的字段的顏色。

 1 public with sharing class GoodsExportObject {
 2     public String goodsName{get;set;}
 3     public String goodsNameColor{get;set;}
 4     public String goodsBrand{get;set;}
 5     public String goodsBrandColor{get;set;}
 6     public String goodsPrice{get;set;}
 7     public String goodsPriceColor{get;set;}
 8     public String goodsCostPrice{get;set;}
 9     public String goodsCostPriceColor{get;set;}
10     public String goodsDescribe{get;set;}
11     public String goodsDescribeColor{get;set;}
12 }

3.新建Controller,此Controller用來獲取顯示到excel的數據。

 1 public with sharing class ExportGoodsController {
 2     
 3     List<Goods__c> goodsList{get;set;}
 4     List<GoodsSign__c> goodsSignList{get;set;}
 5     public List<GoodsExportObject> exportGoodsList{get;set;}
 6     Map<Id,GoodsSign__c> goodsSignMap = new Map<Id,GoodsSign__c>();
 7     public ExportGoodsController() {
 8         goodsList = new List<Goods__c>();
 9         goodsSignList = new List<GoodsSign__c>();
10         exportGoodsList = new List<GoodsExportObject>();
11         String fetchAllGoods = 'SELECT CreatedById, CreatedDate, IsDeleted,' +
12         ' Name, GoodsBrand__c, GoodsCostPrice__c, GoodsDescribe__c, GoodsName__c,' +
13         ' GoodsPrice__c, LastActivityDate, LastModifiedById, LastModifiedDate,' +
14         ' OwnerId, Id, SystemModstamp FROM Goods__c';
15         goodsList = Database.query(fetchAllGoods);
16         String fetchAllGoodsSign = 'SELECT CreatedById, CreatedDate, IsDeleted,' +
17         ' GoodsBrandDate__c, GoodsCostPriceDate__c, GoodsDescribeDate__c,' +
18         ' GoodsId__c, GoodsNameDate__c, GoodsPriceDate__c, Name, LastModifiedById,' +
19         ' LastModifiedDate, OwnerId, Id, SystemModstamp FROM GoodsSign__c';
20         goodsSignList = Database.query(fetchAllGoodsSign);
21         for(GoodsSign__c goodsSign : goodsSignList) {
22             if(!goodsSignMap.containsKey(goodsSign.GoodsId__c)) {
23                 goodsSignMap.put(goodsSign.GoodsId__c,goodsSign);
24             }
25         }
26     }
27     
28     
29     public PageReference exportGoods() {
30         String bgColor = 'red';
31         Integer nowMonth = System.today().month();
32         for(Goods__c currentGoods : goodsList) {
33             GoodsSign__c goodsSign = goodsSignMap.get(currentGoods.Id);
34             GoodsExportObject tempGoodsExportObject = new GoodsExportObject();
35             tempGoodsExportObject.goodsName = currentGoods.GoodsName__c;
36             tempGoodsExportObject.goodsBrand = currentGoods.GoodsBrand__c;
37             tempGoodsExportObject.goodsPrice = String.valueOf(currentGoods.GoodsPrice__c);
38             tempGoodsExportObject.goodsCostPrice = String.valueOf(currentGoods.GoodsCostPrice__c);
39             tempGoodsExportObject.goodsDescribe = currentGoods.GoodsDescribe__c;
40             if(goodsSign != null) {
41                 if(goodsSign.GoodsNameDate__c != null && goodsSign.GoodsNameDate__c.month() == nowMonth) {
42                     tempGoodsExportObject.goodsNameColor = bgColor;
43                 }
44                 if(goodsSign.GoodsBrandDate__c != null && goodsSign.GoodsBrandDate__c.month() == nowMonth) {
45                     tempGoodsExportObject.goodsBrandColor = bgColor;
46                 }
47                 if(goodsSign.GoodsPriceDate__c != null && goodsSign.GoodsPriceDate__c.month() == nowMonth) {
48                     tempGoodsExportObject.goodsPriceColor = bgColor;
49                 }
50                 if(goodsSign.GoodsCostPriceDate__c != null && goodsSign.GoodsCostPriceDate__c.month() == nowMonth) {
51                     tempGoodsExportObject.goodsCostPriceColor = bgColor;
52                 }
53                 if(goodsSign.GoodsDescribeDate__c != null && goodsSign.GoodsDescribeDate__c.month() == nowMonth) {
54                     tempGoodsExportObject.goodsDescribeColor = bgColor;
55                 }
56             }
57             exportGoodsList.add(tempGoodsExportObject);
58         }
59         
60         return new PageReference('/apex/ExportGoodsPage');
61     }
62     
63     
64     
65     
66 }

4.新建顯示的VF頁面

IsExportPage.page:此VF頁面用於顯示一個按鈕,當點擊按鈕后,執行Excel生成操作。

1 <apex:page controller="ExportGoodsController">
2 <apex:form >
3 <apex:commandButton action="{!exportGoods}" value="exportGoods"/>
4 </apex:form>
5 </apex:page>

ExportGoodsPage:生成Excel

 1 <apex:page controller="ExportGoodsController" cache="true" contenttype="application/x-excel# GenExcel.xls" showheader="false">
 2 <head>
 3     <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
 4 </head>
 5 <apex:dataTable value="{!exportGoodsList}" var="exportGoods" border="1">
 6         <apex:column style="background:{!exportGoods.goodsNameColor};">
 7             <apex:facet name="header">Goods Name </apex:facet>
 8             {!exportGoods.goodsName}
 9         </apex:column>
10         <apex:column style="background:{!exportGoods.goodsBrandColor};">
11             <apex:facet name="header">Goods Brand</apex:facet>
12             {!exportGoods.goodsBrand}
13         </apex:column>
14         <apex:column style="background:{!exportGoods.goodsPriceColor};">
15             <apex:facet name="header">Goods Price</apex:facet>
16             {!exportGoods.goodsPrice}
17         </apex:column>
18         <apex:column style="background:{!exportGoods.goodsCostPriceColor};">
19             <apex:facet name="header">Goods Cost Price</apex:facet>
20             {!exportGoods.goodsCostPrice}
21         </apex:column>
22         <apex:column style="background:{!exportGoods.goodsDescribeColor};">
23             <apex:facet name="header">Goods Describe</apex:facet>
24             {!exportGoods.goodsDescribe}
25         </apex:column>
26     </apex:dataTable>
27 </apex:page>

5.配置Button,並顯示到列表頁面上。

結果樣式顯示:

點擊Goods Reports按鈕,跳轉到導出 記錄的按鈕頁面

點擊exportGoods則可以生成Excel。以下為Excel的生成界面,其中紅色為修改的記錄字段。

總結:上述demo只是演示當字段Tracking超過20個需要額外創建表的情況處理,當小於20個情況下可以直接通過History的表進行查詢,有興趣的可以自己嘗試,生成頁面因為使用DataTable,所以對於導出的記錄行數有要求,必須不大於1000條,超過則應該會報Error。篇中如果有寫的錯誤的地方歡迎指出,如果有疑問地方歡迎留言,轉載請注明出處。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM