瀏覽代碼

导出线索

ximinghao 3 月之前
父節點
當前提交
74d12ee883

+ 1 - 1
pom.xml

@@ -67,7 +67,7 @@
         <dependency>
             <groupId>com.alibaba</groupId>
             <artifactId>fastjson</artifactId>
-            <version>1.2.62</version>
+            <version>1.2.83</version>
         </dependency>
         <dependency>
             <groupId>org.apache.commons</groupId>

+ 97 - 0
src/main/java/com/skyversation/xjcy/bean/Clue.java

@@ -0,0 +1,97 @@
+package com.skyversation.xjcy.bean;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+@Data
+public class Clue implements FromJSON{
+    /** 主键(UUID) */
+    private String id;
+
+    /** 线索编码:XS+日期+3位流水号 */
+    private String cClueCode;
+
+    /** 线索名称(项目名称) */
+    private String cClueName;
+
+    /** 投资方企业性质(枚举) */
+    private String cEnterpriseName;
+
+    /** 投资主体(企业名称) */
+    private String enterpriseType;
+
+    /** 投资方简介 */
+    private String cEnterpriseIntroduction;
+
+    /** 所属行业(市级) */
+    private String industry;
+
+    /** 细分行业 */
+    private String industrySegment;
+
+    /** 产业体系(区级) */
+    private String industryType;
+
+    /** 其他行业 */
+    private String otherIndustry;
+
+    /** 建设方式(枚举) */
+    private String constructionMethod;
+
+    /** 土地/物业性质 */
+    private String landNature;
+
+    /** 用地规模(亩) */
+    private BigDecimal landArea;
+
+    /** 物业面积(㎡) */
+    private BigDecimal propertyArea;
+
+    /** 总投资规模(亿元) */
+    private BigDecimal expectedInvestment;
+
+    /** 项目简介 */
+    private String projectIntroduction;
+
+    /** 入库时间 */
+    @JSONField(format = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime storageTime;
+
+    /** 责任分管领导 */
+    private String responsibleLeader;
+
+    /** 招商负责人 */
+    private String investmentManager;
+
+    /** 预计投资额(万元) */
+    private BigDecimal cExpectedInvestment;
+
+    /** 项目状态(枚举) */
+    private String cClueStatus;
+
+    /** 经济小区 code */
+    private String cEconomicZoneId;
+
+    /** 经济小区名称 */
+    private String cEconomicZoneName;
+
+    /** 负责人名称 */
+    private String cResponsiblePersonName;
+
+    /** 创建时间 */
+    @JSONField(format = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime createTime;
+
+    /** 创建人(用户表 code) */
+    private String authorId;
+
+    /** 更新时间 */
+    @JSONField(format = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime updateTime;
+
+    /** 更新人(用户表 code) */
+    private String cUpdater;
+}

+ 18 - 0
src/main/java/com/skyversation/xjcy/bean/ClueFollow.java

@@ -0,0 +1,18 @@
+package com.skyversation.xjcy.bean;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import com.skyversation.xjcy.config.LocalDateFromTimestampDeserializer;
+import com.skyversation.xjcy.util.LocalDateTimeFromTimestampDeserializer;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Data
+public class ClueFollow implements FromJSON{
+    private String cClueCode;
+    private String cFollowupDescription;
+    private String cNextPlan;
+    private String cFollowerId;
+    @JSONField(deserializeUsing = LocalDateTimeFromTimestampDeserializer.class)
+    private LocalDateTime recordTime;
+}

+ 4 - 5
src/main/java/com/skyversation/xjcy/controller/CountController.java

@@ -1,7 +1,6 @@
 package com.skyversation.xjcy.controller;
 
-import com.skyversation.xjcy.counter.InvestmentPreCounter;
-import com.skyversation.xjcy.oauth.LoginService;
+import com.skyversation.xjcy.oauth.AuthService;
 import com.skyversation.xjcy.service.DataCountService;
 import com.skyversation.xjcy.service.InvestmentPreCountService;
 import com.skyversation.xjcy.service.ParkPreCountService;
@@ -34,7 +33,7 @@ public class CountController {
     @Resource
     InvestmentPreCountService investmentPreCountService;
     @Resource
-    LoginService loginService;
+    AuthService authService;
 
     @RequestMapping(value = "/town", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
     public String townCountData() {
@@ -99,7 +98,7 @@ public class CountController {
             return MessageManage.getInstance().getResultContent(-1,"参数不完整,lyCode和roomCode必须提供数据","参数不完整,lyCode和roomCode必须提供数据");
         }
         String token = request.getHeader("token");
-        if (!loginService.checkToken(token)) {
+        if (!authService.checkToken(token)) {
             return MessageManage.getInstance().getResultContent(-1,"未提供有效token","未提供有效token");
         }
         String[] roomCodes = roomCode.split(",");
@@ -113,7 +112,7 @@ public class CountController {
             return MessageManage.getInstance().getResultContent(-1,"参数不完整,lyCode必须提供数据","参数不完整,lyCode必须提供数据");
         }
         String token = request.getHeader("token");
-        if (!loginService.checkToken(token)) {
+        if (!authService.checkToken(token)) {
             return MessageManage.getInstance().getResultContent(-1,"未提供有效token","未提供有效token");
         }
         parkPreCountService.updateStructure(lyCode, token);

+ 38 - 0
src/main/java/com/skyversation/xjcy/controller/DataExportController.java

@@ -0,0 +1,38 @@
+package com.skyversation.xjcy.controller;
+
+import com.skyversation.xjcy.service.DataExportService;
+import com.skyversation.xjcy.util.FileIOData;
+import com.skyversation.xjcy.util.MessageManage;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.List;
+import java.util.Map;
+
+@Slf4j
+@Validated
+@RestController
+@RequestMapping("/export")
+public class DataExportController {
+    @Resource
+    DataExportService dataExportService;
+
+    @RequestMapping("/clue")
+    public String exportClue(HttpServletRequest request, HttpServletResponse response) {
+        try {
+            List<Map<String, Object>> data = dataExportService.exportClue();
+            FileIOData.exportExcelWithPreDefinedHeader(
+                    "徐泾镇招商项目(拿地)动态汇总表",
+                    FileIOData.PreDefinedHeader.CLUE,
+                    data, request, response);
+            return MessageManage.getInstance().getResultContent(200,"成功","成功");
+        } catch (Exception e) {
+            return MessageManage.getInstance().getResultContent(-1,"未知错误","未知错误");
+        }
+    }
+}

+ 3 - 1
src/main/java/com/skyversation/xjcy/dms/DMSColumn.java

@@ -8,7 +8,9 @@ public enum DMSColumn {
     ENTERPRISE_ECONOMIC("1594","1538"),
     ORDER("1587","1531"),
     LEASE_DETAIL("1574","1520"),
-    INVESTMENT_TARGET("1578","1523");
+    INVESTMENT_TARGET("1578","1523"),
+    CLUE("1576","1521"),
+    CLUE_FOLLOW("1577","1522");
     @Getter
     private final String id;
     @Getter

+ 6 - 0
src/main/java/com/skyversation/xjcy/dms/DMSQuery.java

@@ -69,6 +69,12 @@ public enum DMSQuery {
             request.addWhere("c_end_date", "3", indeedStartTime.format(formatter), timeOfFarAfter.format(formatter));
             return request;
         }
+    },
+    CLUE_FOLLOW(DMSColumn.CLUE_FOLLOW,ClueFollow.class) {
+        @Override
+        DMSRequest preRequest(LocalDate now) {
+            return new DMSRequest();
+        }
     };
 
     private final DMSColumn column;

+ 22 - 4
src/main/java/com/skyversation/xjcy/dms/DMSService.java

@@ -29,7 +29,7 @@ public class DMSService {
             this.dmsResult = dmsResult;
         }
     }
-    private Map<DMSQuery, QueryResult> queryCache = new HashMap<>();
+    private final Map<DMSQuery, QueryResult> queryCache = new HashMap<>();
 
     private JSONObject sendQueryToDms(DMSRequest request) {
         JSONObject jsonObject;
@@ -62,16 +62,16 @@ public class DMSService {
         return jsonObject;
     }
 
-    public String updateToDms(Collection<JSONObject> objs,String token,DMSColumn column) {
+    public void updateToDms(Collection<JSONObject> objs,String token,DMSColumn column) {
         if (objs == null || objs.isEmpty()) {
-            return null;
+            return;
         }
         MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
         params.add("modelId",column.getModelId());
         params.add("json",JSON.toJSONString(objs));
         Map<String,String> headers = new HashMap<>();
         headers.put("token", token);
-        return HttpUtil.requestPost(path+"/content/updateContentByJson",params,headers);
+        HttpUtil.requestPost(path+"/content/updateContentByJson",params,headers);
     }
     public String importToDms(Resource resource, String token, DMSImport importType) {
         MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
@@ -124,6 +124,24 @@ public class DMSService {
         return queryDmsList(new DMSRequest(), token, columId);
     }
 
+    public List<JSONObject> queryBeautified(String token,DMSColumn column) {
+        MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
+        params.add("columnId",column.getId());
+        Map<String,String> headers = new HashMap<>();
+        headers.put("token", token);
+        JSONObject object = JSON.parseObject(HttpUtil.requestPost(path+"/content/selectBeautified",params,headers));
+        if (Objects.equals(object.getString("code"), "200")) {
+            JSONArray content = object.getJSONArray("content");
+            List<JSONObject> list = new ArrayList<>();
+            for (int i = 0; i < content.size(); i++) {
+                JSONObject jsonObject = content.getJSONObject(i);
+                list.add(jsonObject);
+            }
+            return list;
+        }
+        return new ArrayList<>();
+    }
+
     public int getLargestCode(String token, String columId, String codeColumn, String today) {
         DMSRequest request = new DMSRequest();
         request.addWhere(codeColumn, "2", "%" + today + "%");

+ 1 - 3
src/main/java/com/skyversation/xjcy/oauth/LoginService.java → src/main/java/com/skyversation/xjcy/oauth/AuthService.java

@@ -2,7 +2,6 @@ package com.skyversation.xjcy.oauth;
 
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
-import com.skyversation.xjcy.dms.DMSService;
 import com.skyversation.xjcy.util.HttpUtil;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
@@ -11,12 +10,11 @@ import org.springframework.util.MultiValueMap;
 import org.springframework.util.StringUtils;
 
 import java.util.HashMap;
-import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.Objects;
 
 @Service
-public class LoginService {
+public class AuthService {
 
     @Value("${app.oauth.login-name}")
     private String loginName;

+ 8 - 8
src/main/java/com/skyversation/xjcy/service/DataCountService.java

@@ -6,7 +6,7 @@ import com.skyversation.xjcy.bean.*;
 import com.skyversation.xjcy.dms.DMSQuery;
 import com.skyversation.xjcy.dms.DMSService;
 import com.skyversation.xjcy.enums.EnterpriseLevel;
-import com.skyversation.xjcy.oauth.LoginService;
+import com.skyversation.xjcy.oauth.AuthService;
 import com.skyversation.xjcy.util.SpecialisationStringCollector;
 import com.skyversation.xjcy.util.TimeUtil;
 import lombok.NoArgsConstructor;
@@ -57,7 +57,7 @@ public class DataCountService {
 
     private final AtomicBoolean running = new AtomicBoolean(false);
     @Resource
-    private LoginService loginService;
+    private AuthService authService;
 
     @PostConstruct
     public void tryCount() {
@@ -119,12 +119,12 @@ public class DataCountService {
         LocalDate now = LocalDate.now();
 
         //数据量大不了所以不做流式
-        List<IndustrialPark> allIndustrialPark = dmsService.query(loginService.getToken(), DMSQuery.INDUSTRIAL_PARK, IndustrialPark.class, now);
-        List<Enterprise> allEnterprise = dmsService.query(loginService.getToken(), DMSQuery.ENTERPRISE, Enterprise.class, now);
-        List<EnterpriseEconomic> inDateEnterpriseEconomic = dmsService.query(loginService.getToken(), DMSQuery.ECONOMIC_ALL_INDEED, EnterpriseEconomic.class, now);
-        List<Order> allOrder = dmsService.query(loginService.getToken(), DMSQuery.ORDER, Order.class, now);
-        List<LeaseDetail> lastLeaseDetail = dmsService.query(loginService.getToken(), DMSQuery.LAST_LEASE_DETAIL, LeaseDetail.class, now);
-        List<LeaseDetail> lastYearLease = dmsService.query(loginService.getToken(), DMSQuery.LAST_YEAR_LEASE_DETAIL, LeaseDetail.class, now);
+        List<IndustrialPark> allIndustrialPark = dmsService.query(authService.getToken(), DMSQuery.INDUSTRIAL_PARK, IndustrialPark.class, now);
+        List<Enterprise> allEnterprise = dmsService.query(authService.getToken(), DMSQuery.ENTERPRISE, Enterprise.class, now);
+        List<EnterpriseEconomic> inDateEnterpriseEconomic = dmsService.query(authService.getToken(), DMSQuery.ECONOMIC_ALL_INDEED, EnterpriseEconomic.class, now);
+        List<Order> allOrder = dmsService.query(authService.getToken(), DMSQuery.ORDER, Order.class, now);
+        List<LeaseDetail> lastLeaseDetail = dmsService.query(authService.getToken(), DMSQuery.LAST_LEASE_DETAIL, LeaseDetail.class, now);
+        List<LeaseDetail> lastYearLease = dmsService.query(authService.getToken(), DMSQuery.LAST_YEAR_LEASE_DETAIL, LeaseDetail.class, now);
         //处理一下拿到的数据,建一建索引
         Map<String, List<EnterpriseEconomic>> enterpriseEconomicMap = new HashMap<>();
         inDateEnterpriseEconomic.forEach(e -> {

+ 65 - 0
src/main/java/com/skyversation/xjcy/service/DataExportService.java

@@ -0,0 +1,65 @@
+package com.skyversation.xjcy.service;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.skyversation.xjcy.bean.Clue;
+import com.skyversation.xjcy.bean.ClueFollow;
+import com.skyversation.xjcy.dms.DMSColumn;
+import com.skyversation.xjcy.dms.DMSQuery;
+import com.skyversation.xjcy.dms.DMSService;
+import com.skyversation.xjcy.oauth.AuthService;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
+import java.util.function.BinaryOperator;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+@Service
+public class DataExportService {
+    @Resource
+    DMSService dmsService;
+    @Resource
+    AuthService authService;
+    public enum ClueKey{
+        id,c_clue_code,c_clue_name,c_enterprise_name,enterprise_type,c_enterprise_introduction,industry,
+        industry_segment,industry_type,other_industry,construction_method,land_nature,land_area,property_area,
+        expected_investment,project_introduction,storage_time,responsible_leader,investment_manager,
+        c_expected_investment,c_economic_contribution,c_clue_source,c_contact_name,c_contact_phone,
+        c_intended_parcel_code,c_intended_building_code,c_clue_status,c_economic_zone_id,c_economic_zone_name,
+        c_responsible_person_id,c_responsible_person_name,create_time,author_id,update_time,c_updater
+    }
+    public List<Map<String, Object>> exportClue() {
+        List<Map<String,Object>> result = new ArrayList<>();
+        LocalDate now = LocalDate.now();
+        List<JSONObject> clues = dmsService.queryBeautified(authService.getToken(), DMSColumn.CLUE);
+        List<ClueFollow> clueFollows = dmsService.query(authService.getToken(), DMSQuery.CLUE_FOLLOW, ClueFollow.class,now);
+        //做map,仅留最近
+        Map<String,ClueFollow> newestClueFollows = clueFollows.stream()
+                .filter(f->f.getCClueCode()!=null)
+                .filter(f->f.getRecordTime()!=null)
+                .collect(Collectors.toMap(ClueFollow::getCClueCode,
+                        Function.identity(), BinaryOperator.maxBy(Comparator.comparing(ClueFollow::getRecordTime)))
+                );
+        for (int i = 0, cluesSize = clues.size(); i < cluesSize; i++) {
+            JSONObject clue = clues.get(i);
+            Map<String, Object> clueMap = new HashMap<>(clue);
+            result.add(clueMap);
+            //添加那个极端复杂的行
+            ClueFollow clueFollow = newestClueFollows.get(clue.getString(String.valueOf(ClueKey.c_clue_code)));
+            if (clueFollow != null) {
+                StringBuilder sb = new StringBuilder("入库时间:");
+                sb.append(clueFollow.getRecordTime().format(DateTimeFormatter.ofPattern("yyyy年M月d日")));
+                sb.append("\n");
+                sb.append(clueFollow.getCFollowupDescription());
+                clueMap.put("#last_week_progress", sb.toString());
+            }
+            clueMap.put("#index", i+1);
+        }
+        return result;
+    }
+}

+ 5 - 5
src/main/java/com/skyversation/xjcy/service/InvestmentPreCountService.java

@@ -6,7 +6,7 @@ import com.skyversation.xjcy.counter.InvestmentPreCounter;
 import com.skyversation.xjcy.dms.DMSColumn;
 import com.skyversation.xjcy.dms.DMSQuery;
 import com.skyversation.xjcy.dms.DMSService;
-import com.skyversation.xjcy.oauth.LoginService;
+import com.skyversation.xjcy.oauth.AuthService;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
@@ -18,15 +18,15 @@ public class InvestmentPreCountService {
     @Resource
     DMSService dmsService;
     @Resource
-    LoginService loginService;
+    AuthService authService;
     public List<JSONObject> updateAllTarget() {
         synchronized (InvestmentPreCounter.LOCK) {
             LocalDate now = LocalDate.now();
-            List<JSONObject> allTarget = dmsService.getAllInvestmentTarget(loginService.getToken());
-            List<Enterprise> allEnterprise = dmsService.query(loginService.getToken(), DMSQuery.ENTERPRISE,Enterprise.class,now);
+            List<JSONObject> allTarget = dmsService.getAllInvestmentTarget(authService.getToken());
+            List<Enterprise> allEnterprise = dmsService.query(authService.getToken(), DMSQuery.ENTERPRISE,Enterprise.class,now);
             InvestmentPreCounter preCounter = new InvestmentPreCounter(allTarget, allEnterprise);
             preCounter.run();
-            dmsService.updateToDms(preCounter.getTargetNeedUpload(), loginService.getToken(), DMSColumn.INVESTMENT_TARGET);
+            dmsService.updateToDms(preCounter.getTargetNeedUpload(), authService.getToken(), DMSColumn.INVESTMENT_TARGET);
             return allTarget;
         }
     }

+ 9 - 9
src/main/java/com/skyversation/xjcy/service/ParkPreCountService.java

@@ -4,7 +4,7 @@ import com.alibaba.fastjson.JSONObject;
 import com.skyversation.xjcy.counter.ParkPreCounter;
 import com.skyversation.xjcy.dms.DMSColumn;
 import com.skyversation.xjcy.dms.DMSService;
-import com.skyversation.xjcy.oauth.LoginService;
+import com.skyversation.xjcy.oauth.AuthService;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
@@ -22,7 +22,7 @@ public class ParkPreCountService {
     @Resource
     DMSService dmsService;
     @Resource
-    LoginService loginService;
+    AuthService authService;
 
     public void updateLimitInRooms(String LyCode, Collection<String> roomCodes, String token) {
         synchronized (ParkPreCounter.LOCK) {
@@ -38,24 +38,24 @@ public class ParkPreCountService {
 
     public void updateAllRoom() {
         synchronized (ParkPreCounter.LOCK) {
-            List<JSONObject> allPark = dmsService.getAllPark(loginService.getToken());
-            List<JSONObject> allLeaseByRooms = dmsService.getAllLease(loginService.getToken());
+            List<JSONObject> allPark = dmsService.getAllPark(authService.getToken());
+            List<JSONObject> allLeaseByRooms = dmsService.getAllLease(authService.getToken());
             LocalDate now = LocalDate.now();
             ParkPreCounter parkPreCounter = new ParkPreCounter(allPark, allLeaseByRooms, now);
             parkPreCounter.run();
-            dmsService.updateToDms(parkPreCounter.getParkNeedUpload(), loginService.getToken(), DMSColumn.INDUSTRIAL_PARK);
-            dmsService.updateToDms(parkPreCounter.getLeaseNeedUpload(), loginService.getToken(), DMSColumn.LEASE_DETAIL);
+            dmsService.updateToDms(parkPreCounter.getParkNeedUpload(), authService.getToken(), DMSColumn.INDUSTRIAL_PARK);
+            dmsService.updateToDms(parkPreCounter.getLeaseNeedUpload(), authService.getToken(), DMSColumn.LEASE_DETAIL);
         }
     }
 
     public void updateStructure(String lyCode, String token) {
         synchronized (ParkPreCounter.LOCK) {
-            List<JSONObject> allPark = dmsService.getAllPark(loginService.getToken());
+            List<JSONObject> allPark = dmsService.getAllPark(authService.getToken());
             LocalDate now = LocalDate.now();
             ParkPreCounter parkPreCounter = new ParkPreCounter(allPark, new ArrayList<>(), now);
             parkPreCounter.runWithOutLease();
-            dmsService.updateToDms(parkPreCounter.getParkNeedUpload(), loginService.getToken(), DMSColumn.INDUSTRIAL_PARK);
-            dmsService.updateToDms(parkPreCounter.getLeaseNeedUpload(), loginService.getToken(), DMSColumn.LEASE_DETAIL);
+            dmsService.updateToDms(parkPreCounter.getParkNeedUpload(), authService.getToken(), DMSColumn.INDUSTRIAL_PARK);
+            dmsService.updateToDms(parkPreCounter.getLeaseNeedUpload(), authService.getToken(), DMSColumn.LEASE_DETAIL);
         }
     }
 }

+ 3 - 3
src/main/java/com/skyversation/xjcy/service/SerialNumberGenerator.java

@@ -1,7 +1,7 @@
 package com.skyversation.xjcy.service;
 
 import com.skyversation.xjcy.dms.DMSService;
-import com.skyversation.xjcy.oauth.LoginService;
+import com.skyversation.xjcy.oauth.AuthService;
 import lombok.Getter;
 import org.springframework.stereotype.Service;
 
@@ -20,7 +20,7 @@ public class SerialNumberGenerator {
     @Resource
     private DMSService dmsService;
     @Resource
-    private LoginService loginService;
+    private AuthService authService;
 
     // 前缀枚举定义(可根据需要扩展)
     @Getter
@@ -63,7 +63,7 @@ public class SerialNumberGenerator {
     public void autoInit() {
         String token;
         try {
-            token = loginService.getToken();
+            token = authService.getToken();
         } catch (Exception e) {
             throw new RuntimeException(e);
         }

+ 128 - 0
src/main/java/com/skyversation/xjcy/util/FileIOData.java

@@ -0,0 +1,128 @@
+package com.skyversation.xjcy.util;
+
+import org.apache.poi.hssf.usermodel.*;
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.apache.poi.ss.usermodel.*;
+import org.springframework.core.io.ClassPathResource;
+import sun.misc.BASE64Encoder;
+
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.net.URLEncoder;
+import java.util.*;
+
+/**
+ * @ClassName fileImportData
+ * @Description TODO
+ * @Author @刘浩湉
+ * @Date 2022/8/8 11:16
+ * @Version 1.0
+ */
+public class FileIOData {
+
+    private FileIOData(){};
+
+    public static enum PreDefinedHeader {
+        CLUE {
+            @Override
+            public Workbook getWorkbook() {
+                Workbook workbook = null;
+                try {
+                    workbook = WorkbookFactory.create(new ClassPathResource("excel/predefine/clue.xlsx").getInputStream());
+                } catch (IOException | InvalidFormatException e) {
+                    return  workbook;
+                }
+                return workbook;
+            }
+
+            @Override
+            public List<String> getHeaders() {
+                return Arrays.asList("#skip","#index","c_clue_source","c_clue_name","industry","industry_segment",
+                        "industry_type","other_industry","c_enterprise_name","enterprise_type",
+                        "c_enterprise_introduction","construction_method","land_nature","land_area",
+                        "expected_investment","project_introduction","c_clue_status","#last_week_progress",
+                        "responsible_leader","c_economic_zone_name","c_responsible_person_name");
+            }
+        };
+        public abstract Workbook getWorkbook();
+        public abstract List<String> getHeaders();
+
+    }
+    public static void exportExcelWithPreDefinedHeader(String sheetName, PreDefinedHeader header, List<Map<String,Object>> data, HttpServletRequest request, HttpServletResponse response){
+        Workbook workbook = createWorkbook( header, data);
+
+        response.setContentType("application/vnd.ms-excel");
+        try {
+            //获取浏览器名称
+            String agent=request.getHeader("user-agent");
+            String filename=sheetName+".xls";
+            //不同浏览器需要对文件名做特殊处理
+            if (agent.contains("Firefox")) { // 火狐浏览器
+                filename = "=?UTF-8?B?"
+                        + new BASE64Encoder().encode(filename.getBytes("utf-8"))
+                        + "?=";
+                filename = filename.replaceAll("\r\n", "");
+            } else { // IE及其他浏览器
+                filename = URLEncoder.encode(filename, "utf-8");
+                filename = filename.replace("+"," ");
+            }
+            //推送浏览器
+            response.setHeader("Content-Disposition", "attachment;filename=" + filename);//UTF-8
+            ServletOutputStream out = response.getOutputStream();
+            workbook.write(out);
+            out.close();
+            workbook.close();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+    public static Workbook createWorkbook(PreDefinedHeader header, List<Map<String,Object>> data){
+        Workbook workbook = header.getWorkbook();
+        Sheet sheet = workbook.getSheet("sheet1");
+
+        Sheet hideSheet = workbook.getSheet("hide");
+        Row modelRow = hideSheet.getRow(0);
+
+
+        for (Map<String, Object> dataRow : data) {
+            Row row = sheet.createRow(sheet.getLastRowNum() + 1);
+            row.setHeight(modelRow.getHeight());
+            List<String> headers = header.getHeaders();
+            for (int i = 0, headersSize = headers.size(); i < headersSize; i++) {
+                String key = headers.get(i);
+                Cell modelCell = modelRow.getCell(i);
+                Cell cell = row.createCell(i);
+                if (modelCell != null) {
+                    cell.setCellStyle(modelCell.getCellStyle());
+                }
+                cell.setCellValue(dataRow.getOrDefault(key,"").toString());
+            }
+        }
+        return workbook;
+    }
+
+    public static void main(String[] args) throws Exception {
+        List<Map<String,Object>> data = new ArrayList<>();
+        Map<String,Object> map = new HashMap<>();
+        map.put("a","a");
+        map.put("b","b");
+        map.put("c","c");
+        data.add(map);
+        Map<String,Object> map2 = new HashMap<>();
+        map2.put("e","a1");
+        map2.put("f","b1");
+        map2.put("z","c1");
+        data.add(map2);
+
+        Workbook workbook = createWorkbook(PreDefinedHeader.CLUE,data);
+        FileOutputStream fos = new FileOutputStream("D:\\output\\result.xlsx");
+        workbook.write(fos);
+        fos.close();
+        workbook.close();
+    }
+}

+ 27 - 0
src/main/java/com/skyversation/xjcy/util/LocalDateTimeFromTimestampDeserializer.java

@@ -0,0 +1,27 @@
+package com.skyversation.xjcy.util;
+
+import com.alibaba.fastjson.parser.DefaultJSONParser;
+import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer;
+import java.lang.reflect.Type;
+import java.time.Instant;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+
+public class LocalDateTimeFromTimestampDeserializer implements ObjectDeserializer {
+    
+    @Override
+    public LocalDateTime deserialze(DefaultJSONParser parser, Type type, Object fieldName) {
+        // 从解析器中读取Long类型的时间戳
+        Long timestamp = parser.parseObject(Long.class);
+        if (timestamp == null) {
+            return null;
+        }
+        // 将时间戳转换为LocalDateTime
+        return LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), ZoneId.systemDefault());
+    }
+    
+    @Override
+    public int getFastMatchToken() {
+        return 0;
+    }
+}

+ 2 - 2
src/main/resources/application.yml

@@ -21,8 +21,8 @@ logging:
 app:
   count-cache-length: ${COUNT_CACHE_LENGTH:5000}
   dms:
-#    path: http://127.0.0.1:10081/dms
-    path: ${DMS_PATH:http://121.43.55.7:10081/dms}
+    path: http://127.0.0.1:10081/dms
+#    path: ${DMS_PATH:http://121.43.55.7:10081/dms}
   oauth:
     login-name: ${DMS_LOGIN_NAME:user_hj}
     password: ${DMS_PASSWORD:Hj@123456}