From 0d63f52d84e393204af3ba5bce86bdfddf936be8 Mon Sep 17 00:00:00 2001
From: 1821349743@qq.com <1821349743@qq.com>
Date: 星期六, 08 四月 2023 16:39:25 +0800
Subject: [PATCH] 修改报表加载返回html更改为数据

---
 src/main/java/com/product/server/report/service/GroupReportService.java | 2256 ++++++++++++++++++++++++++++++++++------------------------
 1 files changed, 1,319 insertions(+), 937 deletions(-)

diff --git a/src/main/java/com/product/server/report/service/GroupReportService.java b/src/main/java/com/product/server/report/service/GroupReportService.java
index 93b677d..59fa0b1 100644
--- a/src/main/java/com/product/server/report/service/GroupReportService.java
+++ b/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;
@@ -25,993 +26,1374 @@
  */
 @Component
 public class GroupReportService extends AbstractBaseService {
-    @Autowired
-    private DataListReportService dataListReportService;
+	@Autowired
+	private DataListReportService dataListReportService;
 
-    /**
-     * 鎶ヨ〃-瑙f瀽
-     * @param recordDte             涓氬姟鏁版嵁dte
-     * @param totalName             鎬昏鍚嶇О
-     * @param reportConfigMap       鎶ヨ〃閰嶇疆缂撳瓨map
-     * @param tableStyle
-     * @return                      鑾峰彇鍒嗙粍鎶ヨ〃鐨勮鎯�
-     */
-    public JSONObject getReport(DataTableEntity recordDte, String totalName, Map<Integer, List<JSONObject>> reportConfigMap, StringBuilder tableStyle) {
-        StringBuilder reportHtml = new StringBuilder(4096);
+	/**
+	 * 鎶ヨ〃-瑙f瀽
+	 *
+	 * @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();
+		// 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 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 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");
-        }
+		// 搴曢儴鏍囬鍖�
+		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>");
+//        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;
-    }
+		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;
+	}
 
-    /**
-     * 鎶ヨ〃-瑙f瀽-鏀惧叆鍒嗙粍琛ㄥご鍖哄拰鏁版嵁Html锛岃繑鍥炲垪鏁�
-     * @param groupAndDataAreaHtml          html瀹瑰櫒
-     * @param reportConfigMap               鎶ヨ〃缂撳瓨鏁版嵁map
-     * @param headAndTailTitleDataMap       澶撮儴銆佸熬閮ㄦ爣棰樺尯鏁版嵁瀛楁map瀹瑰櫒
-     * @param recordDte                     鏁版嵁婧愰泦鍚�
-     * @param totalName                     鎬昏鍚嶇О
-     * @return                              鏁版嵁鍖烘�诲垪鏁�
-     */
-    private int getGroupAndDataAreaHtmlAndReturnDataAreaColCount(StringBuilder groupAndDataAreaHtml, Map<Integer, List<JSONObject>> reportConfigMap, Map<String, Set<String>> headAndTailTitleDataMap, DataTableEntity recordDte, String totalName) {
-        // 鍒嗙粍琛ㄥご鍖哄瓧娈电紦瀛榤ap
-        Map<String, JSONObject> groupAreaFieldConfigMap = dataListReportService.groupAndDataJSONObject2Map(reportConfigMap.get(2));
-        // 鏁版嵁鍖哄瓧娈电紦瀛榤ap
-        Map<String, JSONObject> dataAreaFieldConfigMap = dataListReportService.groupAndDataJSONObject2Map(reportConfigMap.get(0));
+	/**
+	 * 鎶ヨ〃-瑙f瀽
+	 *
+	 * @param recordDte       涓氬姟鏁版嵁dte
+	 * @param totalName       鎬昏鍚嶇О
+	 * @param reportConfigMap 鎶ヨ〃閰嶇疆缂撳瓨map
+	 * @param tableStyle
+	 * @return 鑾峰彇鍒嗙粍鎶ヨ〃鐨勮鎯�
+	 */
+	public JSONObject getReport(DataTableEntity recordDte, String totalName, Map<Integer, List<JSONObject>> reportConfigMap, StringBuilder tableStyle) {
+		StringBuilder reportHtml = new StringBuilder(4096);
 
-        // 鍒嗙粍琛ㄥご鍖哄垎缁勭粺璁″瓧娈靛悕绉發ist
-        List<String> groupAreaGroupStatisticsFieldNameList = Lists.newArrayList();
-        // 鍒嗙粍琛ㄥご鍖哄垎缁勫瓧娈靛悕绉發ist
-        List<String> groupAreaGroupFieldNameList = Lists.newArrayList();
-        // 鍒嗙粍琛ㄥご鍖哄尯鍩熻寖鍥磑bj
-        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));
-        });
+		// css
+		StringBuilder cssHtml = dataListReportService.getCssHtml();
 
-        // 鏁版嵁鍖哄垎缁勭粺璁″瓧娈靛悕绉發ist
-        List<String> dataAreaGroupStatisticsFieldNameList = Lists.newArrayList();
-        // 鏁版嵁鍖哄垎缁勫瓧娈靛悕绉發ist
-        List<String> dataAreaGroupFieldNameList = Lists.newArrayList();
-        // 鏁版嵁鍖虹壒娈婄粺璁″瓧娈靛悕绉發ist-鍒嗙粍琛ㄥご鍖轰笅缁熻瀛楁
-        List<String> dataAreaSpStatisticsFieldNameList = Lists.newArrayList();
-        // 鏁版嵁鍖烘櫘閫氱粺璁″瓧娈靛悕绉發ist-闈炴暟鎹尯鍒嗙粍瀛楁锛岄潪鍒嗙粍琛ㄥご鍖轰笅缁熻瀛楁
-        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);
-                }
-            }
-        });
+		// 鍒嗙粍琛ㄥご鍖哄拰鏁版嵁鍖�
+		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);
 
-        // 鑾峰彇鍒嗙粍琛ㄥご缁熻瀛楁瀵瑰簲鐨勬暟鎹尯瀛楁map
-        Map<String, List<String>> groupAreaStatisticsField2DataAreaFieldMap = getGroupAreaStatisticsField2DataAreaFieldMap(groupAreaFieldConfigMap, dataAreaFieldConfigMap);
-        // 鑾峰彇鍒嗙粍琛ㄥご鍖烘湯琛屽垎缁勫瓧娈靛搴旀暟鎹尯瀛楁map
-        Map<String, List<String>> groupAreaLastStageField2DataAreaFieldMap = getGroupAreaLastStageField2DataAreaFieldMap(groupAreaFieldConfigMap, dataAreaFieldConfigMap, groupAreaRangeObj);
+		// 澶撮儴鏍囬鍖�
+		StringBuilder headTitleHtml = null;
+		if (!reportConfigMap.get(1).isEmpty()) {
+			headTitleHtml = dataListReportService.getTitleHtml(reportConfigMap.get(1), totalColCount, headAndTailTitleDataMap, "head");
+		}
 
-        // 鑾峰彇鎸囧畾鏁版嵁闆嗕腑鍖呭惈鐨勬暟鎹尯瀛楁闆嗗悎
-        Set<String> headAndTailFieldSet = Sets.newHashSet();
-        headAndTailFieldSet.addAll(dataListReportService.getDataFields(reportConfigMap.get(1)));
-        headAndTailFieldSet.addAll(dataListReportService.getDataFields(reportConfigMap.get(3)));
+		// 搴曢儴鏍囬鍖�
+		StringBuilder tailTitleHtml = null;
+		if (!reportConfigMap.get(3).isEmpty()) {
+			tailTitleHtml = dataListReportService.getTitleHtml(reportConfigMap.get(3), totalColCount, headAndTailTitleDataMap, "tail");
+		}
 
-        // 缁熻map
-        Map<JSONObject, JSONObject> statisticsMap = Maps.newLinkedHashMap();
-        // 鍒嗙粍琛ㄥご鍖烘暟鎹畂bj
-        JSONObject groupAreaFieldRecordObj = new JSONObject(Maps.newTreeMap((o1, o2) -> dataListReportService.compare(o1, o2)));
-        // 鏁版嵁鍖哄垎缁勫瓧娈祇bj
-        JSONObject dataAreaFieldRecordObj = new JSONObject(Maps.newLinkedHashMap());
+		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>");
 
-        FieldSetEntity recordFse;
-        for (int i = 0;i < recordDte.getRows();i++) {
-            recordFse = recordDte.getFieldSetEntity(i);
+		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;
+	}
 
-            // 鑾峰彇澶撮儴銆佸熬閮ㄦ爣棰樺尯鏁版嵁瀛楁
-            dataListReportService.getHeadAndTailTitleDataMap(headAndTailTitleDataMap, headAndTailFieldSet, recordFse);
+	/**
+	 * 鎶ヨ〃-瑙f瀽-鏀惧叆鍒嗙粍琛ㄥご鍖哄拰鏁版嵁Html锛岃繑鍥炲垪鏁�
+	 *
+	 * @param groupAndDataAreaHtml    html瀹瑰櫒
+	 * @param reportConfigMap         鎶ヨ〃缂撳瓨鏁版嵁map
+	 * @param headAndTailTitleDataMap 澶撮儴銆佸熬閮ㄦ爣棰樺尯鏁版嵁瀛楁map瀹瑰櫒
+	 * @param recordDte               鏁版嵁婧愰泦鍚�
+	 * @param totalName               鎬昏鍚嶇О
+	 * @return 鏁版嵁鍖烘�诲垪鏁�
+	 */
+	private int getGroupAndDataAreaHtmlAndReturnDataAreaColCount(StringBuilder groupAndDataAreaHtml, Map<Integer, List<JSONObject>> reportConfigMap, Map<String, Set<String>> headAndTailTitleDataMap, DataTableEntity recordDte, String totalName) {
+		// 鍒嗙粍琛ㄥご鍖哄瓧娈电紦瀛榤ap
+		Map<String, JSONObject> groupAreaFieldConfigMap = dataListReportService.groupAndDataJSONObject2Map(reportConfigMap.get(2));
+		// 鏁版嵁鍖哄瓧娈电紦瀛榤ap
+		Map<String, JSONObject> dataAreaFieldConfigMap = dataListReportService.groupAndDataJSONObject2Map(reportConfigMap.get(0));
 
-            // 鑾峰彇鍒嗙粍琛ㄥご鍖烘暟鎹畂bj
-            getGroupAreaFieldRecordObj(groupAreaFieldRecordObj, groupAreaFieldConfigMap, recordFse, groupAreaStatisticsField2DataAreaFieldMap, groupAreaLastStageField2DataAreaFieldMap);
+		// 鍒嗙粍琛ㄥご鍖哄垎缁勭粺璁″瓧娈靛悕绉發ist
+		List<String> groupAreaGroupStatisticsFieldNameList = Lists.newArrayList();
+		// 鍒嗙粍琛ㄥご鍖哄垎缁勫瓧娈靛悕绉發ist
+		List<String> groupAreaGroupFieldNameList = Lists.newArrayList();
+		// 鍒嗙粍琛ㄥご鍖哄尯鍩熻寖鍥磑bj
+		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));
+		});
 
-            // 鑾峰彇鏁版嵁鍖哄垎缁勫瓧娈祇bj
-            getDataAreaGroupFieldRecordObj(dataAreaFieldRecordObj, dataAreaFieldConfigMap, recordFse);
+		// 鏁版嵁鍖哄垎缁勭粺璁″瓧娈靛悕绉發ist
+		List<String> dataAreaGroupStatisticsFieldNameList = Lists.newArrayList();
+		// 鏁版嵁鍖哄垎缁勫瓧娈靛悕绉發ist
+		List<String> dataAreaGroupFieldNameList = Lists.newArrayList();
+		// 鏁版嵁鍖虹壒娈婄粺璁″瓧娈靛悕绉發ist-鍒嗙粍琛ㄥご鍖轰笅缁熻瀛楁
+		List<String> dataAreaSpStatisticsFieldNameList = Lists.newArrayList();
+		// 鏁版嵁鍖烘櫘閫氱粺璁″瓧娈靛悕绉發ist-闈炴暟鎹尯鍒嗙粍瀛楁锛岄潪鍒嗙粍琛ㄥご鍖轰笅缁熻瀛楁
+		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);
+				}
+			}
+		});
 
-            // 鑾峰彇鏁版嵁鍖虹壒娈婂瓧娈电殑缁熻
-            statisticsDataAreaSpField(statisticsMap, dataAreaFieldConfigMap, dataAreaSpStatisticsFieldNameList, recordFse);
+		// 鑾峰彇鍒嗙粍琛ㄥご缁熻瀛楁瀵瑰簲鐨勬暟鎹尯瀛楁map
+		Map<String, List<String>> groupAreaStatisticsField2DataAreaFieldMap = getGroupAreaStatisticsField2DataAreaFieldMap(groupAreaFieldConfigMap, dataAreaFieldConfigMap);
+		// 鑾峰彇鍒嗙粍琛ㄥご鍖烘湯琛屽垎缁勫瓧娈靛搴旀暟鎹尯瀛楁map
+		Map<String, List<String>> groupAreaLastStageField2DataAreaFieldMap = getGroupAreaLastStageField2DataAreaFieldMap(groupAreaFieldConfigMap, dataAreaFieldConfigMap, groupAreaRangeObj);
 
-            // 鑾峰彇鏁版嵁鍖烘櫘閫氬瓧娈电殑缁熻
-            statisticsDataAreaCommonField(statisticsMap, dataAreaFieldConfigMap, dataAreaCommonStatisticsFieldNameList, recordFse);
-        }
+		// 鑾峰彇鎸囧畾鏁版嵁闆嗕腑鍖呭惈鐨勬暟鎹尯瀛楁闆嗗悎
+		Set<String> headAndTailFieldSet = Sets.newHashSet();
+		headAndTailFieldSet.addAll(dataListReportService.getDataFields(reportConfigMap.get(1)));
+		headAndTailFieldSet.addAll(dataListReportService.getDataFields(reportConfigMap.get(3)));
 
-        // 鑾峰彇鍒嗙粍琛ㄥご鍖哄拰鏁版嵁鍖烘�诲垪鏁�
-        int totalColCount = getTotalColCount(groupAreaFieldRecordObj, dataAreaGroupFieldNameList.size(), dataAreaCommonStatisticsFieldNameList.size());
+		// 缁熻map
+		Map<JSONObject, JSONObject> statisticsMap = Maps.newLinkedHashMap();
+		// 鍒嗙粍琛ㄥご鍖烘暟鎹畂bj
+		JSONObject groupAreaFieldRecordObj = new JSONObject(Maps.newTreeMap((o1, o2) -> dataListReportService.compare(o1, o2)));
+		// 鏁版嵁鍖哄垎缁勫瓧娈祇bj
+		JSONObject dataAreaFieldRecordObj = new JSONObject(Maps.newLinkedHashMap());
 
-        // 鏁版嵁鏍囬list
-        List<JSONObject> dataTitleList = Lists.newArrayList();
-        // 鑾峰彇鏍囬html
-        groupAndDataAreaHtml.append(getDataAreaTitleHtml(dataTitleList, groupAreaFieldRecordObj, dataAreaFieldConfigMap, groupAreaRangeObj, dataAreaCommonStatisticsFieldNameList));
-        // 鑾峰彇鍐呭html
-        groupAndDataAreaHtml.append(getDataAreaDataHtml(dataTitleList, dataAreaFieldRecordObj, statisticsMap, totalName, dataAreaGroupFieldNameList, dataAreaFieldConfigMap));
+		FieldSetEntity recordFse;
+		for (int i = 0; i < recordDte.getRows(); i++) {
+			recordFse = recordDte.getFieldSetEntity(i);
 
-        return totalColCount;
-    }
+			// 鑾峰彇澶撮儴銆佸熬閮ㄦ爣棰樺尯鏁版嵁瀛楁
+			dataListReportService.getHeadAndTailTitleDataMap(headAndTailTitleDataMap, headAndTailFieldSet, recordFse);
 
-    /**
-     * 鑾峰彇鍒嗙粍琛ㄥご缁熻瀛楁瀵瑰簲鐨勬暟鎹尯瀛楁map
-     * @param groupAreaFieldConfigMap       鍒嗙粍琛ㄥご鍖哄瓧娈电紦瀛榤ap
-     * @param dataAreaFieldConfigMap        鏁版嵁鍖哄瓧娈电紦瀛榤ap
-     * @return                              鍒嗙粍琛ㄥご缁熻瀛楁瀵瑰簲鐨勬暟鎹尯瀛楁map
-     */
-    private Map<String,List<String>> getGroupAreaStatisticsField2DataAreaFieldMap(Map<String, JSONObject> groupAreaFieldConfigMap, Map<String, JSONObject> dataAreaFieldConfigMap) {
-        Map<String, List<String>> resultMap = Maps.newLinkedHashMap();
-        String groupAreaFieldName;
-        JSONObject groupAreaFieldConfigObj;
-        JSONObject dataAreaFieldConfigObj;
-        for (Map.Entry<String, JSONObject> groupAreaFieldConfigEntry : groupAreaFieldConfigMap.entrySet()) {
-            groupAreaFieldConfigObj = groupAreaFieldConfigEntry.getValue();
-            if (!"1".equals(groupAreaFieldConfigObj.getString(CmnConst.ATTR_IS_STATISTICS))) {
-                continue;
-            }
-            groupAreaFieldName = groupAreaFieldConfigEntry.getKey();
-            for (Map.Entry<String, JSONObject> dataAreaFieldConfigEntry : dataAreaFieldConfigMap.entrySet()) {
-                dataAreaFieldConfigObj = dataAreaFieldConfigEntry.getValue();
-                if (dataListReportService.transfer2List(dataAreaFieldConfigObj.get(CmnConst.ATTR_GROUP_AREA_GROUP_FIELD)).contains(groupAreaFieldName)) {
-                    resultMap.computeIfAbsent(groupAreaFieldName, k -> Lists.newArrayList()).add(dataAreaFieldConfigEntry.getKey());
-                }
-            }
-        }
-        return resultMap;
-    }
+			// 鑾峰彇鍒嗙粍琛ㄥご鍖烘暟鎹畂bj
+			getGroupAreaFieldRecordObj(groupAreaFieldRecordObj, groupAreaFieldConfigMap, recordFse, groupAreaStatisticsField2DataAreaFieldMap, groupAreaLastStageField2DataAreaFieldMap);
 
-    /**
-     * 鑾峰彇鍒嗙粍琛ㄥご鍖烘湯琛屽垎缁勫瓧娈靛搴旀暟鎹尯瀛楁map
-     * @param groupAreaFieldConfigMap       鍒嗙粍琛ㄥご鍖哄瓧娈电紦瀛榤ap
-     * @param dataAreaFieldConfigMap        鏁版嵁鍖哄瓧娈电紦瀛榤ap
-     * @param groupAreaRangeObj             鍒嗙粍琛ㄥご鍖鸿寖鍥磑bj
-     * @return                              鍒嗙粍琛ㄥご鍖烘湯琛屽垎缁勫瓧娈靛搴旀暟鎹尯瀛楁map
-     */
-    private Map<String,List<String>> getGroupAreaLastStageField2DataAreaFieldMap(Map<String, JSONObject> groupAreaFieldConfigMap, Map<String, JSONObject> dataAreaFieldConfigMap, JSONObject groupAreaRangeObj) {
-        Map<String, List<String>> resultMap = Maps.newLinkedHashMap();
-        String groupFieldName;
-        JSONObject groupAreaFieldConfigObj;
-        JSONObject dataAreaFieldConfigObj;
-        for (Map.Entry<String, JSONObject> groupAreaFieldConfigEntry : groupAreaFieldConfigMap.entrySet()) {
-            groupAreaFieldConfigObj = groupAreaFieldConfigEntry.getValue();
-            if (groupAreaFieldConfigObj.getIntValue(CmnConst.ATTR_Y) + Math.max(1, groupAreaFieldConfigObj.getIntValue(CmnConst.ATTR_ROWSPAN)) - 1 < groupAreaRangeObj.getIntValue(CmnConst.MAX_Y)) {
-                continue;
-            }
-            groupFieldName = groupAreaFieldConfigEntry.getKey();
-            for (Map.Entry<String, JSONObject> dataAreaFieldConfigEntry : dataAreaFieldConfigMap.entrySet()) {
-                dataAreaFieldConfigObj = dataAreaFieldConfigEntry.getValue();
-                if (dataListReportService.transfer2List(dataAreaFieldConfigObj.get(CmnConst.ATTR_GROUP_AREA_GROUP_FIELD)).contains(groupFieldName)) {
-                    resultMap.computeIfAbsent(groupFieldName, k -> Lists.newArrayList()).add(dataAreaFieldConfigEntry.getKey());
-                }
-            }
+			// 鑾峰彇鏁版嵁鍖哄垎缁勫瓧娈祇bj
+			getDataAreaGroupFieldRecordObj(dataAreaFieldRecordObj, dataAreaFieldConfigMap, recordFse);
 
-        }
-        return resultMap;
-    }
+			// 鑾峰彇鏁版嵁鍖虹壒娈婂瓧娈电殑缁熻
+			statisticsDataAreaSpField(statisticsMap, dataAreaFieldConfigMap, dataAreaSpStatisticsFieldNameList, recordFse);
 
-    /**
-     * 鑾峰彇鏍囬-鍒嗙粍琛ㄥご鍖烘暟鎹畂bj
-     * @param groupAreaFieldRecordObj                       鍒嗙粍琛ㄥご鍖哄瓧娈佃褰昽bj
-     * @param groupAreaFieldConfigMap                       鍒嗙粍琛ㄥご鍖哄瓧娈电紦瀛榤ap
-     * @param recordFse                                     涓氬姟鏁版嵁璁板綍
-     * @param groupAreaStatisticsField2DataAreaFieldMap     鍒嗙粍琛ㄥご鍖虹粺璁″瓧娈靛搴旀暟鎹尯瀛楁map
-     * @param groupAreaLastStageField2DataAreaFieldMap      鍒嗙粍琛ㄥご鍖烘湯绾у瓧娈靛搴旀暟鎹尯瀛楁map
-     */
-    private void getGroupAreaFieldRecordObj(JSONObject groupAreaFieldRecordObj, Map<String, JSONObject> groupAreaFieldConfigMap, FieldSetEntity recordFse,
-                                            Map<String, List<String>> groupAreaStatisticsField2DataAreaFieldMap, Map<String, List<String>> groupAreaLastStageField2DataAreaFieldMap) {
-        JSONObject parentObj = groupAreaFieldRecordObj;
-        JSONObject subObj;
-        String value;
-        List<String> list;
-        String groupAreaGroupFieldName;
-        int i = 0;
-        List<String> statisticsFieldList;
-        String realValue;
-        for (Map.Entry<String, JSONObject> entry : groupAreaFieldConfigMap.entrySet()) {
-            list = Lists.newArrayList();
-            list.addAll(dataListReportService.transfer2List(entry.getValue().get(CmnConst.ATTR_GROUP_AREA_GROUP_FIELD)));
-            list.add(entry.getKey());
-            for (;i < list.size();i++) {
-                groupAreaGroupFieldName = list.get(i);
-                realValue = dataListReportService.getRealValue(recordFse, groupAreaGroupFieldName);
-                value = recordFse.getString(groupAreaGroupFieldName);
+			// 鑾峰彇鏁版嵁鍖烘櫘閫氬瓧娈电殑缁熻
+			statisticsDataAreaCommonField(statisticsMap, dataAreaFieldConfigMap, dataAreaCommonStatisticsFieldNameList, recordFse);
+		}
 
-                if (parentObj.get(value) == null) {
-                    subObj = new JSONObject(Maps.newTreeMap((o1, o2) -> dataListReportService.compare(o1, o2)));
-                    parentObj.put(value, subObj);
-                    // 娣诲姞鍒嗙粍琛ㄥご鍖哄垎缁勭粺璁″瓧娈靛搴旀暟鎹尯瀛楁
-                    if (groupAreaStatisticsField2DataAreaFieldMap.containsKey(groupAreaGroupFieldName)) {
-                        parentObj.put(value + CmnConst.STATISTICS_NAME, groupAreaStatisticsField2DataAreaFieldMap.get(groupAreaGroupFieldName));
-                        statisticsFieldList = dataListReportService.transfer2List(parentObj.get(CmnConst.ATTR_STATISTICS_FIELD));
-                        if (statisticsFieldList.isEmpty()) {
-                            parentObj.put(CmnConst.ATTR_STATISTICS_FIELD, statisticsFieldList);
-                        }
-                        if (!statisticsFieldList.contains(value + CmnConst.STATISTICS_NAME)) {
-                            statisticsFieldList.add(value + CmnConst.STATISTICS_NAME);
-                        }
-                    }
-                    // 娣诲姞鍒嗙粍琛ㄥご鍖烘湯绾у瓧娈靛搴旀暟鎹尯瀛楁
-                    if (groupAreaLastStageField2DataAreaFieldMap.containsKey(groupAreaGroupFieldName)) {
-                        parentObj.put(value, groupAreaLastStageField2DataAreaFieldMap.get(groupAreaGroupFieldName));
-                    }
-                    // 娣诲姞field_info
-                    if (StringUtils.isEmpty(parentObj.getString(CmnConst.ATTR_FIELD_INFO))) {
-                        parentObj.put(CmnConst.ATTR_FIELD_INFO, dataListReportService.fieldName2FieldInfo(groupAreaGroupFieldName));
-                    }
-                    if (!StringUtils.isEmpty(realValue)) {
-                        subObj.put(CmnConst.ATTR_REAL_VALUE, realValue);
-                    }
-                } else {
-                    if (!(parentObj.get(value) instanceof JSONObject)) {
-                        continue;
-                    }
-                    subObj = parentObj.getJSONObject(value);
-                }
-                parentObj = subObj;
-            }
-        }
-    }
+		// 鑾峰彇鍒嗙粍琛ㄥご鍖哄拰鏁版嵁鍖烘�诲垪鏁�
+		int totalColCount = getTotalColCount(groupAreaFieldRecordObj, dataAreaGroupFieldNameList.size(), dataAreaCommonStatisticsFieldNameList.size());
 
-    /**
-     * 鑾峰彇鏁版嵁鍖哄垎缁勫瓧娈祇bj
-     * @param dataAreaFieldRecordObj    鏁版嵁鍖哄瓧娈佃褰昽bj
-     * @param dataAreaFieldConfigMap    鏁版嵁鍖哄瓧娈电紦瀛榤ap
-     * @param recordFse                 涓氬姟鏁版嵁璁板綍
-     */
-    private void getDataAreaGroupFieldRecordObj(JSONObject dataAreaFieldRecordObj, Map<String, JSONObject> dataAreaFieldConfigMap, FieldSetEntity recordFse) {
-        JSONObject parentObj = dataAreaFieldRecordObj;
-        JSONObject subObj;
-        String value;
-        List<String> list;
-        String groupAreaGroupFieldName;
-        int i = 0;
-        String dataAreaFieldName;
-        JSONObject dataAreaFieldConfigObj;
-        List<String> statisticsFieldList;
-        String realValue;
-        for (Map.Entry<String, JSONObject> entry : dataAreaFieldConfigMap.entrySet()) {
-            dataAreaFieldConfigObj = entry.getValue();
-            if (!"1".equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_IS_GROUP))) {
-                break;
-            }
-            dataAreaFieldName = entry.getKey();
-            realValue = dataListReportService.getRealValue(recordFse, dataAreaFieldName);
-            list = Lists.newArrayList();
-            list.addAll(dataListReportService.transfer2List(dataAreaFieldConfigObj.get(CmnConst.ATTR_DATA_AREA_GROUP_FIELD)));
-            list.add(dataAreaFieldName);
-            for (;i < list.size();i++) {
-                groupAreaGroupFieldName = list.get(i);
-                value = recordFse.getString(groupAreaGroupFieldName);
-                subObj = parentObj.getJSONObject(value);
-                if (subObj == null) {
-                    subObj = new JSONObject(Maps.newLinkedHashMap());
-                    parentObj.put(value, subObj);
-                }
-                // 娣诲姞鏁版嵁鍖哄垎缁勭粺璁″瓧娈�
-                if ("1".equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_IS_STATISTICS))) {
-                    parentObj.put(value + CmnConst.STATISTICS_NAME, new JSONObject());
-                    statisticsFieldList = dataListReportService.transfer2List(parentObj.get(CmnConst.ATTR_STATISTICS_FIELD));
-                    if (statisticsFieldList.isEmpty()) {
-                        parentObj.put(CmnConst.ATTR_STATISTICS_FIELD, statisticsFieldList);
-                    }
-                    if (!statisticsFieldList.contains(value + CmnConst.STATISTICS_NAME)) {
-                        statisticsFieldList.add(value + CmnConst.STATISTICS_NAME);
-                    }
-                }
-                // 娣诲姞field_info
-                if (StringUtils.isEmpty(parentObj.getString(CmnConst.ATTR_FIELD_INFO))) {
-                    parentObj.put(CmnConst.ATTR_FIELD_INFO, dataListReportService.fieldName2FieldInfo(groupAreaGroupFieldName));
-                }
-                if (!StringUtils.isEmpty(realValue)) {
-                    subObj.put(CmnConst.ATTR_REAL_VALUE, realValue);
-                }
-                parentObj = subObj;
-            }
-        }
-    }
+		// 鏁版嵁鏍囬list
+		List<JSONObject> dataTitleList = Lists.newArrayList();
+		// 鑾峰彇鏍囬html
+		groupAndDataAreaHtml.append(getDataAreaTitleHtml(dataTitleList, groupAreaFieldRecordObj, dataAreaFieldConfigMap, groupAreaRangeObj, dataAreaCommonStatisticsFieldNameList));
+		// 鑾峰彇鍐呭html
+		groupAndDataAreaHtml.append(getDataAreaDataHtml(dataTitleList, dataAreaFieldRecordObj, statisticsMap, totalName, dataAreaGroupFieldNameList, dataAreaFieldConfigMap));
 
-    /**
-     * 鑾峰彇鏁版嵁鍖虹壒娈婂瓧娈电殑缁熻
-     * @param statisticsMap                         缁熻map
-     * @param dataAreaFieldConfigMap                鏁版嵁鍖哄瓧娈电紦瀛榤ap
-     * @param dataAreaSpStatisticsFieldNameList     鏁版嵁鍖虹壒娈婄粺璁″瓧娈靛悕绉發ist锛堝垎缁勮〃澶村尯涓嬬粺璁″瓧娈碉級
-     * @param recordFse                             涓氬姟鏁版嵁璁板綍
-     */
-    private void statisticsDataAreaSpField(Map<JSONObject, JSONObject> statisticsMap, Map<String, JSONObject> dataAreaFieldConfigMap, List<String> dataAreaSpStatisticsFieldNameList, FieldSetEntity recordFse) {
-        JSONObject dataAreaFieldConfigObj;
-        List<String> groupAreaGroupFieldNameList;
-        List<String> dataAreaGroupFieldNameList;
-        String value;
-        JSONObject keyObj;
-        JSONObject valueObj;
-        JSONObject groupAreaKeyObj;
-        JSONObject dataAreaKeyObj;
-        String statisticsType;
-        for (String dataAreaFieldName : dataAreaSpStatisticsFieldNameList) {
-            keyObj = new JSONObject();
-            groupAreaKeyObj = new JSONObject();
-            keyObj.put(CmnConst.ATTR_FIELD_INFO, dataListReportService.fieldName2FieldInfo(dataAreaFieldName));
-            dataAreaFieldConfigObj = dataAreaFieldConfigMap.get(dataAreaFieldName);
-            groupAreaGroupFieldNameList = dataListReportService.transfer2List(dataAreaFieldConfigObj.get(CmnConst.ATTR_GROUP_AREA_GROUP_FIELD));
-            dataAreaGroupFieldNameList = dataListReportService.transfer2List(dataAreaFieldConfigObj.get(CmnConst.ATTR_DATA_AREA_GROUP_FIELD));
-            value = dataListReportService.getValue(dataAreaFieldConfigObj, recordFse, dataAreaFieldName);
-            statisticsType = dataAreaFieldConfigObj.getString(CmnConst.ATTR_STATISTICS);
-            for (String groupAreaGroupFieldName : groupAreaGroupFieldNameList) {
-                dataAreaKeyObj = new JSONObject();
-                for (String dataAreaGroupFieldName : dataAreaGroupFieldNameList) {
-                    keyObj.remove(dataAreaGroupFieldName);
-                }
-                groupAreaKeyObj.put(groupAreaGroupFieldName, recordFse.getString(groupAreaGroupFieldName));
-                dataListReportService.extendJSONObject(keyObj, groupAreaKeyObj, null);
-                valueObj = statisticsMap.get(keyObj);
-                valueObj = dataListReportService.getStatisticsValueObj(valueObj, dataAreaFieldConfigObj, value, statisticsType, true);
-                statisticsMap.put((JSONObject) keyObj.clone(), valueObj);
-                for (String dataAreaGroupFieldName : dataAreaGroupFieldNameList) {
-                    dataAreaKeyObj.put(dataAreaGroupFieldName, recordFse.getString(dataAreaGroupFieldName));
-                    keyObj = dataListReportService.extendJSONObject(keyObj, dataAreaKeyObj, null);
-                    valueObj = statisticsMap.get(keyObj);
-                    valueObj = dataListReportService.getStatisticsValueObj(valueObj, dataAreaFieldConfigObj, value, statisticsType, true);
-                    statisticsMap.put((JSONObject) keyObj.clone(), valueObj);
-                }
-            }
-        }
-    }
+		return totalColCount;
+	}
 
-    /**
-     * 鍙栨暟鎹尯鏅�氬瓧娈电殑缁熻
-     * @param statisticsMap                             缁熻map
-     * @param dataAreaFieldConfigMap                    鏁版嵁鍖哄瓧娈电紦瀛榤ap
-     * @param dataAreaCommonStatisticsFieldNameList     鏁版嵁鍖烘櫘閫氱粺璁″瓧娈靛悕绉發ist
-     * @param recordFse                                 涓氬姟鏁版嵁璁板綍
-     */
-    private void statisticsDataAreaCommonField(Map<JSONObject, JSONObject> statisticsMap, Map<String, JSONObject> dataAreaFieldConfigMap, List<String> dataAreaCommonStatisticsFieldNameList, FieldSetEntity recordFse) {
-        JSONObject dataAreaFieldConfigObj;
-        List<String> dataAreaGroupFieldNameList;
-        String value;
-        JSONObject dataAreaKeyObj = new JSONObject();
-        JSONObject keyObj;
-        JSONObject valueObj;
-        String statisticsType;
-        int i;
-        for (String dataAreaFieldName : dataAreaCommonStatisticsFieldNameList) {
-            i = 0;
-            keyObj = new JSONObject();
-            dataAreaFieldConfigObj = dataAreaFieldConfigMap.get(dataAreaFieldName);
-            dataAreaGroupFieldNameList = dataListReportService.transfer2List(dataAreaFieldConfigObj.get(CmnConst.ATTR_DATA_AREA_GROUP_FIELD));
-            statisticsType = dataAreaFieldConfigObj.getString(CmnConst.ATTR_STATISTICS);
-            value = dataListReportService.getValue(dataAreaFieldConfigObj, recordFse, dataAreaFieldName);
-            keyObj.put(CmnConst.ATTR_FIELD_INFO, dataListReportService.fieldName2FieldInfo(dataAreaFieldName));
-            valueObj = statisticsMap.get(keyObj);
-            valueObj = dataListReportService.getStatisticsValueObj(valueObj, dataAreaFieldConfigObj, value, statisticsType, false);
-            statisticsMap.put((JSONObject) keyObj.clone(), valueObj);
-            for (String dataAreaGroupFieldName : dataAreaGroupFieldNameList) {
-                i++;
-                dataAreaKeyObj.put(dataAreaGroupFieldName, recordFse.getString(dataAreaGroupFieldName));
-                keyObj = dataListReportService.extendJSONObject(keyObj, dataAreaKeyObj, null);
-                valueObj = statisticsMap.get(keyObj);
-                valueObj = dataListReportService.getStatisticsValueObj(valueObj, dataAreaFieldConfigObj, value, statisticsType, i == dataAreaGroupFieldNameList.size());
-                statisticsMap.put((JSONObject) keyObj.clone(), valueObj);
-            }
-        }
-    }
+	/**
+	 * 鎶ヨ〃-瑙f瀽-鏀惧叆鍒嗙粍琛ㄥご鍖哄拰鏁版嵁锛岃繑鍥炲垪鏁�
+	 *
+	 * @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) {
+		// 鍒嗙粍琛ㄥご鍖哄瓧娈电紦瀛榤ap
+		Map<String, JSONObject> groupAreaFieldConfigMap = dataListReportService.groupAndDataJSONObject2Map(reportConfigMap.get(2));
+		// 鏁版嵁鍖哄瓧娈电紦瀛榤ap
+		Map<String, JSONObject> dataAreaFieldConfigMap = dataListReportService.groupAndDataJSONObject2Map(reportConfigMap.get(0));
 
-    /**
-     * 鑾峰彇鍒嗙粍琛ㄥご鍖哄拰鏁版嵁鍖烘�诲垪鏁�
-     * @param groupAreaFieldRecordObj               鍒嗙粍琛ㄥご鍖哄瓧娈佃褰昽bj
-     * @param dataAreaGroupFieldCount               鏁版嵁鍖哄垎缁勫瓧娈典釜鏁�
-     * @param dataAreaCommonStatisticsFieldCount    鏁版嵁鍖烘櫘閫氱粺璁″瓧娈典釜鏁�
-     * @return                                      鍒嗙粍琛ㄥご鍖哄拰鏁版嵁鍖烘�诲垪鏁�
-     */
-    private int getTotalColCount(JSONObject groupAreaFieldRecordObj, int dataAreaGroupFieldCount, int dataAreaCommonStatisticsFieldCount) {
-        int groupAreaColCount = getGroupAreaColCount(groupAreaFieldRecordObj, 0);
-        return groupAreaColCount + dataAreaGroupFieldCount + dataAreaCommonStatisticsFieldCount;
-    }
+		// 鍒嗙粍琛ㄥご鍖哄垎缁勭粺璁″瓧娈靛悕绉發ist
+		List<String> groupAreaGroupStatisticsFieldNameList = Lists.newArrayList();
+		// 鍒嗙粍琛ㄥご鍖哄垎缁勫瓧娈靛悕绉發ist
+		List<String> groupAreaGroupFieldNameList = Lists.newArrayList();
+		// 鍒嗙粍琛ㄥご鍖哄尯鍩熻寖鍥磑bj
+		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));
+		});
 
-    /**
-     * 鑾峰彇鍒嗙粍琛ㄥご鍖烘�诲垪鏁�
-     * @param curOperateObj         褰撳墠鎿嶄綔鐨刼bj
-     * @param groupAreaColCount     鍒嗙粍琛ㄥご鍖哄垪鏁�
-     * @return                      鍒嗙粍琛ㄥご鍖烘�诲垪鏁�
-     */
-    private int getGroupAreaColCount(JSONObject curOperateObj, int groupAreaColCount) {
-        if (curOperateObj == null) {
-            return groupAreaColCount;
-        }
-        String key;
-        Object value;
-        for (Map.Entry<String, Object> entry : curOperateObj.entrySet()) {
-            key = entry.getKey();
-            if (CmnConst.ATTR_FIELD_INFO.equals(key) || CmnConst.ATTR_STATISTICS_FIELD.equals(key)) {
-                continue;
-            }
-            value = entry.getValue();
-            if (value == null) {
-                continue;
-            }
-            if (value instanceof List) {
-                groupAreaColCount += ((List) value).size();
-            } else if (value instanceof JSONObject) {
-                groupAreaColCount = getGroupAreaColCount((JSONObject) value, groupAreaColCount);
-            }
-        }
-        return groupAreaColCount;
-    }
+		// 鏁版嵁鍖哄垎缁勭粺璁″瓧娈靛悕绉發ist
+		List<String> dataAreaGroupStatisticsFieldNameList = Lists.newArrayList();
+		// 鏁版嵁鍖哄垎缁勫瓧娈靛悕绉發ist
+		List<String> dataAreaGroupFieldNameList = Lists.newArrayList();
+		// 鏁版嵁鍖虹壒娈婄粺璁″瓧娈靛悕绉發ist-鍒嗙粍琛ㄥご鍖轰笅缁熻瀛楁
+		List<String> dataAreaSpStatisticsFieldNameList = Lists.newArrayList();
+		// 鏁版嵁鍖烘櫘閫氱粺璁″瓧娈靛悕绉發ist-闈炴暟鎹尯鍒嗙粍瀛楁锛岄潪鍒嗙粍琛ㄥご鍖轰笅缁熻瀛楁
+		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);
+				}
+			}
+		});
 
-    /**
-     * 鑾峰彇鏍囬html
-     * @param dataTitleList                             鏁版嵁鏍囬list
-     * @param groupAreaFieldRecordObj                   鍒嗙粍琛ㄥご鍖哄瓧娈佃褰昽bj
-     * @param dataAreaFieldConfigMap                    鏁版嵁鍖哄瓧娈电紦瀛榤ap
-     * @param groupAreaRangeObj                         鍒嗙粍琛ㄥご鍘昏寖鍥磑bj
-     * @param dataAreaCommonStatisticsFieldNameList     鏁版嵁鍖烘櫘閫氱粺璁″瓧娈靛悕绉發ist
-     * @return                                          鏁版嵁鏍囬html
-     */
-    private StringBuilder getDataAreaTitleHtml(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();
+		// 鑾峰彇鍒嗙粍琛ㄥご缁熻瀛楁瀵瑰簲鐨勬暟鎹尯瀛楁map
+		Map<String, List<String>> groupAreaStatisticsField2DataAreaFieldMap = getGroupAreaStatisticsField2DataAreaFieldMap(groupAreaFieldConfigMap, dataAreaFieldConfigMap);
+		// 鑾峰彇鍒嗙粍琛ㄥご鍖烘湯琛屽垎缁勫瓧娈靛搴旀暟鎹尯瀛楁map
+		Map<String, List<String>> groupAreaLastStageField2DataAreaFieldMap = getGroupAreaLastStageField2DataAreaFieldMap(groupAreaFieldConfigMap, dataAreaFieldConfigMap, groupAreaRangeObj);
 
-        String dataAreaFieldName;
-        JSONObject dataAreaFieldConfigObj;
-        JSONObject titleObj;
-        for (Map.Entry<String, JSONObject> entry : dataAreaFieldConfigMap.entrySet()) {
-            dataAreaFieldName = entry.getKey();
-            dataAreaFieldConfigObj = entry.getValue();
-            titleObj = new JSONObject();
+		// 鑾峰彇鎸囧畾鏁版嵁闆嗕腑鍖呭惈鐨勬暟鎹尯瀛楁闆嗗悎
+		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();
+		// 鍒嗙粍琛ㄥご鍖烘暟鎹畂bj
+		JSONObject groupAreaFieldRecordObj = new JSONObject(Maps.newTreeMap((o1, o2) -> dataListReportService.compare(o1, o2)));
+		// 鏁版嵁鍖哄垎缁勫瓧娈祇bj
+		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);
+
+			// 鑾峰彇鍒嗙粍琛ㄥご鍖烘暟鎹畂bj
+			getGroupAreaFieldRecordObj(groupAreaFieldRecordObj, groupAreaFieldConfigMap, recordFse, groupAreaStatisticsField2DataAreaFieldMap, groupAreaLastStageField2DataAreaFieldMap);
+
+			// 鑾峰彇鏁版嵁鍖哄垎缁勫瓧娈祇bj
+			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 鍒嗙粍琛ㄥご鍖哄瓧娈电紦瀛榤ap
+	 * @param dataAreaFieldConfigMap  鏁版嵁鍖哄瓧娈电紦瀛榤ap
+	 * @return 鍒嗙粍琛ㄥご缁熻瀛楁瀵瑰簲鐨勬暟鎹尯瀛楁map
+	 */
+	private Map<String, List<String>> getGroupAreaStatisticsField2DataAreaFieldMap(Map<String, JSONObject> groupAreaFieldConfigMap, Map<String, JSONObject> dataAreaFieldConfigMap) {
+		Map<String, List<String>> resultMap = Maps.newLinkedHashMap();
+		String groupAreaFieldName;
+		JSONObject groupAreaFieldConfigObj;
+		JSONObject dataAreaFieldConfigObj;
+		for (Map.Entry<String, JSONObject> groupAreaFieldConfigEntry : groupAreaFieldConfigMap.entrySet()) {
+			groupAreaFieldConfigObj = groupAreaFieldConfigEntry.getValue();
+			if (!"1".equals(groupAreaFieldConfigObj.getString(CmnConst.ATTR_IS_STATISTICS))) {
+				continue;
+			}
+			groupAreaFieldName = groupAreaFieldConfigEntry.getKey();
+			for (Map.Entry<String, JSONObject> dataAreaFieldConfigEntry : dataAreaFieldConfigMap.entrySet()) {
+				dataAreaFieldConfigObj = dataAreaFieldConfigEntry.getValue();
+				if (dataListReportService.transfer2List(dataAreaFieldConfigObj.get(CmnConst.ATTR_GROUP_AREA_GROUP_FIELD)).contains(groupAreaFieldName)) {
+					resultMap.computeIfAbsent(groupAreaFieldName, k -> Lists.newArrayList()).add(dataAreaFieldConfigEntry.getKey());
+				}
+			}
+		}
+		return resultMap;
+	}
+
+	/**
+	 * 鑾峰彇鍒嗙粍琛ㄥご鍖烘湯琛屽垎缁勫瓧娈靛搴旀暟鎹尯瀛楁map
+	 *
+	 * @param groupAreaFieldConfigMap 鍒嗙粍琛ㄥご鍖哄瓧娈电紦瀛榤ap
+	 * @param dataAreaFieldConfigMap  鏁版嵁鍖哄瓧娈电紦瀛榤ap
+	 * @param groupAreaRangeObj       鍒嗙粍琛ㄥご鍖鸿寖鍥磑bj
+	 * @return 鍒嗙粍琛ㄥご鍖烘湯琛屽垎缁勫瓧娈靛搴旀暟鎹尯瀛楁map
+	 */
+	private Map<String, List<String>> getGroupAreaLastStageField2DataAreaFieldMap(Map<String, JSONObject> groupAreaFieldConfigMap, Map<String, JSONObject> dataAreaFieldConfigMap, JSONObject groupAreaRangeObj) {
+		Map<String, List<String>> resultMap = Maps.newLinkedHashMap();
+		String groupFieldName;
+		JSONObject groupAreaFieldConfigObj;
+		JSONObject dataAreaFieldConfigObj;
+		for (Map.Entry<String, JSONObject> groupAreaFieldConfigEntry : groupAreaFieldConfigMap.entrySet()) {
+			groupAreaFieldConfigObj = groupAreaFieldConfigEntry.getValue();
+			if (groupAreaFieldConfigObj.getIntValue(CmnConst.ATTR_Y) + Math.max(1, groupAreaFieldConfigObj.getIntValue(CmnConst.ATTR_ROWSPAN)) - 1 < groupAreaRangeObj.getIntValue(CmnConst.MAX_Y)) {
+				continue;
+			}
+			groupFieldName = groupAreaFieldConfigEntry.getKey();
+			for (Map.Entry<String, JSONObject> dataAreaFieldConfigEntry : dataAreaFieldConfigMap.entrySet()) {
+				dataAreaFieldConfigObj = dataAreaFieldConfigEntry.getValue();
+				if (dataListReportService.transfer2List(dataAreaFieldConfigObj.get(CmnConst.ATTR_GROUP_AREA_GROUP_FIELD)).contains(groupFieldName)) {
+					resultMap.computeIfAbsent(groupFieldName, k -> Lists.newArrayList()).add(dataAreaFieldConfigEntry.getKey());
+				}
+			}
+
+		}
+		return resultMap;
+	}
+
+	/**
+	 * 鑾峰彇鏍囬-鍒嗙粍琛ㄥご鍖烘暟鎹畂bj
+	 *
+	 * @param groupAreaFieldRecordObj                   鍒嗙粍琛ㄥご鍖哄瓧娈佃褰昽bj
+	 * @param groupAreaFieldConfigMap                   鍒嗙粍琛ㄥご鍖哄瓧娈电紦瀛榤ap
+	 * @param recordFse                                 涓氬姟鏁版嵁璁板綍
+	 * @param groupAreaStatisticsField2DataAreaFieldMap 鍒嗙粍琛ㄥご鍖虹粺璁″瓧娈靛搴旀暟鎹尯瀛楁map
+	 * @param groupAreaLastStageField2DataAreaFieldMap  鍒嗙粍琛ㄥご鍖烘湯绾у瓧娈靛搴旀暟鎹尯瀛楁map
+	 */
+	private void getGroupAreaFieldRecordObj(JSONObject groupAreaFieldRecordObj, Map<String, JSONObject> groupAreaFieldConfigMap, FieldSetEntity recordFse,
+											Map<String, List<String>> groupAreaStatisticsField2DataAreaFieldMap, Map<String, List<String>> groupAreaLastStageField2DataAreaFieldMap) {
+		JSONObject parentObj = groupAreaFieldRecordObj;
+		JSONObject subObj;
+		String value;
+		List<String> list;
+		String groupAreaGroupFieldName;
+		int i = 0;
+		List<String> statisticsFieldList;
+		String realValue;
+		for (Map.Entry<String, JSONObject> entry : groupAreaFieldConfigMap.entrySet()) {
+			list = Lists.newArrayList();
+			list.addAll(dataListReportService.transfer2List(entry.getValue().get(CmnConst.ATTR_GROUP_AREA_GROUP_FIELD)));
+			list.add(entry.getKey());
+			for (; i < list.size(); i++) {
+				groupAreaGroupFieldName = list.get(i);
+				realValue = dataListReportService.getRealValue(recordFse, groupAreaGroupFieldName);
+				value = recordFse.getString(groupAreaGroupFieldName);
+
+				if (parentObj.get(value) == null) {
+					subObj = new JSONObject(Maps.newTreeMap((o1, o2) -> dataListReportService.compare(o1, o2)));
+					parentObj.put(value, subObj);
+					// 娣诲姞鍒嗙粍琛ㄥご鍖哄垎缁勭粺璁″瓧娈靛搴旀暟鎹尯瀛楁
+					if (groupAreaStatisticsField2DataAreaFieldMap.containsKey(groupAreaGroupFieldName)) {
+						parentObj.put(value + CmnConst.STATISTICS_NAME, groupAreaStatisticsField2DataAreaFieldMap.get(groupAreaGroupFieldName));
+						statisticsFieldList = dataListReportService.transfer2List(parentObj.get(CmnConst.ATTR_STATISTICS_FIELD));
+						if (statisticsFieldList.isEmpty()) {
+							parentObj.put(CmnConst.ATTR_STATISTICS_FIELD, statisticsFieldList);
+						}
+						if (!statisticsFieldList.contains(value + CmnConst.STATISTICS_NAME)) {
+							statisticsFieldList.add(value + CmnConst.STATISTICS_NAME);
+						}
+					}
+					// 娣诲姞鍒嗙粍琛ㄥご鍖烘湯绾у瓧娈靛搴旀暟鎹尯瀛楁
+					if (groupAreaLastStageField2DataAreaFieldMap.containsKey(groupAreaGroupFieldName)) {
+						parentObj.put(value, groupAreaLastStageField2DataAreaFieldMap.get(groupAreaGroupFieldName));
+					}
+					// 娣诲姞field_info
+					if (StringUtils.isEmpty(parentObj.getString(CmnConst.ATTR_FIELD_INFO))) {
+						parentObj.put(CmnConst.ATTR_FIELD_INFO, dataListReportService.fieldName2FieldInfo(groupAreaGroupFieldName));
+					}
+					if (!StringUtils.isEmpty(realValue)) {
+						subObj.put(CmnConst.ATTR_REAL_VALUE, realValue);
+					}
+				} else {
+					if (!(parentObj.get(value) instanceof JSONObject)) {
+						continue;
+					}
+					subObj = parentObj.getJSONObject(value);
+				}
+				parentObj = subObj;
+			}
+		}
+	}
+
+	/**
+	 * 鑾峰彇鏁版嵁鍖哄垎缁勫瓧娈祇bj
+	 *
+	 * @param dataAreaFieldRecordObj 鏁版嵁鍖哄瓧娈佃褰昽bj
+	 * @param dataAreaFieldConfigMap 鏁版嵁鍖哄瓧娈电紦瀛榤ap
+	 * @param recordFse              涓氬姟鏁版嵁璁板綍
+	 */
+	private void getDataAreaGroupFieldRecordObj(JSONObject dataAreaFieldRecordObj, Map<String, JSONObject> dataAreaFieldConfigMap, FieldSetEntity recordFse) {
+		JSONObject parentObj = dataAreaFieldRecordObj;
+		JSONObject subObj;
+		String value;
+		List<String> list;
+		String groupAreaGroupFieldName;
+		int i = 0;
+		String dataAreaFieldName;
+		JSONObject dataAreaFieldConfigObj;
+		List<String> statisticsFieldList;
+		String realValue;
+		for (Map.Entry<String, JSONObject> entry : dataAreaFieldConfigMap.entrySet()) {
+			dataAreaFieldConfigObj = entry.getValue();
+			if (!"1".equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_IS_GROUP))) {
+				break;
+			}
+			dataAreaFieldName = entry.getKey();
+			realValue = dataListReportService.getRealValue(recordFse, dataAreaFieldName);
+			list = Lists.newArrayList();
+			list.addAll(dataListReportService.transfer2List(dataAreaFieldConfigObj.get(CmnConst.ATTR_DATA_AREA_GROUP_FIELD)));
+			list.add(dataAreaFieldName);
+			for (; i < list.size(); i++) {
+				groupAreaGroupFieldName = list.get(i);
+				value = recordFse.getString(groupAreaGroupFieldName);
+				subObj = parentObj.getJSONObject(value);
+				if (subObj == null) {
+					subObj = new JSONObject(Maps.newLinkedHashMap());
+					parentObj.put(value, subObj);
+				}
+				// 娣诲姞鏁版嵁鍖哄垎缁勭粺璁″瓧娈�
+				if ("1".equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_IS_STATISTICS))) {
+					parentObj.put(value + CmnConst.STATISTICS_NAME, new JSONObject());
+					statisticsFieldList = dataListReportService.transfer2List(parentObj.get(CmnConst.ATTR_STATISTICS_FIELD));
+					if (statisticsFieldList.isEmpty()) {
+						parentObj.put(CmnConst.ATTR_STATISTICS_FIELD, statisticsFieldList);
+					}
+					if (!statisticsFieldList.contains(value + CmnConst.STATISTICS_NAME)) {
+						statisticsFieldList.add(value + CmnConst.STATISTICS_NAME);
+					}
+				}
+				// 娣诲姞field_info
+				if (StringUtils.isEmpty(parentObj.getString(CmnConst.ATTR_FIELD_INFO))) {
+					parentObj.put(CmnConst.ATTR_FIELD_INFO, dataListReportService.fieldName2FieldInfo(groupAreaGroupFieldName));
+				}
+				if (!StringUtils.isEmpty(realValue)) {
+					subObj.put(CmnConst.ATTR_REAL_VALUE, realValue);
+				}
+				parentObj = subObj;
+			}
+		}
+	}
+
+	/**
+	 * 鑾峰彇鏁版嵁鍖虹壒娈婂瓧娈电殑缁熻
+	 *
+	 * @param statisticsMap                     缁熻map
+	 * @param dataAreaFieldConfigMap            鏁版嵁鍖哄瓧娈电紦瀛榤ap
+	 * @param dataAreaSpStatisticsFieldNameList 鏁版嵁鍖虹壒娈婄粺璁″瓧娈靛悕绉發ist锛堝垎缁勮〃澶村尯涓嬬粺璁″瓧娈碉級
+	 * @param recordFse                         涓氬姟鏁版嵁璁板綍
+	 */
+	private void statisticsDataAreaSpField(Map<JSONObject, JSONObject> statisticsMap, Map<String, JSONObject> dataAreaFieldConfigMap, List<String> dataAreaSpStatisticsFieldNameList, FieldSetEntity recordFse) {
+		JSONObject dataAreaFieldConfigObj;
+		List<String> groupAreaGroupFieldNameList;
+		List<String> dataAreaGroupFieldNameList;
+		String value;
+		JSONObject keyObj;
+		JSONObject valueObj;
+		JSONObject groupAreaKeyObj;
+		JSONObject dataAreaKeyObj;
+		String statisticsType;
+		for (String dataAreaFieldName : dataAreaSpStatisticsFieldNameList) {
+			keyObj = new JSONObject();
+			groupAreaKeyObj = new JSONObject();
+			keyObj.put(CmnConst.ATTR_FIELD_INFO, dataListReportService.fieldName2FieldInfo(dataAreaFieldName));
+			dataAreaFieldConfigObj = dataAreaFieldConfigMap.get(dataAreaFieldName);
+			groupAreaGroupFieldNameList = dataListReportService.transfer2List(dataAreaFieldConfigObj.get(CmnConst.ATTR_GROUP_AREA_GROUP_FIELD));
+			dataAreaGroupFieldNameList = dataListReportService.transfer2List(dataAreaFieldConfigObj.get(CmnConst.ATTR_DATA_AREA_GROUP_FIELD));
+			value = dataListReportService.getValue(dataAreaFieldConfigObj, recordFse, dataAreaFieldName);
+			statisticsType = dataAreaFieldConfigObj.getString(CmnConst.ATTR_STATISTICS);
+			for (String groupAreaGroupFieldName : groupAreaGroupFieldNameList) {
+				dataAreaKeyObj = new JSONObject();
+				for (String dataAreaGroupFieldName : dataAreaGroupFieldNameList) {
+					keyObj.remove(dataAreaGroupFieldName);
+				}
+				groupAreaKeyObj.put(groupAreaGroupFieldName, recordFse.getString(groupAreaGroupFieldName));
+				dataListReportService.extendJSONObject(keyObj, groupAreaKeyObj, null);
+				valueObj = statisticsMap.get(keyObj);
+				valueObj = dataListReportService.getStatisticsValueObj(valueObj, dataAreaFieldConfigObj, value, statisticsType, true);
+				statisticsMap.put((JSONObject) keyObj.clone(), valueObj);
+				for (String dataAreaGroupFieldName : dataAreaGroupFieldNameList) {
+					dataAreaKeyObj.put(dataAreaGroupFieldName, recordFse.getString(dataAreaGroupFieldName));
+					keyObj = dataListReportService.extendJSONObject(keyObj, dataAreaKeyObj, null);
+					valueObj = statisticsMap.get(keyObj);
+					valueObj = dataListReportService.getStatisticsValueObj(valueObj, dataAreaFieldConfigObj, value, statisticsType, true);
+					statisticsMap.put((JSONObject) keyObj.clone(), valueObj);
+				}
+			}
+		}
+	}
+
+	/**
+	 * 鍙栨暟鎹尯鏅�氬瓧娈电殑缁熻
+	 *
+	 * @param statisticsMap                         缁熻map
+	 * @param dataAreaFieldConfigMap                鏁版嵁鍖哄瓧娈电紦瀛榤ap
+	 * @param dataAreaCommonStatisticsFieldNameList 鏁版嵁鍖烘櫘閫氱粺璁″瓧娈靛悕绉發ist
+	 * @param recordFse                             涓氬姟鏁版嵁璁板綍
+	 */
+	private void statisticsDataAreaCommonField(Map<JSONObject, JSONObject> statisticsMap, Map<String, JSONObject> dataAreaFieldConfigMap, List<String> dataAreaCommonStatisticsFieldNameList, FieldSetEntity recordFse) {
+		JSONObject dataAreaFieldConfigObj;
+		List<String> dataAreaGroupFieldNameList;
+		String value;
+		JSONObject dataAreaKeyObj = new JSONObject();
+		JSONObject keyObj;
+		JSONObject valueObj;
+		String statisticsType;
+		int i;
+		for (String dataAreaFieldName : dataAreaCommonStatisticsFieldNameList) {
+			i = 0;
+			keyObj = new JSONObject();
+			dataAreaFieldConfigObj = dataAreaFieldConfigMap.get(dataAreaFieldName);
+			dataAreaGroupFieldNameList = dataListReportService.transfer2List(dataAreaFieldConfigObj.get(CmnConst.ATTR_DATA_AREA_GROUP_FIELD));
+			statisticsType = dataAreaFieldConfigObj.getString(CmnConst.ATTR_STATISTICS);
+			value = dataListReportService.getValue(dataAreaFieldConfigObj, recordFse, dataAreaFieldName);
+			keyObj.put(CmnConst.ATTR_FIELD_INFO, dataListReportService.fieldName2FieldInfo(dataAreaFieldName));
+			valueObj = statisticsMap.get(keyObj);
+			valueObj = dataListReportService.getStatisticsValueObj(valueObj, dataAreaFieldConfigObj, value, statisticsType, false);
+			statisticsMap.put((JSONObject) keyObj.clone(), valueObj);
+			for (String dataAreaGroupFieldName : dataAreaGroupFieldNameList) {
+				i++;
+				dataAreaKeyObj.put(dataAreaGroupFieldName, recordFse.getString(dataAreaGroupFieldName));
+				keyObj = dataListReportService.extendJSONObject(keyObj, dataAreaKeyObj, null);
+				valueObj = statisticsMap.get(keyObj);
+				valueObj = dataListReportService.getStatisticsValueObj(valueObj, dataAreaFieldConfigObj, value, statisticsType, i == dataAreaGroupFieldNameList.size());
+				statisticsMap.put((JSONObject) keyObj.clone(), valueObj);
+			}
+		}
+	}
+
+	/**
+	 * 鑾峰彇鍒嗙粍琛ㄥご鍖哄拰鏁版嵁鍖烘�诲垪鏁�
+	 *
+	 * @param groupAreaFieldRecordObj            鍒嗙粍琛ㄥご鍖哄瓧娈佃褰昽bj
+	 * @param dataAreaGroupFieldCount            鏁版嵁鍖哄垎缁勫瓧娈典釜鏁�
+	 * @param dataAreaCommonStatisticsFieldCount 鏁版嵁鍖烘櫘閫氱粺璁″瓧娈典釜鏁�
+	 * @return 鍒嗙粍琛ㄥご鍖哄拰鏁版嵁鍖烘�诲垪鏁�
+	 */
+	private int getTotalColCount(JSONObject groupAreaFieldRecordObj, int dataAreaGroupFieldCount, int dataAreaCommonStatisticsFieldCount) {
+		int groupAreaColCount = getGroupAreaColCount(groupAreaFieldRecordObj, 0);
+		return groupAreaColCount + dataAreaGroupFieldCount + dataAreaCommonStatisticsFieldCount;
+	}
+
+	/**
+	 * 鑾峰彇鍒嗙粍琛ㄥご鍖烘�诲垪鏁�
+	 *
+	 * @param curOperateObj     褰撳墠鎿嶄綔鐨刼bj
+	 * @param groupAreaColCount 鍒嗙粍琛ㄥご鍖哄垪鏁�
+	 * @return 鍒嗙粍琛ㄥご鍖烘�诲垪鏁�
+	 */
+	private int getGroupAreaColCount(JSONObject curOperateObj, int groupAreaColCount) {
+		if (curOperateObj == null) {
+			return groupAreaColCount;
+		}
+		String key;
+		Object value;
+		for (Map.Entry<String, Object> entry : curOperateObj.entrySet()) {
+			key = entry.getKey();
+			if (CmnConst.ATTR_FIELD_INFO.equals(key) || CmnConst.ATTR_STATISTICS_FIELD.equals(key)) {
+				continue;
+			}
+			value = entry.getValue();
+			if (value == null) {
+				continue;
+			}
+			if (value instanceof List) {
+				groupAreaColCount += ((List) value).size();
+			} else if (value instanceof JSONObject) {
+				groupAreaColCount = getGroupAreaColCount((JSONObject) value, groupAreaColCount);
+			}
+		}
+		return groupAreaColCount;
+	}
+
+	/**
+	 * 鑾峰彇鏍囬
+	 *
+	 * @param dataTitleList                         鏁版嵁鏍囬list
+	 * @param groupAreaFieldRecordObj               鍒嗙粍琛ㄥご鍖哄瓧娈佃褰昽bj
+	 * @param dataAreaFieldConfigMap                鏁版嵁鍖哄瓧娈电紦瀛榤ap
+	 * @param groupAreaRangeObj                     鍒嗙粍琛ㄥご鍘昏寖鍥磑bj
+	 * @param dataAreaCommonStatisticsFieldNameList 鏁版嵁鍖烘櫘閫氱粺璁″瓧娈靛悕绉發ist
+	 * @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);
-                }
-            }
-        }
+			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);
+		dataTitleList.addAll(groupAreaRangeTitleList.get(maxRow));
+		dataTitleList.addAll(afterGroupAreaTitleList);
 
-        List<JSONObject> firstList = Lists.newArrayList();
-        firstList.addAll(beforeGroupAreaTitleList);
-        firstList.addAll(groupAreaRangeTitleList.get(0));
-        firstList.addAll(afterGroupAreaTitleList);
+		List<JSONObject> firstList = Lists.newArrayList();
+		firstList.addAll(beforeGroupAreaTitleList);
+		firstList.addAll(groupAreaRangeTitleList.get(0));
+		firstList.addAll(afterGroupAreaTitleList);
 
-        groupAreaRangeTitleList.set(0, firstList);
+		groupAreaRangeTitleList.set(0, firstList);
 
-        StringBuilder html = new StringBuilder(1024);
-        int rowspan;
-        int colspan;
-        String value;
-        for (List<JSONObject> rowList : groupAreaRangeTitleList) {
-            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);
-                }
-                html.append("<td rowspan=\"").append(rowspan).append("\" colspan=\"").append(colspan).append("\">").append(value == null ? "" : value).append("</td>");
-            }
-            html.append("\n</tr>");
-        }
-        return html;
-    }
+//		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;
+	}
 
-    /**
-     * 鑾峰彇鍒嗙粍琛ㄥご鍖鸿寖鍥寸殑鏍囬list
-     * @param dataAreaFieldConfigMap        鏁版嵁鍖哄瓧娈电紦瀛榤ap
-     * @param curOperateObj                 褰撳墠鎿嶄綔obj
-     * @param groupAreaRangeTitleList       鍒嗙粍琛ㄥご鍖鸿寖鍥翠笅鏁版嵁鏍囬list
-     * @param preTitleObj                   鏈�杩戞搷浣滅殑鏍囬obj
-     * @param row                           褰撳墠琛屾暟
-     * @param maxRow                        鏈�澶ц鏁�
-     */
-    private void getGroupAreaRangeTitleList(Map<String, JSONObject> dataAreaFieldConfigMap, JSONObject curOperateObj, List<List<JSONObject>> groupAreaRangeTitleList, JSONObject preTitleObj, int row, int maxRow, String parentFieldName) {
-        if (curOperateObj == null || curOperateObj.isEmpty()) {
-            return;
-        }
-        String key;
-        Object value;
-        JSONObject curTitleObj;
-        String groupAreaFieldName = dataListReportService.fieldInfo2FieldName(curOperateObj.getString(CmnConst.ATTR_FIELD_INFO));
-        List<String> statisticsFieldList = dataListReportService.transfer2List(curOperateObj.get(CmnConst.ATTR_STATISTICS_FIELD));
-        String realValue = curOperateObj.getString(CmnConst.ATTR_REAL_VALUE);
-        String fieldName = dataListReportService.fieldInfo2FieldName(curOperateObj.getString(CmnConst.ATTR_FIELD_INFO));
-        String newKey;
-        JSONObject realValueObj;
-        for (Map.Entry<String, Object> entry : curOperateObj.entrySet()) {
-            curTitleObj = dataListReportService.extendJSONObject(null, preTitleObj, null);
-            if (!StringUtils.isEmpty(realValue) && !StringUtils.isEmpty(parentFieldName)) {
-                if (curTitleObj.get(CmnConst.ATTR_REAL_VALUE) == null) {
-                    realValueObj = new JSONObject();
-                    curTitleObj.put(CmnConst.ATTR_REAL_VALUE, realValueObj);
-                } else {
-                    realValueObj = (JSONObject) curTitleObj.get(CmnConst.ATTR_REAL_VALUE);
-                }
-                realValueObj.put(parentFieldName, realValue);
-            }
-            key = entry.getKey();
-            if (CmnConst.ATTR_FIELD_INFO.equals(key) || CmnConst.ATTR_STATISTICS_FIELD.equals(key) || CmnConst.ATTR_REAL_VALUE.equals(key)) {
-                continue;
-            }
-            value = entry.getValue();
-            if (value == null) {
-                continue;
-            }
-            curTitleObj.put(CmnConst.ATTR_SHOW_NAME, key);
-            if (statisticsFieldList.contains(key)) {
-                curTitleObj.put(CmnConst.ATTR_IS_STATISTICS_FIELD, "1");
-                newKey = key.replace(CmnConst.STATISTICS_NAME, "");
-                curTitleObj.put(groupAreaFieldName, newKey);
-                curTitleObj.put(CmnConst.ATTR_GROUP_AREA_SUB_CNT, getSubCnt(curOperateObj.getJSONObject(newKey)));
-            } else {
-                curTitleObj.put(groupAreaFieldName, key);
-            }
-            groupAreaRangeTitleList.get(row).add(curTitleObj);
-            if (value instanceof List) {
-                curTitleObj.put(CmnConst.ATTR_COLSPAN, ((List) value).size());
-                curTitleObj.put(CmnConst.ATTR_ROWSPAN, maxRow - row);
-                for (String dataAreaFieldName : (List<String>) value) {
-                    JSONObject cloneTitleObj = (JSONObject) curTitleObj.clone();
-                    cloneTitleObj.put(CmnConst.ATTR_FIELD_INFO, dataListReportService.fieldName2FieldInfo(dataAreaFieldName));
-                    cloneTitleObj.put(CmnConst.ATTR_COLSPAN, 1);
-                    cloneTitleObj.put(CmnConst.ATTR_ROWSPAN, 1);
-                    JSONObject dataAreaFieldConfigObj = dataAreaFieldConfigMap.get(dataAreaFieldName);
-                    cloneTitleObj.put(CmnConst.ATTR_SHOW_NAME, dataListReportService.getStatisticsDesc(dataAreaFieldConfigObj.getString(CmnConst.ATTR_STATISTICS), dataAreaFieldConfigObj.getString(CmnConst.ATTR_SHOW_NAME)));
-                    groupAreaRangeTitleList.get(maxRow).add(cloneTitleObj);
-                }
-            } else {
-                if (value instanceof JSONObject) {
-                    curTitleObj.put(CmnConst.ATTR_COLSPAN, getGroupAreaColCount((JSONObject) value, 0));
-                    curTitleObj.put(CmnConst.ATTR_ROWSPAN, 1);
-                    getGroupAreaRangeTitleList(dataAreaFieldConfigMap, (JSONObject) value, groupAreaRangeTitleList, curTitleObj, row + 1, maxRow, fieldName);
-                }
-            }
-        }
-    }
+	/**
+	 * 鑾峰彇鏍囬html
+	 *
+	 * @param dataTitleList                         鏁版嵁鏍囬list
+	 * @param groupAreaFieldRecordObj               鍒嗙粍琛ㄥご鍖哄瓧娈佃褰昽bj
+	 * @param dataAreaFieldConfigMap                鏁版嵁鍖哄瓧娈电紦瀛榤ap
+	 * @param groupAreaRangeObj                     鍒嗙粍琛ㄥご鍘昏寖鍥磑bj
+	 * @param dataAreaCommonStatisticsFieldNameList 鏁版嵁鍖烘櫘閫氱粺璁″瓧娈靛悕绉發ist
+	 * @return 鏁版嵁鏍囬html
+	 */
+	private StringBuilder getDataAreaTitleHtml(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);
 
-    /**
-     * 鑾峰彇涓嬬骇鍒嗙粍椤规暟
-     * @param obj       寰呮搷浣滅殑obj
-     * @return          涓嬬骇鍒嗙粍椤规暟
-     */
-    private int getSubCnt(JSONObject obj) {
-        int count = 0;
-        List<String> statisticsFieldList = dataListReportService.transfer2List(obj.get(CmnConst.ATTR_STATISTICS_FIELD));
-        for (String key : obj.keySet()) {
-            if (CmnConst.ATTR_FIELD_INFO.equals(key) || CmnConst.ATTR_STATISTICS_FIELD.equals(key) || statisticsFieldList.contains(key)) {
-                continue;
-            }
-            count++;
-        }
-        return count;
-    }
+		List<JSONObject> beforeGroupAreaTitleList = Lists.newArrayList();
+		List<JSONObject> afterGroupAreaTitleList = Lists.newArrayList();
 
-    /**
-     * 鑾峰彇鍐呭html
-     * @param dataTitleList                 鏁版嵁鏍囬list
-     * @param dataAreaFieldRecordObj        鏁版嵁鍖哄瓧娈佃褰昽bj
-     * @param statisticsMap                 缁熻map
-     * @param totalName                     鎬昏鍚嶇О锛岄潪绌�-闇�瑕佹�昏
-     * @param dataAreaGroupFieldNameList    鏁版嵁鍖哄垎缁勫瓧娈靛悕绉發ist
-     * @param dataAreaFieldConfigMap        鏁版嵁鍖哄瓧娈电紦瀛榤ap
-     * @return                              涓氬姟鏁版嵁鍐呭html
-     */
-    private StringBuilder getDataAreaDataHtml(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);
+		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);
+				}
+			}
+		}
 
-        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);
-        }
+		dataTitleList.addAll(groupAreaRangeTitleList.get(maxRow));
+		dataTitleList.addAll(afterGroupAreaTitleList);
 
-        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>");
-        }
+		List<JSONObject> firstList = Lists.newArrayList();
+		firstList.addAll(beforeGroupAreaTitleList);
+		firstList.addAll(groupAreaRangeTitleList.get(0));
+		firstList.addAll(afterGroupAreaTitleList);
 
-        // 鎬昏
-        if (!StringUtils.isEmpty(totalName)) {
-            html.append(getTotalStatisticsHtml(statisticsMap, dataTitleList, dataAreaFieldConfigMap, dataAreaGroupFieldNameList.size(), getSubCnt(dataAreaFieldRecordObj), totalName));
-        }
+		groupAreaRangeTitleList.set(0, firstList);
 
-        return html;
-    }
+		StringBuilder html = new StringBuilder(1024);
+		int rowspan;
+		int colspan;
+		String value;
+		for (List<JSONObject> rowList : groupAreaRangeTitleList) {
+			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);
+				}
+				html.append("<td rowspan=\"").append(rowspan).append("\" colspan=\"").append(colspan).append("\">").append(value == null ? "" : value).append("</td>");
+			}
+			html.append("\n</tr>");
+		}
+		return html;
+	}
 
-    /**
-     * 鑾峰彇鏁版嵁鍖哄垎缁勫瓧娈垫暟鎹甽ist
-     * @param curOperateObj                 褰撳墠鎿嶄綔obj
-     * @param dataAreaGroupFieldDataList    鏁版嵁鍖哄垎缁勫瓧娈垫暟鎹甽ist
-     * @param preObj                        鏈�杩戞搷浣滅殑obj
-     * @param row                           褰撳墠琛屾暟
-     * @param maxCol                        鏈�澶у垪鏁�
-     * @return                              鏁版嵁鍖哄垎缁勫瓧娈垫暟鎹甽ist
-     */
-    private int getDataAreaGroupFieldDataList(JSONObject curOperateObj, List<List<JSONObject>> dataAreaGroupFieldDataList, JSONObject preObj, int row, int col, int maxCol, String parentFieldName) {
-        String key;
-        Object value;
-        JSONObject curObj;
-        JSONObject topLeftCornerObj;
-        String dataAreaFieldName = dataListReportService.fieldInfo2FieldName(curOperateObj.getString(CmnConst.ATTR_FIELD_INFO));
-        List<String> statisticsFieldList = dataListReportService.transfer2List(curOperateObj.get(CmnConst.ATTR_STATISTICS_FIELD));
-        String realValue = curOperateObj.getString(CmnConst.ATTR_REAL_VALUE);
-        JSONObject objValue;
-        String newKey;
-        List<JSONObject> curRowList;
-        JSONObject realValueObj;
-        for (Map.Entry<String, Object> entry : curOperateObj.entrySet()) {
-            curObj = dataListReportService.extendJSONObject(null, preObj, null);
-            key = entry.getKey();
-            if (CmnConst.ATTR_FIELD_INFO.equals(key) || CmnConst.ATTR_STATISTICS_FIELD.equals(key) || CmnConst.ATTR_REAL_VALUE.equals(key)) {
-                continue;
-            }
-            value = entry.getValue();
-            if (value == null) {
-                continue;
-            }
-            if (!StringUtils.isEmpty(realValue) && !StringUtils.isEmpty(parentFieldName)) {
-                if (curObj.get(CmnConst.ATTR_REAL_VALUE) == null) {
-                    realValueObj = new JSONObject();
-                    curObj.put(CmnConst.ATTR_REAL_VALUE, realValueObj);
-                } else {
-                    realValueObj = (JSONObject) curObj.get(CmnConst.ATTR_REAL_VALUE);
-                }
-                realValueObj.put(parentFieldName, realValue);
-            }
-            if (dataAreaGroupFieldDataList.size() < row) {
-                curRowList = Lists.newArrayList();
-                dataAreaGroupFieldDataList.add(curRowList);
-            } else {
-                curRowList = dataAreaGroupFieldDataList.get(row - 1);
-            }
-            if (curRowList.size() < col - 1) {
-                for (int i = 0; i < col - 1; i++) {
-                    curRowList.add(new JSONObject());
-                }
-            }
-            curObj.put(CmnConst.ATTR_SHOW_NAME, key);
-            if (statisticsFieldList.contains(key)) {
-                curObj.put(CmnConst.ATTR_IS_STATISTICS_FIELD, "1");
-                newKey = key.replace(CmnConst.STATISTICS_NAME, "");
-                curObj.put(dataAreaFieldName, newKey);
-                curObj.put(CmnConst.ATTR_DATA_AREA_SUB_CNT, getSubCnt(curOperateObj.getJSONObject(newKey)));
-            } else {
-                curObj.put(dataAreaFieldName, key);
-            }
-            curObj.put(CmnConst.ATTR_ROWSPAN, 1);
-            curObj.put(CmnConst.ATTR_COLSPAN, 1);
-            curRowList.add(curObj);
-            if (value instanceof JSONObject) {
-                objValue = (JSONObject) value;
-                if (objValue.isEmpty()) {
-                    curObj.put(CmnConst.ATTR_COLSPAN, maxCol - col + 1);
-                    if (row > 1 && col > 1) {
-                        int emptyCount = 0;
-                        for (JSONObject obj : curRowList) {
-                            if (obj.isEmpty()) {
-                                emptyCount++;
-                            } else {
-                                break;
-                            }
-                        }
-                        for (int j = 0; j < emptyCount; j++) {
-                            int curRow = row - 2;
-                            topLeftCornerObj = dataAreaGroupFieldDataList.get(curRow).get(j);
-                            while (topLeftCornerObj.isEmpty() && curRow > 0) {
-                                curRow--;
-                                topLeftCornerObj = dataAreaGroupFieldDataList.get(curRow).get(j);
-                            }
-                            topLeftCornerObj.put(CmnConst.ATTR_ROWSPAN, topLeftCornerObj.getIntValue(CmnConst.ATTR_ROWSPAN) + 1);
-                        }
-                    }
-                    row++;
-                    continue;
-                }
-                if (objValue.size() == 1&& objValue.containsKey(CmnConst.ATTR_REAL_VALUE)) {
-                    row++;
-                    continue;
-                }
-                row = getDataAreaGroupFieldDataList(objValue, dataAreaGroupFieldDataList, curObj, row, col + 1, maxCol, dataAreaFieldName);
-            }
-        }
-        return row;
-    }
+	/**
+	 * 鑾峰彇鍒嗙粍琛ㄥご鍖鸿寖鍥寸殑鏍囬list
+	 *
+	 * @param dataAreaFieldConfigMap  鏁版嵁鍖哄瓧娈电紦瀛榤ap
+	 * @param curOperateObj           褰撳墠鎿嶄綔obj
+	 * @param groupAreaRangeTitleList 鍒嗙粍琛ㄥご鍖鸿寖鍥翠笅鏁版嵁鏍囬list
+	 * @param preTitleObj             鏈�杩戞搷浣滅殑鏍囬obj
+	 * @param row                     褰撳墠琛屾暟
+	 * @param maxRow                  鏈�澶ц鏁�
+	 */
+	private void getGroupAreaRangeTitleList(Map<String, JSONObject> dataAreaFieldConfigMap, JSONObject curOperateObj, List<List<JSONObject>> groupAreaRangeTitleList, JSONObject preTitleObj, int row, int maxRow, String parentFieldName) {
+		if (curOperateObj == null || curOperateObj.isEmpty()) {
+			return;
+		}
+		String key;
+		Object value;
+		JSONObject curTitleObj;
+		String groupAreaFieldName = dataListReportService.fieldInfo2FieldName(curOperateObj.getString(CmnConst.ATTR_FIELD_INFO));
+		List<String> statisticsFieldList = dataListReportService.transfer2List(curOperateObj.get(CmnConst.ATTR_STATISTICS_FIELD));
+		String realValue = curOperateObj.getString(CmnConst.ATTR_REAL_VALUE);
+		String fieldName = dataListReportService.fieldInfo2FieldName(curOperateObj.getString(CmnConst.ATTR_FIELD_INFO));
+		String newKey;
+		JSONObject realValueObj;
+		for (Map.Entry<String, Object> entry : curOperateObj.entrySet()) {
+			curTitleObj = dataListReportService.extendJSONObject(null, preTitleObj, null);
+			if (!StringUtils.isEmpty(realValue) && !StringUtils.isEmpty(parentFieldName)) {
+				if (curTitleObj.get(CmnConst.ATTR_REAL_VALUE) == null) {
+					realValueObj = new JSONObject();
+					curTitleObj.put(CmnConst.ATTR_REAL_VALUE, realValueObj);
+				} else {
+					realValueObj = (JSONObject) curTitleObj.get(CmnConst.ATTR_REAL_VALUE);
+				}
+				realValueObj.put(parentFieldName, realValue);
+			}
+			key = entry.getKey();
+			if (CmnConst.ATTR_FIELD_INFO.equals(key) || CmnConst.ATTR_STATISTICS_FIELD.equals(key) || CmnConst.ATTR_REAL_VALUE.equals(key)) {
+				continue;
+			}
+			value = entry.getValue();
+			if (value == null) {
+				continue;
+			}
+			curTitleObj.put(CmnConst.ATTR_SHOW_NAME, key);
+			if (statisticsFieldList.contains(key)) {
+				curTitleObj.put(CmnConst.ATTR_IS_STATISTICS_FIELD, "1");
+				newKey = key.replace(CmnConst.STATISTICS_NAME, "");
+				curTitleObj.put(groupAreaFieldName, newKey);
+				curTitleObj.put(CmnConst.ATTR_GROUP_AREA_SUB_CNT, getSubCnt(curOperateObj.getJSONObject(newKey)));
+			} else {
+				curTitleObj.put(groupAreaFieldName, key);
+			}
+			groupAreaRangeTitleList.get(row).add(curTitleObj);
+			if (value instanceof List) {
+				curTitleObj.put(CmnConst.ATTR_COLSPAN, ((List) value).size());
+				curTitleObj.put(CmnConst.ATTR_ROWSPAN, maxRow - row);
+				for (String dataAreaFieldName : (List<String>) value) {
+					JSONObject cloneTitleObj = (JSONObject) curTitleObj.clone();
+					cloneTitleObj.put(CmnConst.ATTR_FIELD_INFO, dataListReportService.fieldName2FieldInfo(dataAreaFieldName));
+					cloneTitleObj.put(CmnConst.ATTR_COLSPAN, 1);
+					cloneTitleObj.put(CmnConst.ATTR_ROWSPAN, 1);
+					JSONObject dataAreaFieldConfigObj = dataAreaFieldConfigMap.get(dataAreaFieldName);
+					cloneTitleObj.put(CmnConst.ATTR_SHOW_NAME, dataListReportService.getStatisticsDesc(dataAreaFieldConfigObj.getString(CmnConst.ATTR_STATISTICS), dataAreaFieldConfigObj.getString(CmnConst.ATTR_SHOW_NAME)));
+					groupAreaRangeTitleList.get(maxRow).add(cloneTitleObj);
+				}
+			} else {
+				if (value instanceof JSONObject) {
+					curTitleObj.put(CmnConst.ATTR_COLSPAN, getGroupAreaColCount((JSONObject) value, 0));
+					curTitleObj.put(CmnConst.ATTR_ROWSPAN, 1);
+					getGroupAreaRangeTitleList(dataAreaFieldConfigMap, (JSONObject) value, groupAreaRangeTitleList, curTitleObj, row + 1, maxRow, fieldName);
+				}
+			}
+		}
+	}
 
-    /**
-     * 鑾峰彇鎬昏html
-     * @param statisticsMap             缁熻map
-     * @param dataTitleList             鏁版嵁鏍囬list
-     * @param dataAreaFieldConfigMap    鏁版嵁鍖哄瓧娈电紦瀛榤ap
-     * @param dataAreaGroupFieldCount   鏁版嵁鍖哄垎缁勫瓧娈典釜鏁�
-     * @param dataAreaSubCnt            鏁版嵁鍖轰笅绾у垎缁勯」鏁�
-     * @param totalName                 鎬昏鍚嶇О
-     * @return
-     */
-    private StringBuilder getTotalStatisticsHtml(Map<JSONObject, JSONObject> statisticsMap, List<JSONObject> dataTitleList, Map<String, JSONObject> dataAreaFieldConfigMap, int dataAreaGroupFieldCount, int dataAreaSubCnt, String totalName) {
-        StringBuilder html = new StringBuilder(256);
-        html.append("\n<tr class=\"").append(CmnConst.CLASS_TR_DATA_STATISTICS).append("\">\n    ");
-        html.append("<td colspan=\"").append(dataAreaGroupFieldCount).append("\">").append(totalName).append("</td>");
-        JSONObject dataTitleObj;
-        JSONObject keyObj;
-        JSONObject dataAreaFieldConfigObj;
-        String statisticsType;
-        JSONObject valueObj;
-        String value;
-        int groupAreaSubCnt;
-        for (int i = 0;i < dataTitleList.size();i++) {
-            dataTitleObj = dataTitleList.get(i);
-            keyObj = dataListReportService.extendJSONObject(null, 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);
-                keyObj.remove(CmnConst.ATTR_GROUP_AREA_SUB_CNT);
-                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))) {
-                        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, dataTitleObj);
-                html.append(dataListReportService.getTdAttrByObj(keyObj));
-                // 鏍煎紡
-                value = dataListReportService.formatValue(dataAreaFieldConfigObj, value);
-            }
-            html.append(">").append(value == null ? "" : value).append("</td>");
-        }
-        html.append("\n</tr>");
-        return html;
-    }
+	/**
+	 * 鑾峰彇涓嬬骇鍒嗙粍椤规暟
+	 *
+	 * @param obj 寰呮搷浣滅殑obj
+	 * @return 涓嬬骇鍒嗙粍椤规暟
+	 */
+	private int getSubCnt(JSONObject obj) {
+		int count = 0;
+		List<String> statisticsFieldList = dataListReportService.transfer2List(obj.get(CmnConst.ATTR_STATISTICS_FIELD));
+		for (String key : obj.keySet()) {
+			if (CmnConst.ATTR_FIELD_INFO.equals(key) || CmnConst.ATTR_STATISTICS_FIELD.equals(key) || statisticsFieldList.contains(key)) {
+				continue;
+			}
+			count++;
+		}
+		return count;
+	}
 
-    /**
-     * 鑾峰彇缁熻鏂瑰紡涓衡�滄渶缁堢粺璁♀�濈殑鍊�
-     * @param keyObj
-     * @param dataAreaFieldConfigObj
-     * @param statisticsMap
-     * @return
-     */
-    private String getFinalValue(JSONObject keyObj, JSONObject dataAreaFieldConfigObj, Map<JSONObject, JSONObject> statisticsMap) {
-        JSONObject valueObj;
-        String value;
-        if (CmnConst.ATTR_STATISTICS_FINAL_STATISTICS.equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_STATISTICS))
-                && "1".equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_IS_CUSTOM_FIELD)) && !StringUtils.isEmpty(dataAreaFieldConfigObj.getString(CmnConst.ATTR_FORMULA))) {
-            // 缁熻鏂瑰紡涓衡�滄渶缁堢粺璁♀��
-            String formula = dataAreaFieldConfigObj.getString(CmnConst.ATTR_FORMULA);
-            List<String> suitList = dataListReportService.getSuitContent(formula, "\\{#((?!\\{).)+#\\}");
-            JSONObject tempObj = (JSONObject) keyObj.clone();
-            for (String suitContent : suitList) {
-                tempObj.put(CmnConst.ATTR_FIELD_INFO, suitContent);
-                valueObj = statisticsMap.get(tempObj);
-                formula = formula.replace(suitContent, (valueObj == null || valueObj.getString(CmnConst.ATTR_FINAL_VALUE) == null ? "0" : valueObj.getString(CmnConst.ATTR_FINAL_VALUE)) + "d");
-            }
-            try {
-                value = BaseUtil.executeExpression(formula.replace("/0", "/1").replaceAll("\\/\\{#[\\w]+#}", "/1").replaceAll("\\{#[\\w]+#}", "0"), Maps.newHashMap()).toString();
-            } catch (Exception e) {
-                SpringMVCContextHolder.getSystemLogger().error(e);
-                value = "";
-            }
-        } else {
-            value = "";
-        }
-        return value;
-    }
+	/**
+	 * 鑾峰彇鍐呭html
+	 *
+	 * @param dataTitleList              鏁版嵁鏍囬list
+	 * @param dataAreaFieldRecordObj     鏁版嵁鍖哄瓧娈佃褰昽bj
+	 * @param statisticsMap              缁熻map
+	 * @param totalName                  鎬昏鍚嶇О锛岄潪绌�-闇�瑕佹�昏
+	 * @param dataAreaGroupFieldNameList 鏁版嵁鍖哄垎缁勫瓧娈靛悕绉發ist
+	 * @param dataAreaFieldConfigMap     鏁版嵁鍖哄瓧娈电紦瀛榤ap
+	 * @return 涓氬姟鏁版嵁鍐呭html
+	 */
+	private StringBuilder getDataAreaDataHtml(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);
 
-    /**
-     * 鑾峰彇琛屽垪涓ょ涓嶅悓鐨勪笅绾у垎缁勫钩鍧囧��
-     * @param dataAreaSubCnt            鎸夌収鏁版嵁鍖哄垎缁勭殑涓嬬骇鍒嗙粍椤规暟
-     * @param groupAreaSubCnt           鎸夌収鍒嗙粍琛ㄥご鍘诲垎缁勭殑涓嬬骇鍒嗙粍椤规暟
-     * @param curFieldStatisticsObj     褰撳墠瀛楁缁熻obj
-     * @param dataAreaFieldConfigObj    褰撳墠鏁版嵁鍖哄瓧娈电紦瀛榦bj
-     * @param statisticsType            缁熻绫诲瀷
-     * @return                          鎸夌収涓嬬骇鍒嗙粍椤硅繘琛屽钩鍧囩殑琛屽垪骞冲潎鍊�
-     */
-    private String getTwoTypesGroupAvgStatisticsValue(int dataAreaSubCnt, int groupAreaSubCnt, JSONObject curFieldStatisticsObj, JSONObject dataAreaFieldConfigObj, String statisticsType) {
-        // 鍒椾笅绾у垎缁�
-        StringBuilder value = new StringBuilder(32);
-        String dataAreaValue = getGroupAreaGroupAvgStatisticsValue(dataAreaSubCnt, curFieldStatisticsObj, dataAreaFieldConfigObj, statisticsType, CmnConst.ATTR_STATISTICS_DATA_AREA_AVG, dataAreaSubCnt == 0);
-        String groupAreaValue = getGroupAreaGroupAvgStatisticsValue(groupAreaSubCnt, curFieldStatisticsObj, dataAreaFieldConfigObj, statisticsType, CmnConst.ATTR_STATISTICS_GROUP_AREA_AVG, groupAreaSubCnt == 0);
+		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);
+		}
 
-        if (dataAreaSubCnt > 0) {
-            value.append(dataAreaValue);
-        }
-        if (dataAreaSubCnt > 0 && groupAreaSubCnt > 0) {
-            value.append("\\");
-        }
-        if (groupAreaSubCnt > 0) {
-            value.append(groupAreaValue);
-        }
-        return value.toString();
-    }
+		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>");
+		}
 
-    /**
-     * 鑾峰彇鎸囧畾绫诲瀷鐨勪笅绾у垎缁勫钩鍧囧��
-     * @param subCnt                    涓嬬骇鍒嗙粍椤规暟
-     * @param curFieldStatisticsObj     褰撳墠瀛楁缁熻obj
-     * @param dataAreaFieldConfigObj    褰撳墠鏁版嵁鍖哄瓧娈电紦瀛榦bj
-     * @param statisticsType            缁熻绫诲瀷
-     * @param avgType                   CmnConst.ATTR_STATISTICS_DATA_AREA_AVG-琛岋紱CmnConst.ATTR_STATISTICS_GROUP_AREA_AVG-鍒�
-     * @return                          鎸夌収涓嬬骇鍒嗙粍椤硅繘琛屽钩鍧囩殑骞冲潎鍊�
-     */
-    private String getGroupAreaGroupAvgStatisticsValue(int subCnt, JSONObject curFieldStatisticsObj, JSONObject dataAreaFieldConfigObj, String statisticsType, String avgType, boolean lastStage) {
-        String value;
-        if (subCnt > 0) {
-            curFieldStatisticsObj.put(CmnConst.ATTR_STATISTICS_SUB_CNT, subCnt);
-            dataListReportService.getAvgValue(curFieldStatisticsObj, dataAreaFieldConfigObj, lastStage);
-            value = curFieldStatisticsObj.getString(statisticsType);
-            curFieldStatisticsObj.put(avgType, value);
-        } else {
-            value = curFieldStatisticsObj.getString(statisticsType);
-        }
-        return value == null ? "" : value;
-    }
+		// 鎬昏
+		if (!StringUtils.isEmpty(totalName)) {
+			html.append(getTotalStatisticsHtml(statisticsMap, dataTitleList, dataAreaFieldConfigMap, dataAreaGroupFieldNameList.size(), getSubCnt(dataAreaFieldRecordObj), totalName));
+		}
+
+		return html;
+	}
+
+	/**
+	 * 鑾峰彇鍐呭html
+	 *
+	 * @param dataTitleList              鏁版嵁鏍囬list
+	 * @param dataAreaFieldRecordObj     鏁版嵁鍖哄瓧娈佃褰昽bj
+	 * @param statisticsMap              缁熻map
+	 * @param totalName                  鎬昏鍚嶇О锛岄潪绌�-闇�瑕佹�昏
+	 * @param dataAreaGroupFieldNameList 鏁版嵁鍖哄垎缁勫瓧娈靛悕绉發ist
+	 * @param dataAreaFieldConfigMap     鏁版嵁鍖哄瓧娈电紦瀛榤ap
+	 * @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;
+	}
+
+	/**
+	 * 鑾峰彇鏁版嵁鍖哄垎缁勫瓧娈垫暟鎹甽ist
+	 *
+	 * @param curOperateObj              褰撳墠鎿嶄綔obj
+	 * @param dataAreaGroupFieldDataList 鏁版嵁鍖哄垎缁勫瓧娈垫暟鎹甽ist
+	 * @param preObj                     鏈�杩戞搷浣滅殑obj
+	 * @param row                        褰撳墠琛屾暟
+	 * @param maxCol                     鏈�澶у垪鏁�
+	 * @return 鏁版嵁鍖哄垎缁勫瓧娈垫暟鎹甽ist
+	 */
+	private int getDataAreaGroupFieldDataList(JSONObject curOperateObj, List<List<JSONObject>> dataAreaGroupFieldDataList, JSONObject preObj, int row, int col, int maxCol, String parentFieldName) {
+		String key;
+		Object value;
+		JSONObject curObj;
+		JSONObject topLeftCornerObj;
+		String dataAreaFieldName = dataListReportService.fieldInfo2FieldName(curOperateObj.getString(CmnConst.ATTR_FIELD_INFO));
+		List<String> statisticsFieldList = dataListReportService.transfer2List(curOperateObj.get(CmnConst.ATTR_STATISTICS_FIELD));
+		String realValue = curOperateObj.getString(CmnConst.ATTR_REAL_VALUE);
+		JSONObject objValue;
+		String newKey;
+		List<JSONObject> curRowList;
+		JSONObject realValueObj;
+		for (Map.Entry<String, Object> entry : curOperateObj.entrySet()) {
+			curObj = dataListReportService.extendJSONObject(null, preObj, null);
+			key = entry.getKey();
+			if (CmnConst.ATTR_FIELD_INFO.equals(key) || CmnConst.ATTR_STATISTICS_FIELD.equals(key) || CmnConst.ATTR_REAL_VALUE.equals(key)) {
+				continue;
+			}
+			value = entry.getValue();
+			if (value == null) {
+				continue;
+			}
+			if (!StringUtils.isEmpty(realValue) && !StringUtils.isEmpty(parentFieldName)) {
+				if (curObj.get(CmnConst.ATTR_REAL_VALUE) == null) {
+					realValueObj = new JSONObject();
+					curObj.put(CmnConst.ATTR_REAL_VALUE, realValueObj);
+				} else {
+					realValueObj = (JSONObject) curObj.get(CmnConst.ATTR_REAL_VALUE);
+				}
+				realValueObj.put(parentFieldName, realValue);
+			}
+			if (dataAreaGroupFieldDataList.size() < row) {
+				curRowList = Lists.newArrayList();
+				dataAreaGroupFieldDataList.add(curRowList);
+			} else {
+				curRowList = dataAreaGroupFieldDataList.get(row - 1);
+			}
+			if (curRowList.size() < col - 1) {
+				for (int i = 0; i < col - 1; i++) {
+					curRowList.add(new JSONObject());
+				}
+			}
+			curObj.put(CmnConst.ATTR_SHOW_NAME, key);
+			if (statisticsFieldList.contains(key)) {
+				curObj.put(CmnConst.ATTR_IS_STATISTICS_FIELD, "1");
+				newKey = key.replace(CmnConst.STATISTICS_NAME, "");
+				curObj.put(dataAreaFieldName, newKey);
+				curObj.put(CmnConst.ATTR_DATA_AREA_SUB_CNT, getSubCnt(curOperateObj.getJSONObject(newKey)));
+			} else {
+				curObj.put(dataAreaFieldName, key);
+			}
+			curObj.put(CmnConst.ATTR_ROWSPAN, 1);
+			curObj.put(CmnConst.ATTR_COLSPAN, 1);
+			curRowList.add(curObj);
+			if (value instanceof JSONObject) {
+				objValue = (JSONObject) value;
+				if (objValue.isEmpty()) {
+					curObj.put(CmnConst.ATTR_COLSPAN, maxCol - col + 1);
+					if (row > 1 && col > 1) {
+						int emptyCount = 0;
+						for (JSONObject obj : curRowList) {
+							if (obj.isEmpty()) {
+								emptyCount++;
+							} else {
+								break;
+							}
+						}
+						for (int j = 0; j < emptyCount; j++) {
+							int curRow = row - 2;
+							topLeftCornerObj = dataAreaGroupFieldDataList.get(curRow).get(j);
+							while (topLeftCornerObj.isEmpty() && curRow > 0) {
+								curRow--;
+								topLeftCornerObj = dataAreaGroupFieldDataList.get(curRow).get(j);
+							}
+							topLeftCornerObj.put(CmnConst.ATTR_ROWSPAN, topLeftCornerObj.getIntValue(CmnConst.ATTR_ROWSPAN) + 1);
+						}
+					}
+					row++;
+					continue;
+				}
+				if (objValue.size() == 1 && objValue.containsKey(CmnConst.ATTR_REAL_VALUE)) {
+					row++;
+					continue;
+				}
+				row = getDataAreaGroupFieldDataList(objValue, dataAreaGroupFieldDataList, curObj, row, col + 1, maxCol, dataAreaFieldName);
+			}
+		}
+		return row;
+	}
+
+	/**
+	 * 鑾峰彇鎬昏html
+	 *
+	 * @param statisticsMap           缁熻map
+	 * @param dataTitleList           鏁版嵁鏍囬list
+	 * @param dataAreaFieldConfigMap  鏁版嵁鍖哄瓧娈电紦瀛榤ap
+	 * @param dataAreaGroupFieldCount 鏁版嵁鍖哄垎缁勫瓧娈典釜鏁�
+	 * @param dataAreaSubCnt          鏁版嵁鍖轰笅绾у垎缁勯」鏁�
+	 * @param totalName               鎬昏鍚嶇О
+	 * @return
+	 */
+	private StringBuilder getTotalStatisticsHtml(Map<JSONObject, JSONObject> statisticsMap, List<JSONObject> dataTitleList, Map<String, JSONObject> dataAreaFieldConfigMap, int dataAreaGroupFieldCount, int dataAreaSubCnt, String totalName) {
+		StringBuilder html = new StringBuilder(256);
+		html.append("\n<tr class=\"").append(CmnConst.CLASS_TR_DATA_STATISTICS).append("\">\n    ");
+		html.append("<td colspan=\"").append(dataAreaGroupFieldCount).append("\">").append(totalName).append("</td>");
+		JSONObject dataTitleObj;
+		JSONObject keyObj;
+		JSONObject dataAreaFieldConfigObj;
+		String statisticsType;
+		JSONObject valueObj;
+		String value;
+		int groupAreaSubCnt;
+		for (int i = 0; i < dataTitleList.size(); i++) {
+			dataTitleObj = dataTitleList.get(i);
+			keyObj = dataListReportService.extendJSONObject(null, 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);
+				keyObj.remove(CmnConst.ATTR_GROUP_AREA_SUB_CNT);
+				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))) {
+						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, dataTitleObj);
+				html.append(dataListReportService.getTdAttrByObj(keyObj));
+				// 鏍煎紡
+				value = dataListReportService.formatValue(dataAreaFieldConfigObj, value);
+			}
+			html.append(">").append(value == null ? "" : value).append("</td>");
+		}
+		html.append("\n</tr>");
+		return html;
+	}
+
+	/**
+	 * 鑾峰彇缁熻鏂瑰紡涓衡�滄渶缁堢粺璁♀�濈殑鍊�
+	 *
+	 * @param keyObj
+	 * @param dataAreaFieldConfigObj
+	 * @param statisticsMap
+	 * @return
+	 */
+	private String getFinalValue(JSONObject keyObj, JSONObject dataAreaFieldConfigObj, Map<JSONObject, JSONObject> statisticsMap) {
+		JSONObject valueObj;
+		String value;
+		if (CmnConst.ATTR_STATISTICS_FINAL_STATISTICS.equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_STATISTICS))
+				&& "1".equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_IS_CUSTOM_FIELD)) && !StringUtils.isEmpty(dataAreaFieldConfigObj.getString(CmnConst.ATTR_FORMULA))) {
+			// 缁熻鏂瑰紡涓衡�滄渶缁堢粺璁♀��
+			String formula = dataAreaFieldConfigObj.getString(CmnConst.ATTR_FORMULA);
+			List<String> suitList = dataListReportService.getSuitContent(formula, "\\{#((?!\\{).)+#\\}");
+			JSONObject tempObj = (JSONObject) keyObj.clone();
+			for (String suitContent : suitList) {
+				tempObj.put(CmnConst.ATTR_FIELD_INFO, suitContent);
+				valueObj = statisticsMap.get(tempObj);
+				formula = formula.replace(suitContent, (valueObj == null || valueObj.getString(CmnConst.ATTR_FINAL_VALUE) == null ? "0" : valueObj.getString(CmnConst.ATTR_FINAL_VALUE)) + "d");
+			}
+			try {
+				value = BaseUtil.executeExpression(formula.replace("/0", "/1").replaceAll("\\/\\{#[\\w]+#}", "/1").replaceAll("\\{#[\\w]+#}", "0"), Maps.newHashMap()).toString();
+			} catch (Exception e) {
+				SpringMVCContextHolder.getSystemLogger().error(e);
+				value = "";
+			}
+		} else {
+			value = "";
+		}
+		return value;
+	}
+
+	/**
+	 * 鑾峰彇琛屽垪涓ょ涓嶅悓鐨勪笅绾у垎缁勫钩鍧囧��
+	 *
+	 * @param dataAreaSubCnt         鎸夌収鏁版嵁鍖哄垎缁勭殑涓嬬骇鍒嗙粍椤规暟
+	 * @param groupAreaSubCnt        鎸夌収鍒嗙粍琛ㄥご鍘诲垎缁勭殑涓嬬骇鍒嗙粍椤规暟
+	 * @param curFieldStatisticsObj  褰撳墠瀛楁缁熻obj
+	 * @param dataAreaFieldConfigObj 褰撳墠鏁版嵁鍖哄瓧娈电紦瀛榦bj
+	 * @param statisticsType         缁熻绫诲瀷
+	 * @return 鎸夌収涓嬬骇鍒嗙粍椤硅繘琛屽钩鍧囩殑琛屽垪骞冲潎鍊�
+	 */
+	private String getTwoTypesGroupAvgStatisticsValue(int dataAreaSubCnt, int groupAreaSubCnt, JSONObject curFieldStatisticsObj, JSONObject dataAreaFieldConfigObj, String statisticsType) {
+		// 鍒椾笅绾у垎缁�
+		StringBuilder value = new StringBuilder(32);
+		String dataAreaValue = getGroupAreaGroupAvgStatisticsValue(dataAreaSubCnt, curFieldStatisticsObj, dataAreaFieldConfigObj, statisticsType, CmnConst.ATTR_STATISTICS_DATA_AREA_AVG, dataAreaSubCnt == 0);
+		String groupAreaValue = getGroupAreaGroupAvgStatisticsValue(groupAreaSubCnt, curFieldStatisticsObj, dataAreaFieldConfigObj, statisticsType, CmnConst.ATTR_STATISTICS_GROUP_AREA_AVG, groupAreaSubCnt == 0);
+
+		if (dataAreaSubCnt > 0) {
+			value.append(dataAreaValue);
+		}
+		if (dataAreaSubCnt > 0 && groupAreaSubCnt > 0) {
+			value.append("\\");
+		}
+		if (groupAreaSubCnt > 0) {
+			value.append(groupAreaValue);
+		}
+		return value.toString();
+	}
+
+	/**
+	 * 鑾峰彇鎸囧畾绫诲瀷鐨勪笅绾у垎缁勫钩鍧囧��
+	 *
+	 * @param subCnt                 涓嬬骇鍒嗙粍椤规暟
+	 * @param curFieldStatisticsObj  褰撳墠瀛楁缁熻obj
+	 * @param dataAreaFieldConfigObj 褰撳墠鏁版嵁鍖哄瓧娈电紦瀛榦bj
+	 * @param statisticsType         缁熻绫诲瀷
+	 * @param avgType                CmnConst.ATTR_STATISTICS_DATA_AREA_AVG-琛岋紱CmnConst.ATTR_STATISTICS_GROUP_AREA_AVG-鍒�
+	 * @return 鎸夌収涓嬬骇鍒嗙粍椤硅繘琛屽钩鍧囩殑骞冲潎鍊�
+	 */
+	private String getGroupAreaGroupAvgStatisticsValue(int subCnt, JSONObject curFieldStatisticsObj, JSONObject dataAreaFieldConfigObj, String statisticsType, String avgType, boolean lastStage) {
+		String value;
+		if (subCnt > 0) {
+			curFieldStatisticsObj.put(CmnConst.ATTR_STATISTICS_SUB_CNT, subCnt);
+			dataListReportService.getAvgValue(curFieldStatisticsObj, dataAreaFieldConfigObj, lastStage);
+			value = curFieldStatisticsObj.getString(statisticsType);
+			curFieldStatisticsObj.put(avgType, value);
+		} else {
+			value = curFieldStatisticsObj.getString(statisticsType);
+		}
+		return value == null ? "" : value;
+	}
 }

--
Gitblit v1.9.2