1821349743@qq.com
2023-04-08 0d63f52d84e393204af3ba5bce86bdfddf936be8
src/main/java/com/product/server/report/service/GroupReportService.java
@@ -10,6 +10,7 @@
import com.product.core.service.support.AbstractBaseService;
import com.product.core.spring.context.SpringMVCContextHolder;
import com.product.server.report.config.CmnConst;
import com.product.server.report.entity.ReportColumn;
import com.product.util.BaseUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -30,6 +31,55 @@
    /**
     * 报表-解析
    *
    * @param recordDte       业务数据dte
    * @param totalName       总计名称
    * @param reportConfigMap 报表配置缓存map
    * @param tableStyle
    * @return 获取分组报表的详情
    */
   public JSONObject getReportEntity(DataTableEntity recordDte, String totalName, Map<Integer, List<JSONObject>> reportConfigMap, StringBuilder tableStyle) {
      StringBuilder reportHtml = new StringBuilder(4096);
      // css
//        StringBuilder cssHtml = dataListReportService.getCssHtml();
      // 分组表头区和数据区
      StringBuilder groupAndDataAreaHtml = new StringBuilder(1024);
      Map<String, Set<String>> headAndTailTitleDataMap = Maps.newHashMap();
      int totalColCount = reportConfigMap.get(0).size();
      int dataAreaColCount = getGroupAndDataAreaHtmlAndReturnDataAreaColCount(groupAndDataAreaHtml, reportConfigMap, headAndTailTitleDataMap, recordDte, totalName);
      totalColCount = Math.max(totalColCount, dataAreaColCount);
      // 头部标题区
      StringBuilder headTitleHtml = null;
      if (!reportConfigMap.get(1).isEmpty()) {
         headTitleHtml = dataListReportService.getTitleHtml(reportConfigMap.get(1), totalColCount, headAndTailTitleDataMap, "head");
      }
      // 底部标题区
      StringBuilder tailTitleHtml = null;
      if (!reportConfigMap.get(3).isEmpty()) {
         tailTitleHtml = dataListReportService.getTitleHtml(reportConfigMap.get(3), totalColCount, headAndTailTitleDataMap, "tail");
      }
//        reportHtml.append("\n<body>\n<table").append(tableStyle).append(">")
//                .append(cssHtml)
//                .append(headTitleHtml == null ? "" : headTitleHtml)
//                .append(groupAndDataAreaHtml)
//                .append(tailTitleHtml == null ? "" : tailTitleHtml)
//                .append("\n</table>\n</body>");
      JSONObject resultObj = new JSONObject();
      resultObj.put(CmnConst.RETURN_ATTR_RESULT, true);
      resultObj.put(CmnConst.RETURN_ATTR_MESSAGE, "获取报表成功!");
      resultObj.put(CmnConst.RETURN_ATTR_HTML, reportHtml);
      return resultObj;
   }
   /**
    * 报表-解析
    *
     * @param recordDte             业务数据dte
     * @param totalName             总计名称
     * @param reportConfigMap       报表配置缓存map
@@ -77,6 +127,7 @@
    /**
     * 报表-解析-放入分组表头区和数据Html,返回列数
    *
     * @param groupAndDataAreaHtml          html容器
     * @param reportConfigMap               报表缓存数据map
     * @param headAndTailTitleDataMap       头部、尾部标题区数据字段map容器
@@ -184,7 +235,117 @@
    }
    /**
    * 报表-解析-放入分组表头区和数据,返回列数
    *
    * @param groupAndDataArea        容器
    * @param reportConfigMap         报表缓存数据map
    * @param headAndTailTitleDataMap 头部、尾部标题区数据字段map容器
    * @param recordDte               数据源集合
    * @param totalName               总计名称
    * @return 数据区总列数
    */
   private int getGroupAndDataAreaAndReturnDataAreaColCount(List<List<ReportColumn>> groupAndDataArea, Map<Integer, List<JSONObject>> reportConfigMap, Map<String, Set<String>> headAndTailTitleDataMap, DataTableEntity recordDte, String totalName) {
      // 分组表头区字段缓存map
      Map<String, JSONObject> groupAreaFieldConfigMap = dataListReportService.groupAndDataJSONObject2Map(reportConfigMap.get(2));
      // 数据区字段缓存map
      Map<String, JSONObject> dataAreaFieldConfigMap = dataListReportService.groupAndDataJSONObject2Map(reportConfigMap.get(0));
      // 分组表头区分组统计字段名称list
      List<String> groupAreaGroupStatisticsFieldNameList = Lists.newArrayList();
      // 分组表头区分组字段名称list
      List<String> groupAreaGroupFieldNameList = Lists.newArrayList();
      // 分组表头区区域范围obj
      JSONObject groupAreaRangeObj = new JSONObject();
      groupAreaFieldConfigMap.forEach((fieldName, fieldConfigObj) -> {
         groupAreaGroupFieldNameList.add(fieldName);
         if ("1".equals(fieldConfigObj.getString(CmnConst.ATTR_IS_STATISTICS))) {
            groupAreaGroupStatisticsFieldNameList.add(fieldName);
         }
         if (groupAreaRangeObj.getIntValue(CmnConst.MIN_X) == 0) {
            groupAreaRangeObj.put(CmnConst.MIN_X, fieldConfigObj.getIntValue(CmnConst.ATTR_X));
         } else {
            groupAreaRangeObj.put(CmnConst.MIN_X, Math.min(groupAreaRangeObj.getIntValue(CmnConst.MIN_X), fieldConfigObj.getIntValue(CmnConst.ATTR_X)));
         }
         groupAreaRangeObj.put(CmnConst.MAX_X, Math.max(groupAreaRangeObj.getIntValue(CmnConst.MAX_X), fieldConfigObj.getIntValue(CmnConst.ATTR_X) + Math.max(1, fieldConfigObj.getIntValue(CmnConst.ATTR_COLSPAN)) - 1));
         groupAreaRangeObj.put(CmnConst.MAX_Y, Math.max(groupAreaRangeObj.getIntValue(CmnConst.MAX_Y), fieldConfigObj.getIntValue(CmnConst.ATTR_Y) + Math.max(1, fieldConfigObj.getIntValue(CmnConst.ATTR_ROWSPAN)) - 1));
      });
      // 数据区分组统计字段名称list
      List<String> dataAreaGroupStatisticsFieldNameList = Lists.newArrayList();
      // 数据区分组字段名称list
      List<String> dataAreaGroupFieldNameList = Lists.newArrayList();
      // 数据区特殊统计字段名称list-分组表头区下统计字段
      List<String> dataAreaSpStatisticsFieldNameList = Lists.newArrayList();
      // 数据区普通统计字段名称list-非数据区分组字段,非分组表头区下统计字段
      List<String> dataAreaCommonStatisticsFieldNameList = Lists.newArrayList();
      dataAreaFieldConfigMap.forEach((fieldName, fieldConfigObj) -> {
         if ("1".equals(fieldConfigObj.getString(CmnConst.ATTR_IS_GROUP))) {
            dataAreaGroupFieldNameList.add(fieldName);
            if ("1".equals(fieldConfigObj.getString(CmnConst.ATTR_IS_STATISTICS))) {
               dataAreaGroupStatisticsFieldNameList.add(fieldName);
            }
         } else {
            if (fieldConfigObj.getIntValue(CmnConst.ATTR_X) < groupAreaRangeObj.getIntValue(CmnConst.MIN_X) || fieldConfigObj.getIntValue(CmnConst.ATTR_X) > groupAreaRangeObj.getIntValue(CmnConst.MAX_X)) {
               dataAreaCommonStatisticsFieldNameList.add(fieldName);
            } else {
               dataAreaSpStatisticsFieldNameList.add(fieldName);
            }
         }
      });
      // 获取分组表头统计字段对应的数据区字段map
      Map<String, List<String>> groupAreaStatisticsField2DataAreaFieldMap = getGroupAreaStatisticsField2DataAreaFieldMap(groupAreaFieldConfigMap, dataAreaFieldConfigMap);
      // 获取分组表头区末行分组字段对应数据区字段map
      Map<String, List<String>> groupAreaLastStageField2DataAreaFieldMap = getGroupAreaLastStageField2DataAreaFieldMap(groupAreaFieldConfigMap, dataAreaFieldConfigMap, groupAreaRangeObj);
      // 获取指定数据集中包含的数据区字段集合
      Set<String> headAndTailFieldSet = Sets.newHashSet();
      headAndTailFieldSet.addAll(dataListReportService.getDataFields(reportConfigMap.get(1)));
      headAndTailFieldSet.addAll(dataListReportService.getDataFields(reportConfigMap.get(3)));
      // 统计map
      Map<JSONObject, JSONObject> statisticsMap = Maps.newLinkedHashMap();
      // 分组表头区数据obj
      JSONObject groupAreaFieldRecordObj = new JSONObject(Maps.newTreeMap((o1, o2) -> dataListReportService.compare(o1, o2)));
      // 数据区分组字段obj
      JSONObject dataAreaFieldRecordObj = new JSONObject(Maps.newLinkedHashMap());
      FieldSetEntity recordFse;
      for (int i = 0; i < recordDte.getRows(); i++) {
         recordFse = recordDte.getFieldSetEntity(i);
         // 获取头部、尾部标题区数据字段
         dataListReportService.getHeadAndTailTitleDataMap(headAndTailTitleDataMap, headAndTailFieldSet, recordFse);
         // 获取分组表头区数据obj
         getGroupAreaFieldRecordObj(groupAreaFieldRecordObj, groupAreaFieldConfigMap, recordFse, groupAreaStatisticsField2DataAreaFieldMap, groupAreaLastStageField2DataAreaFieldMap);
         // 获取数据区分组字段obj
         getDataAreaGroupFieldRecordObj(dataAreaFieldRecordObj, dataAreaFieldConfigMap, recordFse);
         // 获取数据区特殊字段的统计
         statisticsDataAreaSpField(statisticsMap, dataAreaFieldConfigMap, dataAreaSpStatisticsFieldNameList, recordFse);
         // 获取数据区普通字段的统计
         statisticsDataAreaCommonField(statisticsMap, dataAreaFieldConfigMap, dataAreaCommonStatisticsFieldNameList, recordFse);
      }
      // 获取分组表头区和数据区总列数
      int totalColCount = getTotalColCount(groupAreaFieldRecordObj, dataAreaGroupFieldNameList.size(), dataAreaCommonStatisticsFieldNameList.size());
      // 数据标题list
      List<JSONObject> dataTitleList = Lists.newArrayList();
      // 获取标题html
      groupAndDataArea.addAll(getDataAreaTitle(dataTitleList, groupAreaFieldRecordObj, dataAreaFieldConfigMap, groupAreaRangeObj, dataAreaCommonStatisticsFieldNameList));
      // 获取内容html
//      groupAndDataAreaHtml.append(getDataAreaDataHtml(dataTitleList, dataAreaFieldRecordObj, statisticsMap, totalName, dataAreaGroupFieldNameList, dataAreaFieldConfigMap));
      return totalColCount;
   }
   /**
     * 获取分组表头统计字段对应的数据区字段map
    *
     * @param groupAreaFieldConfigMap       分组表头区字段缓存map
     * @param dataAreaFieldConfigMap        数据区字段缓存map
     * @return                              分组表头统计字段对应的数据区字段map
@@ -212,6 +373,7 @@
    /**
     * 获取分组表头区末行分组字段对应数据区字段map
    *
     * @param groupAreaFieldConfigMap       分组表头区字段缓存map
     * @param dataAreaFieldConfigMap        数据区字段缓存map
     * @param groupAreaRangeObj             分组表头区范围obj
@@ -241,6 +403,7 @@
    /**
     * 获取标题-分组表头区数据obj
    *
     * @param groupAreaFieldRecordObj                       分组表头区字段记录obj
     * @param groupAreaFieldConfigMap                       分组表头区字段缓存map
     * @param recordFse                                     业务数据记录
@@ -304,6 +467,7 @@
    /**
     * 获取数据区分组字段obj
    *
     * @param dataAreaFieldRecordObj    数据区字段记录obj
     * @param dataAreaFieldConfigMap    数据区字段缓存map
     * @param recordFse                 业务数据记录
@@ -362,6 +526,7 @@
    /**
     * 获取数据区特殊字段的统计
    *
     * @param statisticsMap                         统计map
     * @param dataAreaFieldConfigMap                数据区字段缓存map
     * @param dataAreaSpStatisticsFieldNameList     数据区特殊统计字段名称list(分组表头区下统计字段)
@@ -409,6 +574,7 @@
    /**
     * 取数据区普通字段的统计
    *
     * @param statisticsMap                             统计map
     * @param dataAreaFieldConfigMap                    数据区字段缓存map
     * @param dataAreaCommonStatisticsFieldNameList     数据区普通统计字段名称list
@@ -447,6 +613,7 @@
    /**
     * 获取分组表头区和数据区总列数
    *
     * @param groupAreaFieldRecordObj               分组表头区字段记录obj
     * @param dataAreaGroupFieldCount               数据区分组字段个数
     * @param dataAreaCommonStatisticsFieldCount    数据区普通统计字段个数
@@ -459,6 +626,7 @@
    /**
     * 获取分组表头区总列数
    *
     * @param curOperateObj         当前操作的obj
     * @param groupAreaColCount     分组表头区列数
     * @return                      分组表头区总列数
@@ -488,7 +656,96 @@
    }
    /**
    * 获取标题
    *
    * @param dataTitleList                         数据标题list
    * @param groupAreaFieldRecordObj               分组表头区字段记录obj
    * @param dataAreaFieldConfigMap                数据区字段缓存map
    * @param groupAreaRangeObj                     分组表头去范围obj
    * @param dataAreaCommonStatisticsFieldNameList 数据区普通统计字段名称list
    * @return 数据标题html
    */
   private List<List<ReportColumn>> getDataAreaTitle(List<JSONObject> dataTitleList, JSONObject groupAreaFieldRecordObj, Map<String, JSONObject> dataAreaFieldConfigMap, JSONObject groupAreaRangeObj, List<String> dataAreaCommonStatisticsFieldNameList) {
      int maxRow = groupAreaRangeObj.getIntValue(CmnConst.MAX_Y);
      List<List<JSONObject>> groupAreaRangeTitleList = Lists.newArrayList();
      for (int i = 0; i <= maxRow; i++) {
         groupAreaRangeTitleList.add(Lists.newArrayList());
      }
      getGroupAreaRangeTitleList(dataAreaFieldConfigMap, groupAreaFieldRecordObj, groupAreaRangeTitleList, new JSONObject(), 0, maxRow, null);
      List<JSONObject> beforeGroupAreaTitleList = Lists.newArrayList();
      List<JSONObject> afterGroupAreaTitleList = Lists.newArrayList();
      String dataAreaFieldName;
      JSONObject dataAreaFieldConfigObj;
      JSONObject titleObj;
      for (Map.Entry<String, JSONObject> entry : dataAreaFieldConfigMap.entrySet()) {
         dataAreaFieldName = entry.getKey();
         dataAreaFieldConfigObj = entry.getValue();
         titleObj = new JSONObject();
//            titleObj.put(CmnConst.ATTR_FIELD_INFO, getFieldInfo(dataAreaFieldConfigObj));
         titleObj.put(CmnConst.ATTR_FIELD_INFO, dataListReportService.fieldName2FieldInfo(dataAreaFieldName));
         if (dataAreaCommonStatisticsFieldNameList.contains(dataAreaFieldName)) {
            titleObj.put(CmnConst.ATTR_SHOW_NAME, dataListReportService.getStatisticsDesc(dataAreaFieldConfigObj.getString(CmnConst.ATTR_STATISTICS), dataAreaFieldConfigObj.getString(CmnConst.ATTR_SHOW_NAME)));
         } else {
            titleObj.put(CmnConst.ATTR_SHOW_NAME, dataAreaFieldConfigObj.getString(CmnConst.ATTR_SHOW_NAME));
         }
         titleObj.put(CmnConst.ATTR_ROWSPAN, maxRow + 1);
         titleObj.put(CmnConst.ATTR_COLSPAN, 1);
         if (dataAreaFieldConfigObj.getIntValue(CmnConst.ATTR_X) < groupAreaRangeObj.getIntValue(CmnConst.MIN_X)) {
            beforeGroupAreaTitleList.add(titleObj);
         }
         if (dataAreaFieldConfigObj.getIntValue(CmnConst.ATTR_X) > groupAreaRangeObj.getIntValue(CmnConst.MAX_X)) {
            if ("1".equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_IS_GROUP))) {
               beforeGroupAreaTitleList.add(titleObj);
            } else {
               afterGroupAreaTitleList.add(titleObj);
            }
         }
      }
      dataTitleList.addAll(groupAreaRangeTitleList.get(maxRow));
      dataTitleList.addAll(afterGroupAreaTitleList);
      List<JSONObject> firstList = Lists.newArrayList();
      firstList.addAll(beforeGroupAreaTitleList);
      firstList.addAll(groupAreaRangeTitleList.get(0));
      firstList.addAll(afterGroupAreaTitleList);
      groupAreaRangeTitleList.set(0, firstList);
//      StringBuilder html = new StringBuilder(1024);
      int rowspan;
      int colspan;
      String value;
      List<List<ReportColumn>> rowColumn = new ArrayList<>();
      for (List<JSONObject> rowList : groupAreaRangeTitleList) {
         List<ReportColumn> columns = new ArrayList<>();
//         html.append("\n<tr class=\"").append(CmnConst.CLASS_TR_DATA_TITLE).append("\">\n    ");
         for (JSONObject dataTitleObj : rowList) {
            rowspan = Math.max(1, dataTitleObj.getIntValue(CmnConst.ATTR_ROWSPAN));
            colspan = Math.max(1, dataTitleObj.getIntValue(CmnConst.ATTR_COLSPAN));
            value = dataTitleObj.getString(CmnConst.ATTR_SHOW_NAME);
            if (!StringUtils.isEmpty(dataTitleObj.getString(CmnConst.ATTR_FIELD_INFO))) {
               dataAreaFieldName = dataListReportService.fieldInfo2FieldName(dataTitleObj.getString(CmnConst.ATTR_FIELD_INFO));
               value = dataListReportService.dealTdWidth(dataAreaFieldConfigMap.get(dataAreaFieldName), value);
            }
            ReportColumn column = new ReportColumn();
            column.setRowspan(rowspan);
            column.setColspan(colspan);
            column.setContent(value);
            columns.add(column);
//            html.append("<td rowspan=\"").append(rowspan).append("\" colspan=\"").append(colspan).append("\">").append(value == null ? "" : value).append("</td>");
         }
         rowColumn.add(columns);
//         html.append("\n</tr>");
      }
      return rowColumn;
   }
   /**
     * 获取标题html
    *
     * @param dataTitleList                             数据标题list
     * @param groupAreaFieldRecordObj                   分组表头区字段记录obj
     * @param dataAreaFieldConfigMap                    数据区字段缓存map
@@ -568,6 +825,7 @@
    /**
     * 获取分组表头区范围的标题list
    *
     * @param dataAreaFieldConfigMap        数据区字段缓存map
     * @param curOperateObj                 当前操作obj
     * @param groupAreaRangeTitleList       分组表头区范围下数据标题list
@@ -641,6 +899,7 @@
    /**
     * 获取下级分组项数
    *
     * @param obj       待操作的obj
     * @return          下级分组项数
     */
@@ -658,6 +917,7 @@
    /**
     * 获取内容html
    *
     * @param dataTitleList                 数据标题list
     * @param dataAreaFieldRecordObj        数据区字段记录obj
     * @param statisticsMap                 统计map
@@ -773,7 +1033,125 @@
    }
    /**
    * 获取内容html
    *
    * @param dataTitleList              数据标题list
    * @param dataAreaFieldRecordObj     数据区字段记录obj
    * @param statisticsMap              统计map
    * @param totalName                  总计名称,非空-需要总计
    * @param dataAreaGroupFieldNameList 数据区分组字段名称list
    * @param dataAreaFieldConfigMap     数据区字段缓存map
    * @return 业务数据内容html
    */
   private List<List<ReportColumn>> getDataAreaData(List<JSONObject> dataTitleList, JSONObject dataAreaFieldRecordObj, Map<JSONObject, JSONObject> statisticsMap, String totalName, List<String> dataAreaGroupFieldNameList, Map<String, JSONObject> dataAreaFieldConfigMap) {
      List<List<JSONObject>> dataAreaGroupFieldDataList = Lists.newArrayList();
      getDataAreaGroupFieldDataList(dataAreaFieldRecordObj, dataAreaGroupFieldDataList, new JSONObject(), 1, 1, dataAreaGroupFieldNameList.size(), null);
      List<JSONObject> groupTitleList = Lists.newArrayList();
      JSONObject obj;
      for (List<JSONObject> rowList : dataAreaGroupFieldDataList) {
         obj = dataListReportService.extendJSONObject(null, rowList.get(rowList.size() - 1), Arrays.asList(CmnConst.ATTR_ROWSPAN, CmnConst.ATTR_COLSPAN, CmnConst.ATTR_SHOW_NAME, CmnConst.ATTR_IS_STATISTICS_FIELD), -1);
         groupTitleList.add(obj);
      }
      StringBuilder html = new StringBuilder(1024);
      JSONObject dataAreaGroupFieldObj;
      int rowspan;
      int colspan;
      String value;
      JSONObject groupTitleObj;
      JSONObject keyObj;
      JSONObject valueObj;
      String statisticsType;
      JSONObject dataAreaFieldConfigObj;
      int groupAreaSubCnt;
      int dataAreaSubCnt;
      List<JSONObject> curRowList;
      int index;
      for (int i = 0; i < dataAreaGroupFieldDataList.size(); i++) {
         index = 0;
         curRowList = dataAreaGroupFieldDataList.get(i);
         if (!curRowList.isEmpty()) {
            for (int j = 0; j < curRowList.size(); j++) {
               dataAreaGroupFieldObj = curRowList.get(j);
               if (dataAreaGroupFieldObj.isEmpty()) {
                  continue;
               }
               if (index == 0) {
                  if ("1".equals(dataAreaGroupFieldObj.getString(CmnConst.ATTR_IS_STATISTICS_FIELD))) {
                     html.append("\n<tr class=\"").append(CmnConst.CLASS_TR_DATA_STATISTICS).append("\">\n    ");
                  } else {
                     html.append("\n<tr class=\"").append(CmnConst.CLASS_TR_DATA_COMMON).append("\">\n    ");
                  }
               }
               rowspan = Math.max(1, dataAreaGroupFieldObj.getIntValue(CmnConst.ATTR_ROWSPAN));
               colspan = Math.max(1, dataAreaGroupFieldObj.getIntValue(CmnConst.ATTR_COLSPAN));
               value = dataAreaGroupFieldObj.getString(CmnConst.ATTR_SHOW_NAME);
               html.append("<td rowspan=\"").append(rowspan).append("\" colspan=\"").append(colspan).append("\">").append(value == null ? "" : value).append("</td>");
               index++;
            }
         } else {
            html.append("\n<tr class=\"").append(CmnConst.CLASS_TR_DATA_COMMON).append("\">\n    ");
         }
         groupTitleObj = groupTitleList.get(i);
         for (JSONObject dataTitleObj : dataTitleList) {
            keyObj = dataListReportService.extendJSONObject((JSONObject) groupTitleObj.clone(), dataTitleObj, Arrays.asList(CmnConst.ATTR_ROWSPAN, CmnConst.ATTR_COLSPAN, CmnConst.ATTR_SHOW_NAME, CmnConst.ATTR_IS_STATISTICS_FIELD, CmnConst.ATTR_REAL_VALUE), -1);
            dataAreaFieldConfigObj = dataAreaFieldConfigMap.get(dataListReportService.fieldInfo2FieldName(dataTitleObj.getString(CmnConst.ATTR_FIELD_INFO)));
            if (dataAreaFieldConfigObj != null) {
               groupAreaSubCnt = keyObj.getIntValue(CmnConst.ATTR_GROUP_AREA_SUB_CNT);
               dataAreaSubCnt = keyObj.getIntValue(CmnConst.ATTR_DATA_AREA_SUB_CNT);
               keyObj.remove(CmnConst.ATTR_GROUP_AREA_SUB_CNT);
               keyObj.remove(CmnConst.ATTR_DATA_AREA_SUB_CNT);
               keyObj.remove(CmnConst.ATTR_REAL_VALUE);
               statisticsType = dataAreaFieldConfigObj.getString(CmnConst.ATTR_STATISTICS);
               valueObj = statisticsMap.get(keyObj);
               if (valueObj == null || valueObj.isEmpty()) {
                  value = getFinalValue(keyObj, dataAreaFieldConfigObj, statisticsMap);
               } else {
                  if (CmnConst.ATTR_STATISTICS_AVG.equals(statisticsType) && "1".equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_AVG_TYPE))) {
                     if (dataAreaSubCnt == 0 && groupAreaSubCnt == 0) {
                        value = valueObj.getString(statisticsType);
                     } else {
                        value = getTwoTypesGroupAvgStatisticsValue(dataAreaSubCnt, groupAreaSubCnt, valueObj, dataAreaFieldConfigObj, statisticsType);
                     }
                  } else {
                     value = valueObj.getString(statisticsType);
                  }
                  valueObj.put(CmnConst.ATTR_FINAL_VALUE, value);
               }
            } else {
               value = "";
            }
            html.append("<td");
            if (!StringUtils.isEmpty(value)) {
               // class
               if (!StringUtils.isEmpty(dataAreaFieldConfigObj.getString(CmnConst.ATTR_URL))) {
                  dataListReportService.extendJSONObject(keyObj, dataAreaFieldConfigObj, Collections.singletonList(CmnConst.ATTR_URL));
                  html.append(" class=\"").append(CmnConst.CLASS_TD_CAN_TURN).append("\"");
               }
               // 字段属性
               dataListReportService.getTdAttrObj(keyObj, groupTitleObj);
               dataListReportService.getTdAttrObj(keyObj, dataTitleObj);
               html.append(dataListReportService.getTdAttrByObj(keyObj));
               // 格式
               value = dataListReportService.formatValue(dataAreaFieldConfigObj, value);
            }
            html.append(">").append(value == null ? "" : value).append("</td>");
         }
         html.append("\n</tr>");
      }
      // 总计
      if (!StringUtils.isEmpty(totalName)) {
         html.append(getTotalStatisticsHtml(statisticsMap, dataTitleList, dataAreaFieldConfigMap, dataAreaGroupFieldNameList.size(), getSubCnt(dataAreaFieldRecordObj), totalName));
      }
      return null;
   }
   /**
     * 获取数据区分组字段数据list
    *
     * @param curOperateObj                 当前操作obj
     * @param dataAreaGroupFieldDataList    数据区分组字段数据list
     * @param preObj                        最近操作的obj
@@ -873,6 +1251,7 @@
    /**
     * 获取总计html
    *
     * @param statisticsMap             统计map
     * @param dataTitleList             数据标题list
     * @param dataAreaFieldConfigMap    数据区字段缓存map
@@ -935,6 +1314,7 @@
    /**
     * 获取统计方式为“最终统计”的值
    *
     * @param keyObj
     * @param dataAreaFieldConfigObj
     * @param statisticsMap
@@ -968,6 +1348,7 @@
    /**
     * 获取行列两种不同的下级分组平均值
    *
     * @param dataAreaSubCnt            按照数据区分组的下级分组项数
     * @param groupAreaSubCnt           按照分组表头去分组的下级分组项数
     * @param curFieldStatisticsObj     当前字段统计obj
@@ -995,6 +1376,7 @@
    /**
     * 获取指定类型的下级分组平均值
    *
     * @param subCnt                    下级分组项数
     * @param curFieldStatisticsObj     当前字段统计obj
     * @param dataAreaFieldConfigObj    当前数据区字段缓存obj