zoukankan      html  css  js  c++  java
  • 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。篇中如果有写的错误的地方欢迎指出,如果有疑问地方欢迎留言,转载请注明出处。

  • 相关阅读:
    有一个实体类,只想返还一部分字段给前端
    Dozer-对象属性映射工具类
    java冒泡排序
    总结Java中的reference类型与四种引用类型
    关于jar包的两种导包方式
    Java Web项目的创建——IDEA+Maven+Tomcat
    关于maven的配置过程
    MYSQL数据库的增删改以及查
    关于linux系统下,出现ERROR 1366 (HY000): Incorrect string value: 'xE6xB4xBBxE5x8AxA8...' for column 'deptN的问题解决方法
    Java Script
  • 原文地址:https://www.cnblogs.com/zero-zyq/p/5507940.html
Copyright © 2011-2022 走看看