Browse Source

报表增加同比环比

hsh 3 years ago
parent
commit
955a819ccf

+ 11 - 0
src/main/java/thyyxxk/webserver/controller/ybkf/YbStatController.java

@@ -11,7 +11,9 @@ import thyyxxk.webserver.entity.ybkf.YbStatDto;
 import thyyxxk.webserver.entity.ybkf.YbStatResult;
 import thyyxxk.webserver.service.ybkf.YbStatService;
 
+import javax.servlet.http.HttpServletResponse;
 import java.util.List;
+import java.util.Map;
 
 /**
  * @ClassName YbStatController
@@ -35,5 +37,14 @@ public class YbStatController {
         return service.selectYbStatInfo(dto);
     }
 
+    @PostMapping("/selectYbStatRatio")
+    public ResultVo<List<Map<String, Object>>> selectYbStatRatio(@RequestBody @Validated YbStatDto dto) {
+        return service.selectYbStatRatio(dto);
+    }
+
+    @PostMapping("/exportYbStatRatioExcel")
+    public ResultVo<String> exportYbStatRatioExcel(HttpServletResponse response, @RequestBody @Validated YbStatDto dto) {
+        return service.exportYbStatRatioExcel(response, dto);
+    }
 
 }

+ 44 - 36
src/main/java/thyyxxk/webserver/dao/his/ybkf/YbStatDao.java

@@ -25,18 +25,14 @@ public interface YbStatDao {
             "fundPooling=cast(round(sum(a.hifp_pay),2) as decimal(10,2)), " +
             "bigIllFundPooling=cast(round(sum(a.hifmi_pay),2) as decimal(10,2)), " +
             "civilServiceFund=cast(round(sum(a.cvlserv_pay),2) as decimal(10,2)), " +
-            "otherFunds=cast(round(sum(a.fund_pay_sumamt-a.hifp_pay-a.cvlserv_pay-a.hifmi_pay),2) as decimal(10,2)), " +
+            "otherFunds=cast(round(sum(isnull(a.fund_pay_sumamt,0)-isnull(a.hifp_pay,0)-isnull(a.cvlserv_pay,0)-isnull(a.hifmi_pay,0)),2) as decimal(10,2)), " +
             "allFunds=cast(round(sum(a.fund_pay_sumamt),2) as decimal(10,2)), " +
-            "drugFee=cast(round(sum(t1.ypf),2) as decimal(10,2)), " +
-            "drugFeeRatio=cast(round(sum(t1.ypf)/sum(a.medfee_sumamt)*100,2) as decimal(10,2)), " +
-            "matFee=cast(round(sum(t2.clf),2) as decimal(10,2)), " +
-            "matFeeRatio=cast(round(sum(t2.clf)/sum(a.medfee_sumamt)*100,2) as decimal(10,2)) " +
+            "drugFee=cast(round(sum(isnull(a.charge_western_medicine,0) + isnull(a.charge_patent_medicine,0) + isnull(a.charge_herbal,0)),2) as decimal(10,2)), " +
+            "drugFeeRatio=cast(round(sum(isnull(a.charge_western_medicine,0) + isnull(a.charge_patent_medicine,0) + isnull(a.charge_herbal,0))/sum(a.medfee_sumamt)*100,2) as decimal(10,2)), " +
+            "matFee=cast(round(sum(a.charge_sanitary_material),2) as decimal(10,2)), " +
+            "matFeeRatio=cast(round(sum(a.charge_sanitary_material)/sum(a.medfee_sumamt)*100,2) as decimal(10,2)) " +
             "from t_si_setlinfo a " +
             "left join zy_inactpatient zy on (zy.inpatient_no = a.pat_no and zy.admiss_times = a.times) " +
-            "left join (select b.setl_id, sum(b.det_item_fee_sumamt) ypf from t_si_setl_fee_detl b where b.med_chrgitm_type in ('09','10','11') group by b.setl_id) t1 " +
-            "on t1.setl_id = a.setl_id " +
-            "left join (select c.setl_id, sum(c.det_item_fee_sumamt) clf from t_si_setl_fee_detl c where c.med_chrgitm_type = '08' group by c.setl_id) t2 " +
-            "on t2.setl_id = a.setl_id " +
             "where a.revoked=0 and a.setl_type=#{setlType} and a.setl_time&gt;=#{beginTime} and a.setl_time&lt;=#{endTime} " +
             "<if test=\"insuplcAdmdvs != null and insuplcAdmdvs.size > 0 \">" +
             " and a.insuplc_admdvs in  " +
@@ -69,18 +65,14 @@ public interface YbStatDao {
             "fundPooling=cast(round(sum(a.hifp_pay),2) as decimal(10,2)), " +
             "bigIllFundPooling=cast(round(sum(a.hifmi_pay),2) as decimal(10,2)), " +
             "civilServiceFund=cast(round(sum(a.cvlserv_pay),2) as decimal(10,2)), " +
-            "otherFunds=cast(round(sum(a.fund_pay_sumamt-a.hifp_pay-a.cvlserv_pay-a.hifmi_pay),2) as decimal(10,2)), " +
+            "otherFunds=cast(round(sum(isnull(a.fund_pay_sumamt,0)-isnull(a.hifp_pay,0)-isnull(a.cvlserv_pay,0)-isnull(a.hifmi_pay,0)),2) as decimal(10,2)), " +
             "allFunds=cast(round(sum(a.fund_pay_sumamt),2) as decimal(10,2)), " +
-            "drugFee=cast(round(sum(t1.ypf),2) as decimal(10,2)), " +
-            "drugFeeRatio=cast(round(sum(t1.ypf)/sum(a.medfee_sumamt)*100,2) as decimal(10,2)), " +
-            "matFee=cast(round(sum(t2.clf),2) as decimal(10,2)), " +
-            "matFeeRatio=cast(round(sum(t2.clf)/sum(a.medfee_sumamt)*100,2) as decimal(10,2)) " +
+            "drugFee=cast(round(sum(isnull(a.charge_western_medicine,0) + isnull(a.charge_patent_medicine,0) + isnull(a.charge_herbal,0)),2) as decimal(10,2)), " +
+            "drugFeeRatio=cast(round(sum(isnull(a.charge_western_medicine,0) + isnull(a.charge_patent_medicine,0) + isnull(a.charge_herbal,0))/sum(a.medfee_sumamt)*100,2) as decimal(10,2)), " +
+            "matFee=cast(round(sum(a.charge_sanitary_material),2) as decimal(10,2)), " +
+            "matFeeRatio=cast(round(sum(a.charge_sanitary_material)/sum(a.medfee_sumamt)*100,2) as decimal(10,2)) " +
             "from t_si_setlinfo a " +
             "left join zy_inactpatient zy on (zy.inpatient_no = a.pat_no and zy.admiss_times = a.times) " +
-            "left join (select b.setl_id, sum(b.det_item_fee_sumamt) ypf from t_si_setl_fee_detl b where b.med_chrgitm_type in ('09','10','11') group by b.setl_id) t1 " +
-            "on t1.setl_id = a.setl_id " +
-            "left join (select c.setl_id, sum(c.det_item_fee_sumamt) clf from t_si_setl_fee_detl c where c.med_chrgitm_type = '08' group by c.setl_id) t2 " +
-            "on t2.setl_id = a.setl_id " +
             "where a.revoked=0 and a.setl_type=#{setlType} and a.setl_time&gt;=#{beginTime} and a.setl_time&lt;=#{endTime} " +
             "and a.insuplc_admdvs != '439900' and a.insuplc_admdvs like '43%' and a.insuplc_admdvs not like '4301%' and a.med_type != '2102' " +
             "</script>")
@@ -94,18 +86,14 @@ public interface YbStatDao {
             "fundPooling=cast(round(sum(a.hifp_pay),2) as decimal(10,2)), " +
             "bigIllFundPooling=cast(round(sum(a.hifmi_pay),2) as decimal(10,2)), " +
             "civilServiceFund=cast(round(sum(a.cvlserv_pay),2) as decimal(10,2)), " +
-            "otherFunds=cast(round(sum(a.fund_pay_sumamt-a.hifp_pay-a.cvlserv_pay-a.hifmi_pay),2) as decimal(10,2)), " +
+            "otherFunds=cast(round(sum(isnull(a.fund_pay_sumamt,0)-isnull(a.hifp_pay,0)-isnull(a.cvlserv_pay,0)-isnull(a.hifmi_pay,0)),2) as decimal(10,2)), " +
             "allFunds=cast(round(sum(a.fund_pay_sumamt),2) as decimal(10,2)), " +
-            "drugFee=cast(round(sum(t1.ypf),2) as decimal(10,2)), " +
-            "drugFeeRatio=cast(round(sum(t1.ypf)/sum(a.medfee_sumamt)*100,2) as decimal(10,2)), " +
-            "matFee=cast(round(sum(t2.clf),2) as decimal(10,2)), " +
-            "matFeeRatio=cast(round(sum(t2.clf)/sum(a.medfee_sumamt)*100,2) as decimal(10,2)) " +
+            "drugFee=cast(round(sum(isnull(a.charge_western_medicine,0) + isnull(a.charge_patent_medicine,0) + isnull(a.charge_herbal,0)),2) as decimal(10,2)), " +
+            "drugFeeRatio=cast(round(sum(isnull(a.charge_western_medicine,0) + isnull(a.charge_patent_medicine,0) + isnull(a.charge_herbal,0))/sum(a.medfee_sumamt)*100,2) as decimal(10,2)), " +
+            "matFee=cast(round(sum(a.charge_sanitary_material),2) as decimal(10,2)), " +
+            "matFeeRatio=cast(round(sum(a.charge_sanitary_material)/sum(a.medfee_sumamt)*100,2) as decimal(10,2)) " +
             "from t_si_setlinfo a " +
             "left join zy_inactpatient zy on (zy.inpatient_no = a.pat_no and zy.admiss_times = a.times) " +
-            "left join (select b.setl_id, sum(b.det_item_fee_sumamt) ypf from t_si_setl_fee_detl b where b.med_chrgitm_type in ('09','10','11') group by b.setl_id) t1 " +
-            "on t1.setl_id = a.setl_id " +
-            "left join (select c.setl_id, sum(c.det_item_fee_sumamt) clf from t_si_setl_fee_detl c where c.med_chrgitm_type = '08' group by c.setl_id) t2 " +
-            "on t2.setl_id = a.setl_id " +
             "where a.revoked=0 and a.setl_type=#{setlType} and a.setl_time&gt;=#{beginTime} and a.setl_time&lt;=#{endTime} " +
             "and a.insuplc_admdvs != '439900' and a.insuplc_admdvs not like '43%' " +
             "</script>")
@@ -119,21 +107,41 @@ public interface YbStatDao {
             "fundPooling=cast(round(sum(a.hifp_pay),2) as decimal(10,2)), " +
             "bigIllFundPooling=cast(round(sum(a.hifmi_pay),2) as decimal(10,2)), " +
             "civilServiceFund=cast(round(sum(a.cvlserv_pay),2) as decimal(10,2)), " +
-            "otherFunds=cast(round(sum(a.fund_pay_sumamt-a.hifp_pay-a.cvlserv_pay-a.hifmi_pay),2) as decimal(10,2)), " +
+            "otherFunds=cast(round(sum(isnull(a.fund_pay_sumamt,0)-isnull(a.hifp_pay,0)-isnull(a.cvlserv_pay,0)-isnull(a.hifmi_pay,0)),2) as decimal(10,2)), " +
             "allFunds=cast(round(sum(a.fund_pay_sumamt),2) as decimal(10,2)), " +
-            "drugFee=cast(round(sum(t1.ypf),2) as decimal(10,2)), " +
-            "drugFeeRatio=cast(round(sum(t1.ypf)/sum(a.medfee_sumamt)*100,2) as decimal(10,2)), " +
-            "matFee=cast(round(sum(t2.clf),2) as decimal(10,2)), " +
-            "matFeeRatio=cast(round(sum(t2.clf)/sum(a.medfee_sumamt)*100,2) as decimal(10,2)) " +
+            "drugFee=cast(round(sum(isnull(a.charge_western_medicine,0) + isnull(a.charge_patent_medicine,0) + isnull(a.charge_herbal,0)),2) as decimal(10,2)), " +
+            "drugFeeRatio=cast(round(sum(isnull(a.charge_western_medicine,0) + isnull(a.charge_patent_medicine,0) + isnull(a.charge_herbal,0))/sum(a.medfee_sumamt)*100,2) as decimal(10,2)), " +
+            "matFee=cast(round(sum(a.charge_sanitary_material),2) as decimal(10,2)), " +
+            "matFeeRatio=cast(round(sum(a.charge_sanitary_material)/sum(a.medfee_sumamt)*100,2) as decimal(10,2)) " +
             "from t_si_setlinfo a " +
             "left join zy_inactpatient zy on (zy.inpatient_no = a.pat_no and zy.admiss_times = a.times) " +
-            "left join (select b.setl_id, sum(b.det_item_fee_sumamt) ypf from t_si_setl_fee_detl b where b.med_chrgitm_type in ('09','10','11') group by b.setl_id) t1 " +
-            "on t1.setl_id = a.setl_id " +
-            "left join (select c.setl_id, sum(c.det_item_fee_sumamt) clf from t_si_setl_fee_detl c where c.med_chrgitm_type = '08' group by c.setl_id) t2 " +
-            "on t2.setl_id = a.setl_id " +
             "where a.revoked=0 and a.setl_type=#{setlType} and a.setl_time&gt;=#{beginTime} and a.setl_time&lt;=#{endTime} " +
             "and a.insuplc_admdvs != '439900' and a.insuplc_admdvs like '43%' and a.insuplc_admdvs not like '4301%' and a.med_type = '2102' " +
             "</script>")
     YbStatResult selectYbStatInfoInProvinceOtherCitiesSingleDisease(@Param("beginTime") String beginTime, @Param("endTime") String endTime, @Param("setlType") String setlType);
 
+    @Select("<script>" +
+            "select yf=convert(varchar(7), a.setl_time, 120), " +
+            "totalFee=cast(round(sum(a.medfee_sumamt),2) as decimal(10,2)), " +
+            "allFunds=cast(round(sum(a.fund_pay_sumamt),2) as decimal(10,2)), " +
+            "drugFee=cast(round(sum(isnull(a.charge_western_medicine,0) + isnull(a.charge_patent_medicine,0) + isnull(a.charge_herbal,0)),2) as decimal(10,2)), " +
+            "matFee=cast(round(sum(a.charge_sanitary_material),2) as decimal(10,2)) " +
+            "from t_si_setlinfo a " +
+            "left join zy_inactpatient zy on (zy.inpatient_no = a.pat_no and zy.admiss_times = a.times) " +
+            "where a.revoked=0 and a.setl_type=#{setlType} and a.setl_time&gt;=#{beginTime} and a.setl_time&lt;=#{endTime} " +
+            "group by convert(varchar(7), a.setl_time, 120) " +
+            "</script>")
+    List<YbStatResult> selectYbStatRatio(@Param("beginTime") String beginTime, @Param("endTime") String endTime, @Param("setlType") String setlType);
+
+    @Select("<script>" +
+            "select totalFee=cast(round(sum(a.medfee_sumamt),2) as decimal(10,2)), " +
+            "allFunds=cast(round(sum(a.fund_pay_sumamt),2) as decimal(10,2)), " +
+            "drugFee=cast(round(sum(isnull(a.charge_western_medicine,0) + isnull(a.charge_patent_medicine,0) + isnull(a.charge_herbal,0)),2) as decimal(10,2)), " +
+            "matFee=cast(round(sum(a.charge_sanitary_material),2) as decimal(10,2)) " +
+            "from t_si_setlinfo a " +
+            "left join zy_inactpatient zy on (zy.inpatient_no = a.pat_no and zy.admiss_times = a.times) " +
+            "where a.revoked=0 and a.setl_type=#{setlType} and a.setl_time&gt;=#{beginTime} and a.setl_time&lt;=#{endTime} " +
+            "</script>")
+    YbStatResult selectYbStatRatioTotal(@Param("beginTime") String beginTime, @Param("endTime") String endTime, @Param("setlType") String setlType);
+
 }

+ 20 - 0
src/main/java/thyyxxk/webserver/entity/HeadInfo.java

@@ -0,0 +1,20 @@
+package thyyxxk.webserver.entity;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @ClassName HeadInfo
+ * @Description 导出表头信息
+ * @Author hsh
+ * @Date 2022/6/30 14:55
+ **/
+@Data
+public class HeadInfo {
+
+    private String display;
+    private String name;
+    private List<HeadInfo> columns;
+
+}

+ 6 - 2
src/main/java/thyyxxk/webserver/entity/ybkf/YbStatDto.java

@@ -13,10 +13,14 @@ import javax.validation.constraints.NotNull;
  **/
 @Data
 public class YbStatDto {
-    @NotBlank(message = "请选择年月!")
-    private String month;
+    @NotBlank(message = "请选择开始时间!")
+    private String startTime;
+    @NotBlank(message = "请选择结束时间!")
+    private String endTime;
     @NotNull(message = "请选择险种!")
     private String insurType;
     private String setlType;
+    private String selectType;
+    private String exportName;
 
 }

+ 1 - 1
src/main/java/thyyxxk/webserver/entity/ybkf/YbStatResult.java

@@ -26,6 +26,6 @@ public class YbStatResult {
     private String civilServiceFund;
     private String otherFunds;
     private String allFunds;
-
+    private String yf;
 
 }

+ 589 - 6
src/main/java/thyyxxk/webserver/service/ybkf/YbStatService.java

@@ -6,14 +6,19 @@ import org.springframework.util.ObjectUtils;
 import thyyxxk.webserver.config.exception.ExceptionEnum;
 import thyyxxk.webserver.dao.his.ybkf.YbStatDao;
 import thyyxxk.webserver.entity.ResultVo;
+import thyyxxk.webserver.entity.HeadInfo;
 import thyyxxk.webserver.entity.ybkf.YbStatDto;
 import thyyxxk.webserver.entity.ybkf.YbStatResult;
 import thyyxxk.webserver.utils.DateUtil;
+import thyyxxk.webserver.utils.DecimalUtil;
+import thyyxxk.webserver.utils.ExcelUtil;
 import thyyxxk.webserver.utils.ResultVoUtil;
-import thyyxxk.webserver.utils.StringUtil;
 
+import javax.servlet.http.HttpServletResponse;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 /**
  * @ClassName YbStatService
@@ -32,13 +37,11 @@ public class YbStatService {
     }
 
     public ResultVo<List<YbStatResult>> selectYbStatInfo(YbStatDto dto){
-        String beginTime = dto.getMonth() + "-01 00:00:00.000";
-        String endTime = DateUtil.getMonthEndtime(dto.getMonth());
+        String beginTime = dto.getStartTime();
+        String endTime = DateUtil.getMonthEndtime(dto.getEndTime());
         String insurType = dto.getInsurType();
         String setlType = dto.getSetlType();
-        if (StringUtil.isBlank(insurType)) {
-            insurType = "%%";
-        }
+
         // 统筹区域
         List<String> insuplcAdmdvs = new ArrayList<>();
         // 险种类型
@@ -47,6 +50,7 @@ public class YbStatService {
         List<String> med_type = new ArrayList<>();
         // 返回结果
         List<YbStatResult> ybStatResult = new ArrayList<>();
+
         if("21".equals(setlType)){
             // 住院
             if("43010031001".equals(insurType) || "99".equals(insurType)){
@@ -56,6 +60,7 @@ public class YbStatService {
                 insuplcAdmdvs.add("430104");
                 insuplcAdmdvs.add("430105");
                 insuplcAdmdvs.add("430111");
+                insuplcAdmdvs.add("430112");
                 insuplcAdmdvs.add("430140");
                 insuplcAdmdvs.add("430199");
                 insurtype.add("310");
@@ -79,6 +84,7 @@ public class YbStatService {
                 insuplcAdmdvs.add("430104");
                 insuplcAdmdvs.add("430105");
                 insuplcAdmdvs.add("430111");
+                insuplcAdmdvs.add("430112");
                 insuplcAdmdvs.add("430140");
                 insuplcAdmdvs.add("430199");
                 insurtype.add("390");
@@ -102,6 +108,7 @@ public class YbStatService {
                 insuplcAdmdvs.add("430104");
                 insuplcAdmdvs.add("430105");
                 insuplcAdmdvs.add("430111");
+                insuplcAdmdvs.add("430112");
                 insuplcAdmdvs.add("430140");
                 insuplcAdmdvs.add("430199");
                 insurtype.add("340");
@@ -125,6 +132,7 @@ public class YbStatService {
                 insuplcAdmdvs.add("430104");
                 insuplcAdmdvs.add("430105");
                 insuplcAdmdvs.add("430111");
+                insuplcAdmdvs.add("430112");
                 insuplcAdmdvs.add("430140");
                 insuplcAdmdvs.add("430199");
                 med_type.add("52");
@@ -361,6 +369,7 @@ public class YbStatService {
                 insuplcAdmdvs.add("430104");
                 insuplcAdmdvs.add("430105");
                 insuplcAdmdvs.add("430111");
+                insuplcAdmdvs.add("430112");
                 insuplcAdmdvs.add("430140");
                 insuplcAdmdvs.add("430199");
                 insuplcAdmdvs.add("430121");
@@ -453,4 +462,578 @@ public class YbStatService {
         return ResultVoUtil.success(ybStatResult);
     }
 
+    /**
+     *@Author hsh
+     *@Description // 计算同比/环比
+     *@Date 2022/6/29 16:01
+     *@Param [dto]
+     *@Return thyyxxk.webserver.entity.ResultVo<java.util.List<java.util.Map<java.lang.String,java.lang.Object>>>
+     **/
+    public ResultVo<List<Map<String, Object>>> selectYbStatRatio(YbStatDto dto){
+        String beginTime = dto.getStartTime();
+        String endTime = DateUtil.getMonthEndtime(dto.getEndTime());
+        String setlType = dto.getSetlType();
+        String selectType = dto.getSelectType();
+
+        String year = beginTime.substring(0,4);
+        int lastYear = Integer.valueOf(year) - 1;
+        // 开始月份
+        String mouthS = beginTime.startsWith("10", 5) ? "10" : beginTime.substring(5,7).replace("0", "") ;
+        int m = Integer.parseInt(mouthS);
+        // 结束月份
+        String mouthE = endTime.startsWith("10", 5) ? "10" : endTime.substring(5,7).replace("0", "") ;
+        // 数据月份
+        int le = Integer.parseInt(mouthE) - Integer.parseInt(mouthS) ;
+
+        List<Map<String, Object>> ybStatRatio = new ArrayList<>();
+
+        // 查询本年数据
+        List<YbStatResult> result1 = dao.selectYbStatRatio(beginTime, endTime, setlType);
+        Map<String, YbStatResult> mapYf1 = new HashMap<>();
+        for(YbStatResult r : result1){
+            mapYf1.put(r.getYf(), r);
+        }
+
+        if("second".equals(selectType)) {
+            // 查询同比
+            // 查询上年数据
+            String beginTimeLast = DateUtil.getLastYearDate(beginTime, null);
+            String endTimeLast = DateUtil.getLastYearDate(endTime, null);
+            List<YbStatResult> result2 = dao.selectYbStatRatio(beginTimeLast, endTimeLast, setlType);
+            Map<String, YbStatResult> mapYf2 = new HashMap<>();
+            for(YbStatResult r : result2){
+                mapYf2.put(r.getYf(), r);
+            }
+
+            for(int i = m; i <= m + le; i++){
+                Map<String, Object> result = new HashMap<>();
+                String yf1 = "";
+                String yf2 = "";
+                String yf3 = calCNMonth(i);
+                result.put("month", yf3);
+                if(i < 10){
+                    yf1 = year + "-0"+ i;
+                    yf2 = lastYear + "-0"+ i;
+                } else {
+                    yf1 = year + "-" + i;
+                    yf2 = lastYear + "-" + i;
+                }
+                YbStatResult r1 = mapYf1.get(yf1);
+                YbStatResult r2 = mapYf2.get(yf2);
+
+                if(!ObjectUtils.isEmpty(r1) && Double.parseDouble(r1.getTotalFee()) > 0){
+                    result.put("zfy_jn", r1.getTotalFee());
+                    result.put("zjj_jn", r1.getAllFunds());
+                    result.put("ypf_jn", r1.getDrugFee());
+                    result.put("clf_jn", r1.getMatFee());
+
+                    if(!ObjectUtils.isEmpty(r2) && Double.parseDouble(r2.getTotalFee()) > 0){
+                        result.put("zfy_qn", r2.getTotalFee());
+                        result.put("zjj_qn", r2.getAllFunds());
+                        result.put("ypf_qn", r2.getDrugFee());
+                        result.put("clf_qn", r2.getMatFee());
+
+                        // 都有值的时候计算同比增长率(同比增长速度=(本期发展水平-同期水平)/同期发展水平×100%)
+                        if(Double.parseDouble(r2.getTotalFee()) > 0){
+                            String zfyTb = DecimalUtil.percentage(DecimalUtil.minus(r1.getTotalFee(), r2.getTotalFee()), r2.getTotalFee());
+                            result.put("zfy_tb", zfyTb);
+                        } else {
+                            result.put("zfy_tb", "");
+                        }
+
+                        if(Double.parseDouble(r2.getAllFunds()) > 0){
+                            String zjjTb = DecimalUtil.percentage(DecimalUtil.minus(r1.getAllFunds(), r2.getAllFunds()), r2.getAllFunds());
+                            result.put("zjj_tb", zjjTb);
+                        } else {
+                            result.put("zjj_tb", "");
+                        }
+
+                        if(Double.parseDouble(r2.getDrugFee()) > 0){
+                            String ypfTb = DecimalUtil.percentage(DecimalUtil.minus(r1.getDrugFee(), r2.getDrugFee()), r2.getDrugFee());
+                            result.put("ypf_tb", ypfTb);
+                        } else {
+                            result.put("ypf_tb", "");
+                        }
+
+                        if(Double.parseDouble(r2.getMatFee()) > 0){
+                            String clfTb = DecimalUtil.percentage(DecimalUtil.minus(r1.getMatFee(), r2.getMatFee()), r2.getMatFee());
+                            result.put("clf_tb", clfTb);
+                        } else {
+                            result.put("clf_tb", "");
+                        }
+
+                    } else {
+                        result.put("zfy_qn", "");
+                        result.put("zjj_qn", "");
+                        result.put("ypf_qn", "");
+                        result.put("clf_qn", "");
+                        result.put("zfy_tb", "");
+                        result.put("zjj_tb", "");
+                        result.put("ypf_tb", "");
+                        result.put("clf_tb", "");
+                    }
+                } else {
+                    if(!ObjectUtils.isEmpty(r2) && Double.parseDouble(r2.getTotalFee()) > 0){
+                        result.put("zfy_qn", r2.getTotalFee());
+                        result.put("zjj_qn", r2.getAllFunds());
+                        result.put("ypf_qn", r2.getDrugFee());
+                        result.put("clf_qn", r2.getMatFee());
+                        result.put("zfy_jn", "");
+                        result.put("zjj_jn", "");
+                        result.put("ypf_jn", "");
+                        result.put("clf_jn", "");
+                        result.put("zfy_tb", "");
+                        result.put("zjj_tb", "");
+                        result.put("ypf_tb", "");
+                        result.put("clf_tb", "");
+                    }
+                }
+                ybStatRatio.add(result);
+            }
+
+        } else {
+            // 查询环比
+            for(int i = m; i <= m + le; i++){
+                Map<String, Object> result = new HashMap<>();
+                String yf1 = "";
+                // 上一个月
+                String yf2 = "";
+                String yf3 = calCNMonth(i);
+                result.put("month", yf3);
+                int s = i-1;
+                if(i < 10){
+                    yf1 = year + "-0"+ i;
+                    yf2 = year + "-0"+ s;
+                } else {
+                    yf1 = year + "-" + i;
+                    yf2 = year + "-"+ s;
+                }
+                YbStatResult r1 = mapYf1.get(yf1);
+                if(i == m){
+                    if(!ObjectUtils.isEmpty(r1) && Double.parseDouble(r1.getTotalFee()) > 0){
+                        result.put("zfy", r1.getTotalFee());
+                        result.put("zjj", r1.getAllFunds());
+                        result.put("ypf", r1.getDrugFee());
+                        result.put("clf", r1.getMatFee());
+                        result.put("zfy_hb", "");
+                        result.put("zjj_hb", "");
+                        result.put("ypf_hb", "");
+                        result.put("clf_hb", "");
+                    } else {
+                        result.put("zfy", "0");
+                        result.put("zjj", "0");
+                        result.put("ypf", "0");
+                        result.put("clf", "0");
+                        result.put("zfy_hb", "");
+                        result.put("zjj_hb", "");
+                        result.put("ypf_hb", "");
+                        result.put("clf_hb", "");
+                    }
+                } else {
+                    YbStatResult r2 = mapYf1.get(yf2);
+                    if(!ObjectUtils.isEmpty(r1) && Double.parseDouble(r1.getTotalFee()) > 0){
+                        result.put("zfy", r1.getTotalFee());
+                        result.put("zjj", r1.getAllFunds());
+                        result.put("ypf", r1.getDrugFee());
+                        result.put("clf", r1.getMatFee());
+                        // 都有值的时候计算环比增长率(环比增长速度=(本月发展水平-上月发展水平)/上月发展水平×100%)
+                        if(Double.parseDouble(r2.getTotalFee()) > 0){
+                            String hb = DecimalUtil.percentage(DecimalUtil.minus(r1.getTotalFee(), r2.getTotalFee()), r2.getTotalFee());
+                            result.put("zfy_hb", hb);
+                        } else {
+                            result.put("zfy_hb", "");
+                        }
+
+                        if(r2.getAllFunds() != null && Double.parseDouble(r2.getAllFunds()) > 0){
+                            String hb = DecimalUtil.percentage(DecimalUtil.minus(r1.getAllFunds(), r2.getAllFunds()), r2.getAllFunds());
+                            result.put("zjj_hb", hb);
+                        } else {
+                            result.put("zjj_hb", "");
+                        }
+
+                        if(r2.getDrugFee() != null && Double.parseDouble(r2.getDrugFee()) > 0){
+                            String hb = DecimalUtil.percentage(DecimalUtil.minus(r1.getDrugFee(), r2.getDrugFee()), r2.getDrugFee());
+                            result.put("ypf_hb", hb);
+                        } else {
+                            result.put("ypf_hb", "");
+                        }
+
+                        if(r2.getMatFee() != null && Double.parseDouble(r2.getMatFee()) > 0){
+                            String hb = DecimalUtil.percentage(DecimalUtil.minus(r1.getMatFee(), r2.getMatFee()), r2.getMatFee());
+                            result.put("clf_hb", hb);
+                        } else {
+                            result.put("clf_hb", "");
+                        }
+                    }
+
+                }
+                ybStatRatio.add(result);
+            }
+
+        }
+
+        return ResultVoUtil.success(ybStatRatio);
+    }
+
+    /**
+     *@Author hsh
+     *@Description // 根据数字转换中文月份
+     *@Date 2022/6/29 16:55
+     *@Param [i]
+     *@Return java.lang.String
+     **/
+    private String calCNMonth(int i) {
+        String yf;
+        switch (i){
+            case 1:
+                yf = "一    月";
+                break;
+            case 2:
+                yf = "二    月";
+                break;
+            case 3:
+                yf = "三    月";
+                break;
+            case 4:
+                yf = "四    月";
+                break;
+            case 5:
+                yf = "五    月";
+                break;
+            case 6:
+                yf = "六    月";
+                break;
+            case 7:
+                yf = "七    月";
+                break;
+            case 8:
+                yf = "八    月";
+                break;
+            case 9:
+                yf = "九    月";
+                break;
+            case 10:
+                yf = "十    月";
+                break;
+            case 11:
+                yf = "十一月";
+                break;
+            case 12:
+                yf = "十二月";
+                break;
+            default:
+                yf = "";
+        }
+        return yf;
+    }
+
+    public ResultVo<String> exportYbStatRatioExcel(HttpServletResponse response, YbStatDto dto){
+        String beginTime = dto.getStartTime();
+        String endTime = DateUtil.getMonthEndtime(dto.getEndTime());
+        String setlType = dto.getSetlType();
+        String selectType = dto.getSelectType();
+        ResultVo<List<Map<String, Object>>> rs =  selectYbStatRatio(dto);
+        List<Map<String, Object>> list = rs.getData();
+
+        if(null == list){
+            String log = "导出没有数据";
+            return ResultVoUtil.fail(ExceptionEnum.NO_DATA_EXIST, log);
+        }
+
+        // 计算合计
+        // 查询今年数据
+        YbStatResult r1 = dao.selectYbStatRatioTotal(beginTime, endTime, setlType);
+        // 查询上年数据
+        String beginTimeLast = DateUtil.getLastYearDate(beginTime, null);
+        String endTimeLast = DateUtil.getLastYearDate(endTime, null);
+        YbStatResult r2 = dao.selectYbStatRatioTotal(beginTimeLast, endTimeLast, setlType);
+
+        // 计算合计
+        Map<String, Object> result = calTotalInfo(r1, r2, selectType);
+        list.add(result);
+
+        // 导出标题
+        String exportName = dto.getExportName();
+
+        // 组装表头
+        List<HeadInfo> headInfoList = calHeadList(selectType);
+
+        // 导出
+        ExcelUtil.exportExcelReport(response, list, headInfoList, exportName);
+
+        String log = "导出成功";
+        return ResultVoUtil.success(log);
+    }
+
+    private List<HeadInfo> calHeadList(String selectType) {
+        List<HeadInfo> headInfoList = new ArrayList<>();
+        if("second".equals(selectType)){
+            HeadInfo headInfo = new HeadInfo();
+            headInfo.setDisplay("月份");
+            headInfo.setName("month");
+            headInfoList.add(headInfo);
+
+            headInfo = new HeadInfo();
+            headInfo.setDisplay("总费用");
+            headInfo.setName("zfy");
+
+            List<HeadInfo> headInfoList1 = new ArrayList<>();
+            HeadInfo headInfo1 = new HeadInfo();
+            headInfo1.setDisplay("今年");
+            headInfo1.setName("zfy_jn");
+            headInfoList1.add(headInfo1);
+
+            headInfo1 = new HeadInfo();
+            headInfo1.setDisplay("去年");
+            headInfo1.setName("zfy_qn");
+            headInfoList1.add(headInfo1);
+
+            headInfo1 = new HeadInfo();
+            headInfo1.setDisplay("同比");
+            headInfo1.setName("zfy_tb");
+            headInfoList1.add(headInfo1);
+
+            headInfo.setColumns(headInfoList1);
+            headInfoList.add(headInfo);
+
+            headInfo = new HeadInfo();
+            headInfo.setDisplay("全部基金");
+            headInfo.setName("zjj");
+
+            headInfoList1 = new ArrayList<>();
+            headInfo1 = new HeadInfo();
+            headInfo1.setDisplay("今年");
+            headInfo1.setName("zjj_jn");
+            headInfoList1.add(headInfo1);
+
+            headInfo1 = new HeadInfo();
+            headInfo1.setDisplay("去年");
+            headInfo1.setName("zjj_qn");
+            headInfoList1.add(headInfo1);
+
+            headInfo1 = new HeadInfo();
+            headInfo1.setDisplay("同比");
+            headInfo1.setName("zjj_tb");
+            headInfoList1.add(headInfo1);
+
+            headInfo.setColumns(headInfoList1);
+            headInfoList.add(headInfo);
+
+            headInfo = new HeadInfo();
+            headInfo.setDisplay("药品费用");
+            headInfo.setName("ypf");
+
+            headInfoList1 = new ArrayList<>();
+            headInfo1 = new HeadInfo();
+            headInfo1.setDisplay("今年");
+            headInfo1.setName("ypf_jn");
+            headInfoList1.add(headInfo1);
+
+            headInfo1 = new HeadInfo();
+            headInfo1.setDisplay("去年");
+            headInfo1.setName("ypf_qn");
+            headInfoList1.add(headInfo1);
+
+            headInfo1 = new HeadInfo();
+            headInfo1.setDisplay("同比");
+            headInfo1.setName("ypf_tb");
+            headInfoList1.add(headInfo1);
+
+            headInfo.setColumns(headInfoList1);
+            headInfoList.add(headInfo);
+
+            headInfo = new HeadInfo();
+            headInfo.setDisplay("耗材费用");
+            headInfo.setName("clf");
+
+            headInfoList1 = new ArrayList<>();
+            headInfo1 = new HeadInfo();
+            headInfo1.setDisplay("今年");
+            headInfo1.setName("clf_jn");
+            headInfoList1.add(headInfo1);
+
+            headInfo1 = new HeadInfo();
+            headInfo1.setDisplay("去年");
+            headInfo1.setName("clf_qn");
+            headInfoList1.add(headInfo1);
+
+            headInfo1 = new HeadInfo();
+            headInfo1.setDisplay("同比");
+            headInfo1.setName("clf_tb");
+            headInfoList1.add(headInfo1);
+
+            headInfo.setColumns(headInfoList1);
+            headInfoList.add(headInfo);
+        } else {
+            HeadInfo headInfo = new HeadInfo();
+            headInfo.setDisplay("月份");
+            headInfo.setName("month");
+            headInfoList.add(headInfo);
+
+            headInfo = new HeadInfo();
+            headInfo.setDisplay("总费用");
+            headInfo.setName("zfys");
+
+            List<HeadInfo> headInfoList1 = new ArrayList<>();
+            HeadInfo headInfo1 = new HeadInfo();
+            headInfo1.setDisplay("费用");
+            headInfo1.setName("zfy");
+            headInfoList1.add(headInfo1);
+
+            headInfo1 = new HeadInfo();
+            headInfo1.setDisplay("环比");
+            headInfo1.setName("zfy_hb");
+            headInfoList1.add(headInfo1);
+
+            headInfo.setColumns(headInfoList1);
+            headInfoList.add(headInfo);
+
+            headInfo = new HeadInfo();
+            headInfo.setDisplay("全部基金");
+            headInfo.setName("zjjs");
+
+            headInfoList1 = new ArrayList<>();
+            headInfo1 = new HeadInfo();
+            headInfo1.setDisplay("费用");
+            headInfo1.setName("zjj");
+            headInfoList1.add(headInfo1);
+
+            headInfo1 = new HeadInfo();
+            headInfo1.setDisplay("环比");
+            headInfo1.setName("zjj_hb");
+            headInfoList1.add(headInfo1);
+
+            headInfo.setColumns(headInfoList1);
+            headInfoList.add(headInfo);
+
+            headInfo = new HeadInfo();
+            headInfo.setDisplay("药品费用");
+            headInfo.setName("ypfs");
+
+            headInfoList1 = new ArrayList<>();
+            headInfo1 = new HeadInfo();
+            headInfo1.setDisplay("费用");
+            headInfo1.setName("ypf");
+            headInfoList1.add(headInfo1);
+
+            headInfo1 = new HeadInfo();
+            headInfo1.setDisplay("环比");
+            headInfo1.setName("ypf_hb");
+            headInfoList1.add(headInfo1);
+
+            headInfo.setColumns(headInfoList1);
+            headInfoList.add(headInfo);
+
+            headInfo = new HeadInfo();
+            headInfo.setDisplay("耗材费用");
+            headInfo.setName("clfs");
+
+            headInfoList1 = new ArrayList<>();
+            headInfo1 = new HeadInfo();
+            headInfo1.setDisplay("费用");
+            headInfo1.setName("clf");
+            headInfoList1.add(headInfo1);
+
+            headInfo1 = new HeadInfo();
+            headInfo1.setDisplay("环比");
+            headInfo1.setName("clf_hb");
+            headInfoList1.add(headInfo1);
+
+            headInfo.setColumns(headInfoList1);
+            headInfoList.add(headInfo);
+        }
+        return headInfoList;
+    }
+
+    private Map<String, Object> calTotalInfo(YbStatResult r1, YbStatResult r2, String selectType) {
+        Map<String, Object> result = new HashMap<>();
+        if("second".equals(selectType)){
+            if(!ObjectUtils.isEmpty(r1) && Double.parseDouble(r1.getTotalFee()) > 0){
+                result.put("zfy_jn", r1.getTotalFee());
+                result.put("zjj_jn", r1.getAllFunds());
+                result.put("ypf_jn", r1.getDrugFee());
+                result.put("clf_jn", r1.getMatFee());
+
+                if(!ObjectUtils.isEmpty(r2) && Double.parseDouble(r2.getTotalFee()) > 0){
+                    result.put("zfy_qn", r2.getTotalFee());
+                    result.put("zjj_qn", r2.getAllFunds());
+                    result.put("ypf_qn", r2.getDrugFee());
+                    result.put("clf_qn", r2.getMatFee());
+
+                    // 都有值的时候计算同比增长率(同比增长速度=(本期发展水平-同期水平)/同期发展水平×100%)
+                    String zfyTb = DecimalUtil.percentage(DecimalUtil.minus(r1.getTotalFee(), r2.getTotalFee()), r2.getTotalFee());
+                    result.put("zfy_tb", zfyTb);
+
+                    if(Double.parseDouble(r2.getAllFunds()) > 0){
+                        String zjjTb = DecimalUtil.percentage(DecimalUtil.minus(r1.getAllFunds(), r2.getAllFunds()), r2.getAllFunds());
+                        result.put("zjj_tb", zjjTb);
+                    } else {
+                        result.put("zjj_tb", "");
+                    }
+
+                    if(Double.parseDouble(r2.getDrugFee()) > 0){
+                        String zjjTb = DecimalUtil.percentage(DecimalUtil.minus(r1.getDrugFee(), r2.getDrugFee()), r2.getDrugFee());
+                        result.put("ypf_tb", zjjTb);
+                    } else {
+                        result.put("ypf_tb", "");
+                    }
+
+                    if(Double.parseDouble(r2.getMatFee()) > 0){
+                        String zjjTb = DecimalUtil.percentage(DecimalUtil.minus(r1.getMatFee(), r2.getMatFee()), r2.getMatFee());
+                        result.put("clf_tb", zjjTb);
+                    } else {
+                        result.put("clf_tb", "");
+                    }
+
+                } else {
+                    result.put("zfy_qn", "");
+                    result.put("zjj_qn", "");
+                    result.put("ypf_qn", "");
+                    result.put("clf_qn", "");
+                    result.put("zfy_tb", "");
+                    result.put("zjj_tb", "");
+                    result.put("ypf_tb", "");
+                    result.put("clf_tb", "");
+                }
+            } else {
+                if(!ObjectUtils.isEmpty(r2) && Double.parseDouble(r2.getTotalFee()) > 0){
+                    result.put("zfy_qn", r2.getTotalFee());
+                    result.put("zjj_qn", r2.getAllFunds());
+                    result.put("ypf_qn", r2.getDrugFee());
+                    result.put("clf_qn", r2.getMatFee());
+                    result.put("zfy_jn", "");
+                    result.put("zjj_jn", "");
+                    result.put("ypf_jn", "");
+                    result.put("clf_jn", "");
+                    result.put("zfy_tb", "");
+                    result.put("zjj_tb", "");
+                    result.put("ypf_tb", "");
+                    result.put("clf_tb", "");
+                }
+            }
+        } else {
+            if(!ObjectUtils.isEmpty(r1) && Double.parseDouble(r1.getTotalFee()) > 0) {
+                result.put("zfy", r1.getTotalFee());
+                result.put("zjj", r1.getAllFunds());
+                result.put("ypf", r1.getDrugFee());
+                result.put("clf", r1.getMatFee());
+                result.put("zfy_tb", "");
+                result.put("zjj_tb", "");
+                result.put("ypf_tb", "");
+                result.put("clf_tb", "");
+            } else {
+                result.put("zfy", 0);
+                result.put("zjj", 0);
+                result.put("ypf", 0);
+                result.put("clf", 0);
+                result.put("zfy_tb", "");
+                result.put("zjj_tb", "");
+                result.put("ypf_tb", "");
+                result.put("clf_tb", "");
+            }
+        }
+        result.put("month", "合计");
+        return result;
+    }
+
 }

+ 21 - 1
src/main/java/thyyxxk/webserver/utils/DateUtil.java

@@ -331,12 +331,32 @@ public class DateUtil {
         return -1;
     }
 
+    public static String getLastYearDate(String time, String pattern) {
+        if (StringUtil.isBlank(time)) {
+            return "";
+        }
+        if (StringUtil.isBlank(pattern)) {
+            pattern = "yyyy-MM-dd HH:mm:ss";
+        }
+        try {
+            SimpleDateFormat sdf = new SimpleDateFormat(pattern);
+            Date dt = sdf.parse(time);
+            Calendar rightNow = Calendar.getInstance();
+            rightNow.setTime(dt);
+            // 日期减1年
+            rightNow.add(Calendar.YEAR, -1);
+            return sdf.format(rightNow.getTime());
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return "";
+    }
+
     public static void main(String[] args) {
         long a = DateUtil.parse("2020-03-04 02:25:20").getTime() - DateUtil.parse("2020-03-02 01:20:20").getTime();
         long b = DateUtil.parse("2020-03-04 02:25:20").getTime() - DateUtil.parse("2020-03-02 01:18:20").getTime();
         log.info("a:{},b:{}", a, b);
         log.info("大小:{}", b > a);
-
     }
 }
 

+ 205 - 10
src/main/java/thyyxxk/webserver/utils/ExcelUtil.java

@@ -1,27 +1,38 @@
 package thyyxxk.webserver.utils;
 
-import java.io.*;
-import java.util.ArrayList;
-import java.util.List;
-
 import lombok.extern.slf4j.Slf4j;
-import org.apache.poi.hssf.usermodel.*;
-import org.apache.poi.ss.usermodel.CellType;
-import org.apache.poi.ss.usermodel.HorizontalAlignment;
-import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.poi.hssf.usermodel.HSSFCell;
+import org.apache.poi.hssf.usermodel.HSSFCellStyle;
+import org.apache.poi.hssf.usermodel.HSSFFont;
+import org.apache.poi.hssf.usermodel.HSSFRow;
+import org.apache.poi.hssf.usermodel.HSSFSheet;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.ss.usermodel.BorderStyle;
 import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.CellType;
 import org.apache.poi.ss.usermodel.DateUtil;
+import org.apache.poi.ss.usermodel.HorizontalAlignment;
 import org.apache.poi.ss.usermodel.Row;
 import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.usermodel.VerticalAlignment;
 import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.ss.util.RegionUtil;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 import org.jetbrains.annotations.NotNull;
 import thyyxxk.webserver.entity.nationalmatch.SiCentralSuppliesMini;
+import thyyxxk.webserver.entity.HeadInfo;
 
+import javax.servlet.http.HttpServletResponse;
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
-
-import javax.servlet.http.HttpServletResponse;
+import java.io.OutputStream;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
 
 /**
  * @author dj
@@ -176,4 +187,188 @@ public class ExcelUtil {
         }
     }
 
+    public static void exportExcelReport(HttpServletResponse response, List<Map<String, Object>> recordList, List<HeadInfo> headlList, String report_name) {
+        // Excel数据拼接
+        HSSFWorkbook wb = new HSSFWorkbook();
+
+        //设置总列数,下面要用到
+        int cellCounts = -1 ;
+        int rowIndex = 1;
+
+        boolean isSecondaryMeter = false; // 不存在二级表头
+
+        for (HeadInfo head : headlList) {
+            if(!"操作".equals(head.getDisplay())){
+                if(head.getColumns() != null){
+                    List<HeadInfo>  columns = head.getColumns();
+                    rowIndex = 2;
+                    isSecondaryMeter = true; // 存在二级表头
+                    cellCounts+=columns.size();
+                }else{
+                    cellCounts++;
+                }
+            }
+        }
+        // 设置样式
+        HSSFCellStyle cellStyle = wb.createCellStyle();
+        cellStyle.setAlignment(HorizontalAlignment.CENTER); // 创建一个居中格式
+        cellStyle.setBorderBottom(BorderStyle.THIN); //下边框
+        cellStyle.setBorderLeft(BorderStyle.THIN);//左边框
+        cellStyle.setBorderTop(BorderStyle.THIN);//上边框
+        cellStyle.setBorderRight(BorderStyle.THIN);//右边框
+        cellStyle.setAlignment(HorizontalAlignment.CENTER);
+        cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
+
+        // 建立新的sheet对象(excel的表单)
+        HSSFSheet sheet = wb.createSheet(report_name);
+        HSSFRow row1 = sheet.createRow(0);
+        // 创建单元格,参数为列的索引
+        HSSFCell cell = row1.createCell(0);
+        //表头样式
+        HSSFCellStyle topicStyle = wb.createCellStyle();
+        HSSFFont font =  wb.createFont();//创建字体对象
+        font.setFontName("微软雅黑");
+        font.setFontHeightInPoints((short)20);
+        topicStyle.setFont(font);
+        topicStyle.setAlignment(HorizontalAlignment.CENTER);
+        topicStyle.setVerticalAlignment(VerticalAlignment.CENTER);
+        cell.setCellStyle(topicStyle);// 将样式应用于单元格
+
+        cell.setCellValue(report_name);
+        // 合并单元格CellRangeAddress构造参数依次表示起始行,截至行,起始列, 截至列
+        CellRangeAddress cra1 = new CellRangeAddress(0, 0, 0, cellCounts);
+        sheet.addMergedRegion(cra1);
+        createCellRangeBorder(cra1, sheet);
+
+        //创造第二 三行表头
+        HSSFRow row2 = sheet.createRow(1);
+
+        HSSFRow row3 = null;
+        if(isSecondaryMeter) {
+            row3 = sheet.createRow(rowIndex);
+        }
+
+        int index = 0 ;
+        List<String> keyList = new ArrayList<String>();
+        for (HeadInfo head : headlList) {
+            if(!"操作".equals(head.getDisplay())){
+                if(head.getColumns() != null){
+                    List<HeadInfo>  columns = head.getColumns();
+                    CellRangeAddress cra = new CellRangeAddress(1, 1, index, index+columns.size()-1);
+                    sheet.addMergedRegion(cra);
+                    createCellRangeBorder(cra, sheet);
+                    createHeaderInfo(row2,cellStyle,index,head.getDisplay(), report_name);
+                    for (HeadInfo column : columns) {
+                        createHeader(row3,cellStyle,index,column.getDisplay());
+                        keyList.add(column.getName());
+                        index++;
+                    }
+                }else{
+                    if(rowIndex>1) {
+                        CellRangeAddress cra = new CellRangeAddress(1, rowIndex, index, index);
+                        sheet.addMergedRegion(cra);
+                        createCellRangeBorder(cra, sheet);
+                    }
+                    createHeaderInfo(row2,cellStyle,index,head.getDisplay(), report_name);
+                    keyList.add(head.getName());
+                    index++;
+                }
+            }
+        }
+
+        int index2 = rowIndex+1;
+        for (Map<String, Object> map : recordList) {
+            //第二行开始
+            HSSFRow row = sheet.createRow(index2);
+
+            for (int i = 0; i < keyList.size(); i++) {
+                createHeaderInfo(row,cellStyle,i,(map.get(keyList.get(i))==null?"":map.get(keyList.get(i)).toString())+"", report_name);
+
+            }
+            index2++;
+        }
+
+        // 处理中文不能自动调整列宽的问题
+        for (int i = 0; i < cellCounts+1; i++) {
+            // 调整每一列宽度
+            sheet.autoSizeColumn((short) i);
+            // 解决自动设置列宽中文失效的问题
+            int colWidth=sheet.getColumnWidth(i) * 17 / 10;
+            // sheet 最大单元格长度问题处理
+            if(colWidth<255*256){
+                sheet.setColumnWidth(i, sheet.getColumnWidth(i) * 17 / 10);
+            }else{
+                sheet.setColumnWidth(i,255*256 );
+            }
+        }
+
+        response.setContentType("application/octet-stream;charset=ISO8859-1");
+        response.setHeader("Cache-Control", "no-cache");
+        OutputStream out = null;
+        try {
+            out = response.getOutputStream();
+            wb.write(out);
+        } catch (Exception e) {
+            log.error("导出EXCEL文件出错", e);
+        } finally {
+            try {
+                if (null != out) {
+                    out.flush();
+                    out.close();
+                }
+                wb.close();
+            } catch (Exception e) {
+                log.error("关闭导出EXCEL输出流出错", e);
+            }
+        }
+    }
+
+    // 补全合并单元格格子线条
+    public static void createCellRangeBorder(CellRangeAddress cellRange, HSSFSheet sheet) {
+        RegionUtil.setBorderBottom(BorderStyle.THIN, cellRange, sheet);
+        RegionUtil.setBorderTop(BorderStyle.THIN, cellRange, sheet);
+        RegionUtil.setBorderLeft(BorderStyle.THIN, cellRange, sheet);
+        RegionUtil.setBorderRight(BorderStyle.THIN, cellRange, sheet);
+    }
+
+    private static void createHeader(HSSFRow hfCell1, HSSFCellStyle cellStyle, int column, String value) {
+        HSSFCell row = hfCell1.createCell(column);
+        row.setCellStyle(cellStyle);// 将样式应用于单元格
+        if(StringUtils.isNotEmpty(value) && !"null".equals(value)){
+            value=processNumer(value);
+            row.setCellValue(value);
+
+        } else {
+            row.setCellValue(value);
+        }
+    }
+
+    private static void createHeaderInfo(HSSFRow hfCell1, HSSFCellStyle cellStyle, int column, String value, String title) {
+        HSSFCell row = hfCell1.createCell(column);
+        // 将样式应用于单元格
+        row.setCellStyle(cellStyle);
+        if(StringUtils.isNotEmpty(value) && !"null".equals(value)){
+            value = processNumer(value);
+            row.setCellValue(value);
+        } else {
+            row.setCellValue(value);
+        }
+    }
+
+    public static String processNumer(String value){
+        // 包含点,并且是整数和.
+        String pattren="([0-9]\\d*\\.?\\d*)|((-)?[0-9]\\d*\\.?\\d*)";
+
+        if(value.contains(".") && value.matches(pattren)){
+            try{
+                BigDecimal bigDecimal=new BigDecimal(value);
+                bigDecimal=bigDecimal.setScale(2,BigDecimal.ROUND_HALF_UP);
+                return bigDecimal.toString();
+            }catch (Exception e){
+                return value;
+            }
+        }
+        return value;
+    }
+
 }