package com.product.server.report.service; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.NumberUtil; import com.alibaba.fastjson.JSONObject; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; import com.product.common.lang.StringUtils; import com.product.core.entity.DataTableEntity; import com.product.core.entity.FieldSetEntity; 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.server.report.entity.ReportEntity; import com.product.util.BaseUtil; import com.product.util.SystemParamReplace; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.util.*; /** * Copyright © 6c * * @Date: 2021-05-11 15:41 * @Author: 6c * @Description: */ @Component public class CommonReportService extends AbstractBaseService { @Autowired private DataListReportService dataListReportService; /** * 报表-解析 * * @param recordDte 业务数据dte * @param totalStatisticsFlag 是否合计标识 * @param reportConfigMap 报表配置缓存map * @param tableStyle * @return */ public ReportEntity getReportEntity(DataTableEntity recordDte, String totalName, Map> reportConfigMap) { ReportEntity report = null; Map> headAndTailTitleDataMap = Maps.newHashMap(); // 数据区 report = getDataArea(reportConfigMap, headAndTailTitleDataMap, recordDte, totalName); int totalColCount = reportConfigMap.get(0).size(); // 头部标题区 List> headTitleRows = null; if (!reportConfigMap.get(1).isEmpty()) { headTitleRows = dataListReportService.getTitle(reportConfigMap.get(1), totalColCount, headAndTailTitleDataMap, "head"); } // 底部标题区 List> tailTitleRows = null; if (!reportConfigMap.get(3).isEmpty()) { tailTitleRows = dataListReportService.getTitle(reportConfigMap.get(3), totalColCount, headAndTailTitleDataMap, "tail"); } if (!CollectionUtil.isEmpty(headTitleRows)) { List> reportHeader = report.getReportHeader(); headTitleRows.addAll(reportHeader); report.setReportHeader(headTitleRows); } if (!CollectionUtil.isEmpty(tailTitleRows)) { report.setReportTail(tailTitleRows); } return report; } /** * 报表-解析 * * @param recordDte 业务数据dte * @param totalStatisticsFlag 是否合计标识 * @param reportConfigMap 报表配置缓存map * @param tableStyle * @return */ public JSONObject getReport(DataTableEntity recordDte, String totalName, Map> reportConfigMap, StringBuilder tableStyle) { StringBuilder reportHtml = new StringBuilder(4096); // css StringBuilder cssHtml = dataListReportService.getCssHtml(); // 数据区 Map> headAndTailTitleDataMap = Maps.newHashMap(); String dataAreaHtml = getDataAreaHtml(reportConfigMap, headAndTailTitleDataMap, recordDte, totalName); int totalColCount = reportConfigMap.get(0).size(); // 头部标题区 StringBuilder headTitleHtml = null; if (!reportConfigMap.get(1).isEmpty()) { headTitleHtml = dataListReportService.getTitleHtml(reportConfigMap.get(1), totalColCount, headAndTailTitleDataMap, "head"); } // 底部标题区 StringBuilder tailTitleHtml = null; if (!reportConfigMap.get(3).isEmpty()) { tailTitleHtml = dataListReportService.getTitleHtml(reportConfigMap.get(3), totalColCount, headAndTailTitleDataMap, "tail"); } reportHtml.append("\n\n") .append(cssHtml) .append(headTitleHtml == null ? "" : headTitleHtml) .append(dataAreaHtml) .append(tailTitleHtml == null ? "" : tailTitleHtml) .append("\n
\n"); 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; } /** * 获取报表数据区html * * @param reportConfigMap 报表缓存map * @param headAndTailTitleDataMap 头部、尾部标题区数据字段map * @param recordDte 业务数据集合 * @param totalName 总计名称,非空-需要总计 * @return */ private String getDataAreaHtml(Map> reportConfigMap, Map> headAndTailTitleDataMap, DataTableEntity recordDte, String totalName) { // 数据区字段缓存map Map dataAreaFieldConfigMap = dataListReportService.groupAndDataJSONObject2Map(reportConfigMap.get(0)); // 获取指定数据集中包含的数据区字段集合 Set headAndTailFieldSet = Sets.newHashSet(); headAndTailFieldSet.addAll(dataListReportService.getDataFields(reportConfigMap.get(1))); headAndTailFieldSet.addAll(dataListReportService.getDataFields(reportConfigMap.get(3))); // 统计map Map statisticsMap = Maps.newLinkedHashMap(); StringBuilder dataAreaHtml = new StringBuilder(1024); // 标题 dataAreaHtml.append(getDataAreaTitleHtml(dataAreaFieldConfigMap)); // 内容 dataAreaHtml.append(getDataAreaDataHtml(dataAreaFieldConfigMap, recordDte, headAndTailTitleDataMap, headAndTailFieldSet, statisticsMap, totalName)); return dataAreaHtml.toString(); } private ReportEntity getDataArea(Map> reportConfigMap, Map> headAndTailTitleDataMap, DataTableEntity recordDte, String totalName) { // 数据区字段缓存map Map dataAreaFieldConfigMap = dataListReportService.groupAndDataJSONObject2Map(reportConfigMap.get(0)); // 获取指定数据集中包含的数据区字段集合 Set headAndTailFieldSet = Sets.newHashSet(); headAndTailFieldSet.addAll(dataListReportService.getDataFields(reportConfigMap.get(1))); headAndTailFieldSet.addAll(dataListReportService.getDataFields(reportConfigMap.get(3))); // 统计map Map statisticsMap = Maps.newLinkedHashMap(); List reportHeader = getReportHeader(dataAreaFieldConfigMap); List> reportData = getReportData(dataAreaFieldConfigMap, recordDte, headAndTailTitleDataMap, headAndTailFieldSet, statisticsMap, totalName); ReportEntity report = new ReportEntity(); report.addReportHeader(reportHeader); report.setReportData(reportData); return report; } private List getReportHeader(Map dataAreaFieldConfigMap) { if (CollectionUtil.isEmpty(dataAreaFieldConfigMap)) { return null; } List reportColumnList = new ArrayList<>(); dataAreaFieldConfigMap.forEach((k, v) -> { ReportColumn column = new ReportColumn(); column.setContent(v.getString(CmnConst.ATTR_SHOW_NAME)); column.setColumnWidth(NumberUtil.isNumber(v.getString(CmnConst.ATTR_WIDTH)) ? NumberUtil.parseInt(v.getString(CmnConst.ATTR_WIDTH)) : 0); reportColumnList.add(column); }); return reportColumnList; } private List> getReportData(Map dataAreaFieldConfigMap, DataTableEntity recordDte, Map> headAndTailTitleDataMap, Set headAndTailFieldSet, Map statisticsMap, String totalName) { List> reportData = new ArrayList<>(); // 数据区分组统计字段名称list List dataAreaGroupStatisticsFieldNameList = Lists.newArrayList(); // 数据区分组字段名称list List dataAreaGroupFieldNameList = Lists.newArrayList(); dataAreaFieldConfigMap.forEach((dataAreaFieldName, dataAreaFieldConfigObj) -> { if ("1".equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_IS_GROUP))) { dataAreaGroupFieldNameList.add(dataAreaFieldName); if ("1".equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_IS_STATISTICS))) { dataAreaGroupStatisticsFieldNameList.add(dataAreaFieldName); } } }); FieldSetEntity recordFse; FieldSetEntity preFse = null; String dataAreaFieldName; JSONObject dataAreaFieldConfigObj; String value; JSONObject keyObj; Map replaceMap = Maps.newHashMap(); Map dataAreaClosestGroupStatisticsFieldValueMap = Maps.newHashMap(); Map dataAreaClosestGroupFieldValueMap = Maps.newHashMap(); String closestGroupStatisticsFieldName = null; String closestGroupFieldName = null; String tempFieldName; String paramKey; boolean combineFlag; JSONObject dataAreaGroupFieldRecordObj = new JSONObject(); for (int i = 0; i < recordDte.getRows(); i++) { recordFse = recordDte.getFieldSetEntity(i); // 获取头部、尾部标题区数据字段 dataListReportService.getHeadAndTailTitleDataMap(headAndTailTitleDataMap, headAndTailFieldSet, recordFse); combineFlag = true; List columns = new ArrayList<>(); for (Map.Entry entry : dataAreaFieldConfigMap.entrySet()) { ReportColumn column = new ReportColumn(); dataAreaFieldName = entry.getKey(); dataAreaFieldConfigObj = entry.getValue(); value = dataListReportService.getValue(dataAreaFieldConfigObj, recordFse, dataAreaFieldName); // 若是自定义字段,则放入业务数据记录中 if ("1".equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_IS_CUSTOM_FIELD))) { recordFse.setValue(dataAreaFieldName, value); } if (dataAreaGroupFieldNameList.contains(dataAreaFieldName)) { int curFieldIndex = dataAreaGroupFieldNameList.indexOf(dataAreaFieldName); // 记录分组字段 recordDataAreaGroupField(dataAreaGroupFieldRecordObj, dataAreaGroupFieldNameList, curFieldIndex, recordFse); // 分组合字段并 closestGroupFieldName = dataAreaFieldName; if (preFse != null && combineFlag) { if (value.equals(dataAreaClosestGroupFieldValueMap.get(closestGroupFieldName))) { dealReplaceMapAddRowspan(replaceMap, dataAreaGroupFieldNameList.subList(0, curFieldIndex + 1), preFse, true); continue; } else { combineFlag = false; } } dataAreaClosestGroupFieldValueMap.put(dataAreaFieldName, value); } // 分组统计 if (dataAreaGroupStatisticsFieldNameList.contains(dataAreaFieldName)) { int minK = dataAreaGroupStatisticsFieldNameList.size(); for (int j = 0; j < dataAreaGroupStatisticsFieldNameList.size(); j++) { tempFieldName = dataAreaGroupStatisticsFieldNameList.get(j); if (!StringUtils.isEmpty(dataAreaClosestGroupStatisticsFieldValueMap.get(tempFieldName)) && !recordFse.getString(tempFieldName).equals(dataAreaClosestGroupStatisticsFieldValueMap.get(tempFieldName))) { minK = j; break; } } for (int k = dataAreaGroupStatisticsFieldNameList.size() - 1; k >= minK; k--) { tempFieldName = dataAreaGroupStatisticsFieldNameList.get(k); if (preFse != null && dataAreaClosestGroupStatisticsFieldValueMap.get(tempFieldName) != null) { reportData.add(getDataAreaGroupStatisticsFieldStatisticsRow(dataAreaClosestGroupStatisticsFieldValueMap.get(tempFieldName), statisticsMap, dataAreaFieldConfigMap, tempFieldName, preFse, dataAreaGroupFieldNameList, replaceMap, dataAreaGroupFieldRecordObj)); dataAreaClosestGroupStatisticsFieldValueMap.remove(tempFieldName); } } closestGroupStatisticsFieldName = dataAreaFieldName; dataAreaClosestGroupStatisticsFieldValueMap.put(dataAreaFieldName, value); } // 非分组统计字段(普通+自定义) if (!"1".equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_IS_GROUP)) && !StringUtils.isEmpty(dataAreaFieldConfigObj.getString(CmnConst.ATTR_STATISTICS))) { addStatisticsRowInfo(statisticsMap, dataAreaGroupStatisticsFieldNameList, recordFse, dataAreaFieldConfigObj, dataAreaFieldName, value); } // 自定义统计字段(未指定统计类型,使用基础字段公式进行计算) if ("1".equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_IS_CUSTOM_FIELD)) && StringUtils.isEmpty(dataAreaFieldConfigObj.getString(CmnConst.ATTR_STATISTICS)) && !StringUtils.isEmpty(dataAreaFieldConfigObj.getString(CmnConst.ATTR_FORMULA))) { String formula = dataAreaFieldConfigObj.getString(CmnConst.ATTR_FORMULA); List formFieldList = dataListReportService.getSuitContent(formula, CmnConst.REGEXP_FORM_FIELD); Map formulaMap = Maps.newHashMap(); boolean statisticsFlag = true; JSONObject tempObj; for (String formFieldInfo : formFieldList) { tempObj = dataAreaFieldConfigMap.get(dataListReportService.fieldInfo2FieldName(formFieldInfo)); if (tempObj == null || StringUtils.isEmpty(tempObj.getString(CmnConst.ATTR_STATISTICS))) { statisticsFlag = false; break; } formulaMap.put(formFieldInfo, tempObj.getString(CmnConst.ATTR_STATISTICS)); } if (statisticsFlag) { addStatisticsRowInfo(statisticsMap, dataAreaGroupStatisticsFieldNameList, recordFse, dataAreaFieldConfigObj, dataAreaFieldName, value, formulaMap); } } if ("1".equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_IS_GROUP))) { keyObj = new JSONObject(); for (String dataAreaGroupFieldName : dataAreaGroupFieldNameList) { keyObj.put(dataAreaGroupFieldName, recordFse.getString(dataAreaGroupFieldName)); if (dataAreaGroupFieldName.equals(dataAreaFieldName)) { keyObj.put(CmnConst.ATTR_FIELD_INFO, dataListReportService.fieldName2FieldInfo(dataAreaGroupFieldName)); break; } } paramKey = dataListReportService.concat(keyObj, CmnConst.ATTR_ROWSPAN); column.setRowspan(NumberUtil.parseInt(paramKey)); replaceMap.put(paramKey, "1"); } // class if (!StringUtils.isEmpty(dataAreaFieldConfigObj.getString(CmnConst.ATTR_URL))) { //子报表 String url = dataAreaFieldConfigObj.getString(CmnConst.ATTR_URL); url = SystemParamReplace.replaceParams(url, recordFse); column.setSubReport("true".equals(dataAreaFieldConfigObj.getString("~isSubReport~"))); if (!column.isSubReport()) { column.setPenetrate(true); column.setPenetrateProperty(url); } else { column.setSubReportProperty(url); } } String attrValue = recordFse.getString(dataAreaFieldName + CmnConst.PROMPT_REAL_VALUE_TAIL); if (StringUtils.isEmpty(attrValue)) { attrValue = recordFse.getString(dataAreaFieldName); } column.addProperty(dataAreaFieldName, attrValue); // 格式 value = dataListReportService.formatValue(dataAreaFieldConfigObj, value); column.setContent(value); columns.add(column); } reportData.add(columns); preFse = recordFse; } // 补全末尾统计 if (!StringUtils.isEmpty(closestGroupStatisticsFieldName)) { int maxK = -1; for (int j = 0; j < dataAreaGroupStatisticsFieldNameList.size(); j++) { tempFieldName = dataAreaGroupStatisticsFieldNameList.get(j); if (closestGroupStatisticsFieldName.equals(tempFieldName)) { maxK = j; } } for (int k = maxK; k >= 0; k--) { tempFieldName = dataAreaGroupStatisticsFieldNameList.get(k); if (preFse != null) { reportData.add(getDataAreaGroupStatisticsFieldStatisticsRow(dataAreaClosestGroupStatisticsFieldValueMap.get(tempFieldName), statisticsMap, dataAreaFieldConfigMap, tempFieldName, preFse, dataAreaGroupFieldNameList, replaceMap, dataAreaGroupFieldRecordObj)); } } } // 总计 if (!StringUtils.isEmpty(totalName)) { reportData.add(getDataAreaTotalStatistics(statisticsMap, dataAreaFieldConfigMap, dataAreaGroupFieldNameList, preFse, dataAreaGroupFieldRecordObj, totalName)); } for (Map.Entry entry : replaceMap.entrySet()) { reportData.stream().forEach(item -> { item.stream().forEach(column -> { column.replace(entry.getKey(), entry.getValue()); }); }); } return reportData; } /** * 获取总计行 * * @param statisticsMap 统计map * @param dataAreaFieldConfigMap 数据区字段缓存map * @param dataAreaGroupFieldNameList 数据区分组字段名称list * @param preFse 最近操作的数据fse * @param dataAreaGroupFieldRecordObj 数据区分组字段记录obj * @param totalName 总计名称 * @return */ private List getDataAreaTotalStatistics(Map statisticsMap, Map dataAreaFieldConfigMap, List dataAreaGroupFieldNameList, FieldSetEntity preFse, JSONObject dataAreaGroupFieldRecordObj, String totalName) { List columns = new ArrayList<>(); // StringBuilder html = new StringBuilder(512); String dataAreaFieldName; JSONObject dataAreaFieldConfigObj; String value; JSONObject keyObj = new JSONObject(); String statisticsType; // html.append("\n\n "); if (preFse == null) { return null; } int index = 0; for (Map.Entry entry : dataAreaFieldConfigMap.entrySet()) { ReportColumn column = new ReportColumn(); index++; dataAreaFieldName = entry.getKey(); if (!dataAreaGroupFieldNameList.contains(dataAreaFieldName)) { dataAreaFieldConfigObj = entry.getValue(); statisticsType = dataAreaFieldConfigObj.getString(CmnConst.ATTR_STATISTICS); keyObj.put(CmnConst.ATTR_FIELD_INFO, dataAreaFieldConfigObj.getString(CmnConst.ATTR_FIELD_INFO)); if ((!"1".equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_IS_CUSTOM_FIELD)) && StringUtils.isEmpty(statisticsType)) || statisticsMap.get(keyObj) == null) { value = ""; } else { JSONObject valueObj = statisticsMap.get(keyObj); if (StringUtils.isEmpty(statisticsType)) { statisticsType = CmnConst.ATTR_STATISTICS_DEFAULT; } if (CmnConst.ATTR_STATISTICS_AVG.equals(statisticsType) && "1".equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_AVG_TYPE))) { int subCnt = dataAreaGroupFieldRecordObj.size(); valueObj.put(CmnConst.ATTR_STATISTICS_SUB_CNT, subCnt); dataListReportService.getAvgValue(valueObj, dataAreaFieldConfigObj, false); } value = valueObj.getString(statisticsType); } // 格式 value = dataListReportService.formatValue(dataAreaFieldConfigObj, value); column.setContent(value); // html.append("").append(value == null ? "" : value).append(""); } else { if (index == 1) { column.setColspan(dataAreaGroupFieldNameList.size()); column.setContent(totalName); // html.append("").append(totalName).append(""); } } columns.add(column); } // html.append("\n"); return columns; } private List getDataAreaGroupStatisticsFieldStatisticsRow(String waitStatisticsValue, Map statisticsMap, Map dataAreaFieldConfigMap, String tempFieldName, FieldSetEntity recordFse, List dataAreaGroupFieldNameList, Map replaceMap, JSONObject dataAreaGroupFieldRecordObj) { List columns = new ArrayList<>(); // StringBuilder html = new StringBuilder(); // html.append("\n\n "); String dataAreaFieldName; JSONObject dataAreaFieldConfigObj; boolean flag = false; JSONObject keyObj = new JSONObject(); String value; String statisticsType; int index = 0; List needAddRowspanDataAreaGroupFieldNameList = Lists.newArrayList(); for (Map.Entry entry : dataAreaFieldConfigMap.entrySet()) { ReportColumn column = new ReportColumn(); index++; dataAreaFieldName = entry.getKey(); if (!flag) { if (dataAreaGroupFieldNameList.contains(dataAreaFieldName)) { keyObj.put(dataAreaFieldName, recordFse.getString(dataAreaFieldName)); if (dataAreaFieldName.equals(tempFieldName)) { column.setColspan(dataAreaGroupFieldNameList.size() - index + 1); column.setContent(waitStatisticsValue + CmnConst.STATISTICS_NAME); } if (!flag) { needAddRowspanDataAreaGroupFieldNameList.add(dataAreaFieldName); } } } else { dataAreaFieldConfigObj = entry.getValue(); statisticsType = dataAreaFieldConfigObj.getString(CmnConst.ATTR_STATISTICS); if (!"1".equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_IS_CUSTOM_FIELD)) && StringUtils.isEmpty(statisticsType)) { if (!"1".equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_IS_GROUP))) { // html.append(""); } } else { keyObj.put(CmnConst.ATTR_FIELD_INFO, dataListReportService.fieldName2FieldInfo(dataAreaFieldName)); if (statisticsMap.get(keyObj) == null) { value = ""; } else { JSONObject valueObj = statisticsMap.get(keyObj); if (StringUtils.isEmpty(statisticsType)) { statisticsType = CmnConst.ATTR_STATISTICS_DEFAULT; } if (CmnConst.ATTR_STATISTICS_AVG.equals(statisticsType) && "1".equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_AVG_TYPE))) { int subCnt = getAimSubCnt(keyObj, dataAreaGroupFieldNameList, dataAreaGroupFieldRecordObj); valueObj.put(CmnConst.ATTR_STATISTICS_SUB_CNT, subCnt); dataListReportService.getAvgValue(valueObj, dataAreaFieldConfigObj, false); } value = valueObj.getString(statisticsType); } // 格式 value = dataListReportService.formatValue(dataAreaFieldConfigObj, value); column.setContent(value); // html.append("").append(value == null ? "" : value).append(""); } } columns.add(column); } // html.append("\n"); dealReplaceMapAddRowspan(replaceMap, needAddRowspanDataAreaGroupFieldNameList, recordFse, false); return null; } /** * 获取标题 * * @param dataAreaFieldConfigMap 数据区字段缓存map * @return */ private StringBuilder getDataAreaTitleHtml(Map dataAreaFieldConfigMap) { StringBuilder html = new StringBuilder(256); html.append(""); dataAreaFieldConfigMap.forEach((dataAreaFieldName, dataAreaFieldConfigObj) -> { html.append("").append(dataListReportService.dealTdWidth(dataAreaFieldConfigObj, dataAreaFieldConfigObj.getString(CmnConst.ATTR_SHOW_NAME))).append(""); }); html.append(""); return html; } /** * 获取内容,包含统计 * * @param dataAreaFieldConfigMap 数据区字段缓存map * @param recordDte 业务数据集合 * @param headAndTailFieldSet 头部、尾部标题区字段set * @param statisticsMap 统计map * @param totalName 总计名称 * @return */ private String getDataAreaDataHtml(Map dataAreaFieldConfigMap, DataTableEntity recordDte, Map> headAndTailTitleDataMap, Set headAndTailFieldSet, Map statisticsMap, String totalName) { // 数据区分组统计字段名称list List dataAreaGroupStatisticsFieldNameList = Lists.newArrayList(); // 数据区分组字段名称list List dataAreaGroupFieldNameList = Lists.newArrayList(); dataAreaFieldConfigMap.forEach((dataAreaFieldName, dataAreaFieldConfigObj) -> { if ("1".equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_IS_GROUP))) { dataAreaGroupFieldNameList.add(dataAreaFieldName); if ("1".equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_IS_STATISTICS))) { dataAreaGroupStatisticsFieldNameList.add(dataAreaFieldName); } } }); StringBuilder dataAreaDataHtml = new StringBuilder(1024); StringBuilder curRowHtml = new StringBuilder(256); FieldSetEntity recordFse; FieldSetEntity preFse = null; String dataAreaFieldName; JSONObject dataAreaFieldConfigObj; String value; JSONObject keyObj; Map replaceMap = Maps.newHashMap(); Map dataAreaClosestGroupStatisticsFieldValueMap = Maps.newHashMap(); Map dataAreaClosestGroupFieldValueMap = Maps.newHashMap(); String closestGroupStatisticsFieldName = null; String closestGroupFieldName = null; String tempFieldName; String paramKey; boolean combineFlag; JSONObject dataAreaGroupFieldRecordObj = new JSONObject(); for (int i = 0; i < recordDte.getRows(); i++) { recordFse = recordDte.getFieldSetEntity(i); // 获取头部、尾部标题区数据字段 dataListReportService.getHeadAndTailTitleDataMap(headAndTailTitleDataMap, headAndTailFieldSet, recordFse); curRowHtml.setLength(0); String rowUuid = IdUtil.simpleUUID(); curRowHtml.append("\n\n "); combineFlag = true; for (Map.Entry entry : dataAreaFieldConfigMap.entrySet()) { dataAreaFieldName = entry.getKey(); dataAreaFieldConfigObj = entry.getValue(); value = dataListReportService.getValue(dataAreaFieldConfigObj, recordFse, dataAreaFieldName); // 若是自定义字段,则放入业务数据记录中 if ("1".equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_IS_CUSTOM_FIELD))) { recordFse.setValue(dataAreaFieldName, value); } if (dataAreaGroupFieldNameList.contains(dataAreaFieldName)) { int curFieldIndex = dataAreaGroupFieldNameList.indexOf(dataAreaFieldName); // 记录分组字段 recordDataAreaGroupField(dataAreaGroupFieldRecordObj, dataAreaGroupFieldNameList, curFieldIndex, recordFse); // 分组合字段并 closestGroupFieldName = dataAreaFieldName; if (preFse != null && combineFlag) { if (value.equals(dataAreaClosestGroupFieldValueMap.get(closestGroupFieldName))) { dealReplaceMapAddRowspan(replaceMap, dataAreaGroupFieldNameList.subList(0, curFieldIndex + 1), preFse, true); continue; } else { combineFlag = false; } } dataAreaClosestGroupFieldValueMap.put(dataAreaFieldName, value); } // 分组统计 if (dataAreaGroupStatisticsFieldNameList.contains(dataAreaFieldName)) { int minK = dataAreaGroupStatisticsFieldNameList.size(); for (int j = 0; j < dataAreaGroupStatisticsFieldNameList.size(); j++) { tempFieldName = dataAreaGroupStatisticsFieldNameList.get(j); if (!StringUtils.isEmpty(dataAreaClosestGroupStatisticsFieldValueMap.get(tempFieldName)) && !recordFse.getString(tempFieldName).equals(dataAreaClosestGroupStatisticsFieldValueMap.get(tempFieldName))) { minK = j; break; } } for (int k = dataAreaGroupStatisticsFieldNameList.size() - 1; k >= minK; k--) { tempFieldName = dataAreaGroupStatisticsFieldNameList.get(k); if (preFse != null && dataAreaClosestGroupStatisticsFieldValueMap.get(tempFieldName) != null) { dataAreaDataHtml.append(getDataAreaGroupStatisticsFieldStatisticsRowHtml(dataAreaClosestGroupStatisticsFieldValueMap.get(tempFieldName), statisticsMap, dataAreaFieldConfigMap, tempFieldName, preFse, dataAreaGroupFieldNameList, replaceMap, dataAreaGroupFieldRecordObj)); dataAreaClosestGroupStatisticsFieldValueMap.remove(tempFieldName); } } closestGroupStatisticsFieldName = dataAreaFieldName; dataAreaClosestGroupStatisticsFieldValueMap.put(dataAreaFieldName, value); } // 非分组统计字段(普通+自定义) if (!"1".equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_IS_GROUP)) && !StringUtils.isEmpty(dataAreaFieldConfigObj.getString(CmnConst.ATTR_STATISTICS))) { addStatisticsRowInfo(statisticsMap, dataAreaGroupStatisticsFieldNameList, recordFse, dataAreaFieldConfigObj, dataAreaFieldName, value); } // 自定义统计字段(未指定统计类型,使用基础字段公式进行计算) if ("1".equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_IS_CUSTOM_FIELD)) && StringUtils.isEmpty(dataAreaFieldConfigObj.getString(CmnConst.ATTR_STATISTICS)) && !StringUtils.isEmpty(dataAreaFieldConfigObj.getString(CmnConst.ATTR_FORMULA))) { String formula = dataAreaFieldConfigObj.getString(CmnConst.ATTR_FORMULA); List formFieldList = dataListReportService.getSuitContent(formula, CmnConst.REGEXP_FORM_FIELD); Map formulaMap = Maps.newHashMap(); boolean statisticsFlag = true; JSONObject tempObj; for (String formFieldInfo : formFieldList) { tempObj = dataAreaFieldConfigMap.get(dataListReportService.fieldInfo2FieldName(formFieldInfo)); if (tempObj == null || StringUtils.isEmpty(tempObj.getString(CmnConst.ATTR_STATISTICS))) { statisticsFlag = false; break; } formulaMap.put(formFieldInfo, tempObj.getString(CmnConst.ATTR_STATISTICS)); } if (statisticsFlag) { addStatisticsRowInfo(statisticsMap, dataAreaGroupStatisticsFieldNameList, recordFse, dataAreaFieldConfigObj, dataAreaFieldName, value, formulaMap); } } if ("1".equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_IS_GROUP))) { keyObj = new JSONObject(); for (String dataAreaGroupFieldName : dataAreaGroupFieldNameList) { keyObj.put(dataAreaGroupFieldName, recordFse.getString(dataAreaGroupFieldName)); if (dataAreaGroupFieldName.equals(dataAreaFieldName)) { keyObj.put(CmnConst.ATTR_FIELD_INFO, dataListReportService.fieldName2FieldInfo(dataAreaGroupFieldName)); break; } } paramKey = dataListReportService.concat(keyObj, CmnConst.ATTR_ROWSPAN); curRowHtml.append(""); // 格式 value = dataListReportService.formatValue(dataAreaFieldConfigObj, value); curRowHtml.append(value == null ? "" : value); curRowHtml.append(""); } curRowHtml.append("\n"); dataAreaDataHtml.append(curRowHtml); preFse = recordFse; } // 补全末尾统计 if (!StringUtils.isEmpty(closestGroupStatisticsFieldName)) { int maxK = -1; for (int j = 0; j < dataAreaGroupStatisticsFieldNameList.size(); j++) { tempFieldName = dataAreaGroupStatisticsFieldNameList.get(j); if (closestGroupStatisticsFieldName.equals(tempFieldName)) { maxK = j; } } for (int k = maxK; k >= 0; k--) { tempFieldName = dataAreaGroupStatisticsFieldNameList.get(k); if (preFse != null) { dataAreaDataHtml.append(getDataAreaGroupStatisticsFieldStatisticsRowHtml(dataAreaClosestGroupStatisticsFieldValueMap.get(tempFieldName), statisticsMap, dataAreaFieldConfigMap, tempFieldName, preFse, dataAreaGroupFieldNameList, replaceMap, dataAreaGroupFieldRecordObj)); } } } // 总计 if (!StringUtils.isEmpty(totalName)) { dataAreaDataHtml.append(getDataAreaTotalStatisticsHtml(statisticsMap, dataAreaFieldConfigMap, dataAreaGroupFieldNameList, preFse, dataAreaGroupFieldRecordObj, totalName)); } String str = dataAreaDataHtml.toString(); for (Map.Entry entry : replaceMap.entrySet()) { str = str.replace(entry.getKey(), entry.getValue()); } return str; } /** * 添加分组统计信息 * * @param statisticsMap 统计map * @param dataAreaGroupStatisticsFieldNameList 数据区分组统计字段名称list * @param recordFse 业务数据fse * @param dataAreaFieldConfigObj 数据区字段obj * @param dataAreaFieldName 数据区字段名称 * @param value 值 * @param formulaMap 公式map,字段info和统计类型的映射 */ private void addStatisticsRowInfo(Map statisticsMap, List dataAreaGroupStatisticsFieldNameList, FieldSetEntity recordFse, JSONObject dataAreaFieldConfigObj, String dataAreaFieldName, String value, Map formulaMap) { JSONObject keyObj = new JSONObject(); keyObj.put(CmnConst.ATTR_FIELD_INFO, dataListReportService.fieldName2FieldInfo(dataAreaFieldName)); String statisticsType = dataAreaFieldConfigObj.getString(CmnConst.ATTR_STATISTICS); if (StringUtils.isEmpty(statisticsType) && "1".equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_IS_STATISTICS))) { statisticsType = CmnConst.ATTR_STATISTICS_DEFAULT; } String statisticsValue; String formula = dataAreaFieldConfigObj.getString(CmnConst.ATTR_FORMULA); JSONObject formulaFieldKeyObj = new JSONObject(); // 总计 JSONObject cloneKeyObj = (JSONObject) keyObj.clone(); JSONObject valueObj = statisticsMap.computeIfAbsent(cloneKeyObj, k -> new JSONObject()); statisticsValue = getStatisticsValue(statisticsMap, formulaMap, formulaFieldKeyObj, formula, value); statisticsMap.put(keyObj, dataListReportService.getStatisticsValueObj(valueObj, dataAreaFieldConfigObj, statisticsValue, statisticsType, true)); // 分组统计 for (String dataAreaGroupStatisticsFieldName : dataAreaGroupStatisticsFieldNameList) { keyObj.put(dataAreaGroupStatisticsFieldName, recordFse.getString(dataAreaGroupStatisticsFieldName)); formulaFieldKeyObj.put(dataAreaGroupStatisticsFieldName, recordFse.getString(dataAreaGroupStatisticsFieldName)); cloneKeyObj = (JSONObject) keyObj.clone(); valueObj = statisticsMap.computeIfAbsent(cloneKeyObj, k -> new JSONObject()); statisticsValue = getStatisticsValue(statisticsMap, formulaMap, formulaFieldKeyObj, formula, value); statisticsMap.put(keyObj, dataListReportService.getStatisticsValueObj(valueObj, dataAreaFieldConfigObj, statisticsValue, statisticsType, true)); } } private void addStatisticsRowInfo(Map statisticsMap, List dataAreaGroupStatisticsFieldNameList, FieldSetEntity recordFse, JSONObject dataAreaFieldConfigObj, String dataAreaFieldName, String value) { addStatisticsRowInfo(statisticsMap, dataAreaGroupStatisticsFieldNameList, recordFse, dataAreaFieldConfigObj, dataAreaFieldName, value, null); } /** * 获取统计行的公式计算值 * * @param statisticsMap 统计map * @param formulaMap 公式map * @param formulaFieldKeyObj 公式字段keyobj * @param formula 公式 * @param value 原本的值 * @return */ private String getStatisticsValue(Map statisticsMap, Map formulaMap, JSONObject formulaFieldKeyObj, String formula, String value) { String statisticsValue = ""; String formulaFieldValue; if (formulaMap != null && !formulaMap.isEmpty()) { for (Map.Entry entry : formulaMap.entrySet()) { formulaFieldKeyObj.put(CmnConst.ATTR_FIELD_INFO, entry.getKey()); formulaFieldValue = statisticsMap.get(formulaFieldKeyObj).getString(entry.getValue()); if (formulaFieldValue != null && formulaFieldValue.matches(CmnConst.REGEXP_NUMBER)) { formulaFieldValue += "d"; } formula = formula.replace(entry.getKey(), StringUtils.isEmpty(formulaFieldValue) ? "" : formulaFieldValue); } try { statisticsValue = BaseUtil.executeExpression(formula, Maps.newHashMap()).toString(); } catch (Exception e) { SpringMVCContextHolder.getSystemLogger().error(e); statisticsValue = ""; } } return StringUtils.isEmpty(statisticsValue) ? value : statisticsValue; } /** * 获取数据区分组统计字段统计行html * * @param waitStatisticsValue 待统计的值 * @param statisticsMap 统计map * @param dataAreaFieldConfigMap 数据区字段缓存map * @param tempFieldName 本次操作的字段名称 * @param recordFse 业务数据记录 * @param dataAreaGroupFieldNameList 数据区分组字段名称list * @param replaceMap 替换map * @param dataAreaGroupFieldRecordObj 数据区分组字段记录obj * @return */ private StringBuilder getDataAreaGroupStatisticsFieldStatisticsRowHtml(String waitStatisticsValue, Map statisticsMap, Map dataAreaFieldConfigMap, String tempFieldName, FieldSetEntity recordFse, List dataAreaGroupFieldNameList, Map replaceMap, JSONObject dataAreaGroupFieldRecordObj) { StringBuilder html = new StringBuilder(); html.append("\n\n "); String dataAreaFieldName; JSONObject dataAreaFieldConfigObj; boolean flag = false; JSONObject keyObj = new JSONObject(); String value; String statisticsType; int index = 0; List needAddRowspanDataAreaGroupFieldNameList = Lists.newArrayList(); for (Map.Entry entry : dataAreaFieldConfigMap.entrySet()) { index++; dataAreaFieldName = entry.getKey(); if (!flag) { if (dataAreaGroupFieldNameList.contains(dataAreaFieldName)) { keyObj.put(dataAreaFieldName, recordFse.getString(dataAreaFieldName)); if (dataAreaFieldName.equals(tempFieldName)) { html.append("").append(waitStatisticsValue).append(CmnConst.STATISTICS_NAME).append(""); flag = true; } if (!flag) { needAddRowspanDataAreaGroupFieldNameList.add(dataAreaFieldName); } } } else { dataAreaFieldConfigObj = entry.getValue(); statisticsType = dataAreaFieldConfigObj.getString(CmnConst.ATTR_STATISTICS); if (!"1".equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_IS_CUSTOM_FIELD)) && StringUtils.isEmpty(statisticsType)) { if (!"1".equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_IS_GROUP))) { html.append(""); } } else { keyObj.put(CmnConst.ATTR_FIELD_INFO, dataListReportService.fieldName2FieldInfo(dataAreaFieldName)); if (statisticsMap.get(keyObj) == null) { value = ""; } else { JSONObject valueObj = statisticsMap.get(keyObj); if (StringUtils.isEmpty(statisticsType)) { statisticsType = CmnConst.ATTR_STATISTICS_DEFAULT; } if (CmnConst.ATTR_STATISTICS_AVG.equals(statisticsType) && "1".equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_AVG_TYPE))) { int subCnt = getAimSubCnt(keyObj, dataAreaGroupFieldNameList, dataAreaGroupFieldRecordObj); valueObj.put(CmnConst.ATTR_STATISTICS_SUB_CNT, subCnt); dataListReportService.getAvgValue(valueObj, dataAreaFieldConfigObj, false); } value = valueObj.getString(statisticsType); } // 格式 value = dataListReportService.formatValue(dataAreaFieldConfigObj, value); html.append("").append(value == null ? "" : value).append(""); } } } html.append("\n"); dealReplaceMapAddRowspan(replaceMap, needAddRowspanDataAreaGroupFieldNameList, recordFse, false); return html; } /** * 获取总计html * * @param statisticsMap 统计map * @param dataAreaFieldConfigMap 数据区字段缓存map * @param dataAreaGroupFieldNameList 数据区分组字段名称list * @param preFse 最近操作的数据fse * @param dataAreaGroupFieldRecordObj 数据区分组字段记录obj * @param totalName 总计名称 * @return */ private String getDataAreaTotalStatisticsHtml(Map statisticsMap, Map dataAreaFieldConfigMap, List dataAreaGroupFieldNameList, FieldSetEntity preFse, JSONObject dataAreaGroupFieldRecordObj, String totalName) { StringBuilder html = new StringBuilder(512); String dataAreaFieldName; JSONObject dataAreaFieldConfigObj; String value; JSONObject keyObj = new JSONObject(); String statisticsType; html.append("\n\n "); if (preFse == null) { return html.toString(); } int index = 0; for (Map.Entry entry : dataAreaFieldConfigMap.entrySet()) { index++; dataAreaFieldName = entry.getKey(); if (!dataAreaGroupFieldNameList.contains(dataAreaFieldName)) { dataAreaFieldConfigObj = entry.getValue(); statisticsType = dataAreaFieldConfigObj.getString(CmnConst.ATTR_STATISTICS); keyObj.put(CmnConst.ATTR_FIELD_INFO, dataAreaFieldConfigObj.getString(CmnConst.ATTR_FIELD_INFO)); if ((!"1".equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_IS_CUSTOM_FIELD)) && StringUtils.isEmpty(statisticsType)) || statisticsMap.get(keyObj) == null) { value = ""; } else { JSONObject valueObj = statisticsMap.get(keyObj); if (StringUtils.isEmpty(statisticsType)) { statisticsType = CmnConst.ATTR_STATISTICS_DEFAULT; } if (CmnConst.ATTR_STATISTICS_AVG.equals(statisticsType) && "1".equals(dataAreaFieldConfigObj.getString(CmnConst.ATTR_AVG_TYPE))) { int subCnt = dataAreaGroupFieldRecordObj.size(); valueObj.put(CmnConst.ATTR_STATISTICS_SUB_CNT, subCnt); dataListReportService.getAvgValue(valueObj, dataAreaFieldConfigObj, false); } value = valueObj.getString(statisticsType); } // 格式 value = dataListReportService.formatValue(dataAreaFieldConfigObj, value); html.append("").append(value == null ? "" : value).append(""); } else { if (index == 1) { html.append("").append(totalName).append(""); } } } html.append("\n"); return html.toString(); } /** * 处理参数替换map-添加数据区分组字段的占行 * * @param replaceMap 替换map * @param needAddRowspanDataAreaGroupFieldNames 需要添加占行的数据区分组字段名称集合 * @param recordFse 业务数据记录 */ private void dealReplaceMapAddRowspan(Map replaceMap, Collection needAddRowspanDataAreaGroupFieldNames, FieldSetEntity recordFse, boolean commonFieldFlag) { JSONObject keyObj = new JSONObject(); String value; int rowspan; String paramKey; int index = 0; for (String fieldName : needAddRowspanDataAreaGroupFieldNames) { index++; keyObj.put(fieldName, recordFse.getString(fieldName)); if (commonFieldFlag && index != needAddRowspanDataAreaGroupFieldNames.size()) { continue; } keyObj.put(CmnConst.ATTR_FIELD_INFO, dataListReportService.fieldName2FieldInfo(fieldName)); paramKey = dataListReportService.concat(keyObj, CmnConst.ATTR_ROWSPAN); value = replaceMap.get(paramKey); rowspan = StringUtils.isEmpty(value) ? 1 : Integer.parseInt(value) + 1; replaceMap.put(paramKey, String.valueOf(rowspan)); } } /** * 记录分组字段 * * @param dataAreaGroupFieldRecordObj 数据区分组字段记录obj * @param dataAreaGroupFieldNameList 数据区分组字段名称list * @param curFieldIndex 当前字段下标 * @param recordFse 业务数据记录 */ private void recordDataAreaGroupField(JSONObject dataAreaGroupFieldRecordObj, List dataAreaGroupFieldNameList, int curFieldIndex, FieldSetEntity recordFse) { String tempFieldName; JSONObject parentObj = dataAreaGroupFieldRecordObj; JSONObject subObj; String value; for (int j = 0; j <= curFieldIndex; j++) { tempFieldName = dataAreaGroupFieldNameList.get(j); value = recordFse.getString(tempFieldName); subObj = parentObj.getJSONObject(value); if (subObj == null) { subObj = new JSONObject(); parentObj.put(value, subObj); } parentObj = subObj; } } /** * 获取指定的下级分组项 * * @param keyObj 指定的key * @param dataAreaGroupFieldNameList 数据区分组字段名称list * @param dataAreaGroupFieldRecordObj 数据区分组字段记录obj * @return */ private int getAimSubCnt(JSONObject keyObj, List dataAreaGroupFieldNameList, JSONObject dataAreaGroupFieldRecordObj) { String value; JSONObject parentObj = dataAreaGroupFieldRecordObj; JSONObject subObj = null; for (String fieldName : dataAreaGroupFieldNameList) { value = keyObj.getString(fieldName); if (value != null) { subObj = parentObj.getJSONObject(value); } else { break; } parentObj = subObj; } return subObj == null ? 0 : subObj.size(); } }