Sfoglia il codice sorgente

关于excel读取相关

chenendian 3 giorni fa
parent
commit
8b74790735

+ 222 - 0
siwei-modules/siwei-apply/src/main/java/com/siwei/apply/controller/third/DealExcelController.java

@@ -0,0 +1,222 @@
+package com.siwei.apply.controller.third;
+
+import com.siwei.apply.domain.LandOneCode;
+import com.siwei.apply.service.third.TakeDataService;
+import com.siwei.common.core.domain.R;
+import com.siwei.common.core.web.controller.BaseController;
+import lombok.RequiredArgsConstructor;
+import org.apache.poi.ss.usermodel.*;
+import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.springframework.web.bind.annotation.*;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.*;
+
+/**
+ *
+ * excel  处理器
+ */
+@RestController
+@RequestMapping("/public/excel")
+@RequiredArgsConstructor
+public class DealExcelController extends BaseController {
+    protected final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+    private final TakeDataService takeDataService;
+
+
+    /**
+     * 按ID查询
+     */
+    @GetMapping("{id}")
+    public R<LandOneCode> getById(@PathVariable String id) {
+        try {
+            return R.ok();
+        } catch (Exception e) {
+            return R.fail(e.getMessage());
+        }
+    }
+
+    /**
+     * 更新(按ID)
+     */
+    @PutMapping("zzz")
+    public R<Void> update(@RequestBody LandOneCode body) {
+        try {
+            return R.ok(null);
+        } catch (Exception e) {
+            return R.fail(e.getMessage());
+        }
+    }
+
+
+
+    /**
+     * 处理excel数据(按合并列头分组读取)
+     */
+    @GetMapping("excelDeal_v2")
+    public R<Map<String, List<Map<String,String>>>> excelDeal_v2() {
+        try {
+            String uploadFile = "D:\\workspace\\one-code-manage\\node_modules\\excel_deom\\project_info_v2.xlsx";
+            Path filePath = Paths.get(uploadFile);
+            File file = filePath.toFile();
+            Map<String, List<Map<String, String>>> dataMap = readExcelWithMergedHeaders(file);
+            for (Map.Entry<String, List<Map<String, String>>> entry : dataMap.entrySet()) {
+                logger.info("分类 [{}] 共 {} 条数据", entry.getKey(), entry.getValue().size());
+                for (int i = 0; i < entry.getValue().size(); i++) {
+                    logger.info("  第{}行: {}", i + 1, entry.getValue().get(i));
+                }
+            }
+            return R.ok(dataMap);
+        } catch (Exception e) {
+            return R.fail(e.getMessage());
+        }
+    }
+
+
+
+    /**
+     * 处理excel数据
+     */
+    @GetMapping("excelDeal")
+    public R<List<Map<String, Object>>> excelDeal() {
+        try {
+            // 获取地址:
+            String uploadFile =  "D:\\workspace\\one-code-manage\\node_modules\\excel_deom\\project_info_v2.xlsx";
+            // 构建文件的完整路径
+            Path filePath = Paths.get(uploadFile);
+            File file = filePath.toFile();
+            List<Map<String, Object>> dataList = readExcel(file);
+            for (int i = 0; i < dataList.size(); i++) {
+                logger.info("第{}行数据: {}", i + 1, dataList.get(i));
+            }
+            return R.ok(dataList);
+        } catch (Exception e) {
+            return R.fail(e.getMessage());
+        }
+    }
+
+
+
+
+    private List<Map<String, Object>> readExcel(File file) throws Exception {
+        List<Map<String, Object>> result = new ArrayList<>();
+        try (FileInputStream fis = new FileInputStream(file);
+             Workbook workbook = new XSSFWorkbook(fis)) {
+            Sheet sheet = workbook.getSheetAt(0);
+            if (sheet == null) {
+                return result;
+            }
+            Row headerRow = sheet.getRow(0);
+            if (headerRow == null) {
+                return result;
+            }
+            List<String> headers = new ArrayList<>();
+            for (int i = 0; i < headerRow.getPhysicalNumberOfCells(); i++) {
+                Cell cell = headerRow.getCell(i);
+                headers.add(cell == null ? "" : getCellValueAsString(cell));
+            }
+            for (int i = 1; i <= sheet.getLastRowNum(); i++) {
+                Row row = sheet.getRow(i);
+                if (row == null) {
+                    continue;
+                }
+                Map<String, Object> rowData = new LinkedHashMap<>();
+                for (int j = 0; j < headers.size(); j++) {
+                    Cell cell = row.getCell(j);
+                    rowData.put(headers.get(j), cell == null ? "" : getCellValueAsString(cell));
+                }
+                result.add(rowData);
+            }
+        }
+        return result;
+    }
+
+    /**
+     * 按合并列头分组读取Excel
+     * 第一行合并单元格作为分类key,第二行作为子列头,第三行起为数据
+     */
+    private Map<String, List<Map<String, String>>> readExcelWithMergedHeaders(File file) throws Exception {
+        Map<String, List<Map<String, String>>> result = new LinkedHashMap<>();
+        try (FileInputStream fis = new FileInputStream(file);
+             Workbook workbook = new XSSFWorkbook(fis)) {
+            Sheet sheet = workbook.getSheetAt(0);
+            if (sheet == null) {
+                return result;
+            }
+            List<CellRangeAddress> mergedRegions = sheet.getMergedRegions();
+            if (mergedRegions == null || mergedRegions.isEmpty()) {
+                return result;
+            }
+            Row subHeaderRow = sheet.getRow(1);
+            if (subHeaderRow == null) {
+                return result;
+            }
+            for (CellRangeAddress region : mergedRegions) {
+                // 只处理第一行的合并区域
+                if (region.getFirstRow() != 0) {
+                    continue;
+                }
+                Cell categoryCell = sheet.getRow(0).getCell(region.getFirstColumn());
+                String category = categoryCell == null ? "" : getCellValueAsString(categoryCell).trim().replace("\n", "");
+                if (category.isEmpty()) {
+                    continue;
+                }
+                // 读取子列头(Row 2)
+                List<String> subHeaders = new ArrayList<>();
+                for (int col = region.getFirstColumn(); col <= region.getLastColumn(); col++) {
+                    Cell hCell = subHeaderRow.getCell(col);
+                    subHeaders.add(hCell == null ? "" : getCellValueAsString(hCell).trim().replace("\n", ""));
+                }
+                // 读取数据行(Row 3+)
+                List<Map<String, String>> rows = new ArrayList<>();
+                for (int rowIdx = 2; rowIdx <= sheet.getLastRowNum(); rowIdx++) {
+                    Row dataRow = sheet.getRow(rowIdx);
+                    if (dataRow == null) {
+                        continue;
+                    }
+                    Map<String, String> rowMap = new LinkedHashMap<>();
+                    for (int j = 0; j < subHeaders.size(); j++) {
+                        Cell cell = dataRow.getCell(region.getFirstColumn() + j);
+                        rowMap.put(subHeaders.get(j), cell == null ? "" : getCellValueAsString(cell));
+                    }
+                    rows.add(rowMap);
+                }
+                result.put(category, rows);
+            }
+        }
+        return result;
+    }
+
+    private String getCellValueAsString(Cell cell) {
+        if (cell == null) {
+            return "";
+        }
+        switch (cell.getCellType()) {
+            case STRING:
+                return cell.getStringCellValue();
+            case NUMERIC:
+                if (DateUtil.isCellDateFormatted(cell)) {
+                    return cell.getDateCellValue().toString();
+                }
+                double numVal = cell.getNumericCellValue();
+                if (numVal == (long) numVal) {
+                    return String.valueOf((long) numVal);
+                }
+                return String.valueOf(numVal);
+            case BOOLEAN:
+                return String.valueOf(cell.getBooleanCellValue());
+            case FORMULA:
+                return cell.getCellFormula();
+            default:
+                return "";
+        }
+    }
+}

+ 81 - 4
siwei-modules/siwei-apply/src/main/java/com/siwei/apply/utils/MdbUtil.java

@@ -357,22 +357,99 @@ public class MdbUtil {
 
 
 
+//    /**
+//     *  判断两个List<Map<String, Object>>中的数据是否完全一致
+//     * (排除map中的geom字段和valid_flag字段的比较,针对其他字段值做比较)
+//     * @param dbDataList  之前图层数据列表 (从数据库查询出来的图层数据列表)
+//     * @param layerDataList 图层数据列表
+//     * @return
+//     */
+//    private boolean validMapSameData(List<Map<String, Object>> dbDataList, List<Map<String, Object>> layerDataList) {
+//
+//
+//
+//        return true;
+//    }
+
+
     /**
-     *  判断两个List<Map<String, Object>>中的数据是否完全一致
+     * 判断两个List<Map<String, Object>>中的数据是否完全一致
      * (排除map中的geom字段和valid_flag字段的比较,针对其他字段值做比较)
-     * @param dbDataList  之前图层数据列表 (从数据库查询出来的图层数据列表)
-     * @param layerDataList 图层数据列表
-     * @return
+     * @param dbDataList    数据库查询出来的图层数据列表
+     * @param layerDataList 前端/图层传入的数据列表
+     * @return 数据完全一致返回true,不一致返回false
      */
     private boolean validMapSameData(List<Map<String, Object>> dbDataList, List<Map<String, Object>> layerDataList) {
+        // 1. 先判断集合是否都为null
+        if (dbDataList == null && layerDataList == null) {
+            return true;
+        }
+        // 2. 一个null一个非null → 不相等
+        if (dbDataList == null || layerDataList == null) {
+            return false;
+        }
+        // 3. 数量不一样 → 直接不相等
+        if (dbDataList.size() != layerDataList.size()) {
+            return false;
+        }
 
+        // 4. 逐行对比
+        for (int i = 0; i < dbDataList.size(); i++) {
+            Map<String, Object> dbMap = dbDataList.get(i);
+            Map<String, Object> layerMap = layerDataList.get(i);
 
+            // 逐行内部对比(排除geom、valid_flag)
+            if (!compareSingleMapIgnoreKeys(dbMap, layerMap, "geom", "valid_flag")) {
+                return false;
+            }
+        }
 
+        // 所有行都一致
         return true;
     }
 
 
 
 
+    /**
+     * 对比两个Map,忽略指定的key,其他所有key必须值完全一致
+     */
+    private boolean compareSingleMapIgnoreKeys(Map<String, Object> map1,
+                                               Map<String, Object> map2,
+                                               String... ignoreKeys) {
+        if (map1 == null && map2 == null) return true;
+        if (map1 == null || map2 == null) return false;
+
+        Set<String> ignoreSet = new HashSet<>(Arrays.asList(ignoreKeys));
+
+        // 只对比需要比较的key
+        Set<String> allKeys = new HashSet<>();
+        allKeys.addAll(map1.keySet());
+        allKeys.addAll(map2.keySet());
+        allKeys.removeAll(ignoreSet);
+
+        for (String key : allKeys) {
+            Object v1 = map1.get(key);
+            Object v2 = map2.get(key);
+
+            // 处理 null 情况
+            if (v1 == null && v2 == null) {
+                continue;
+            }
+            if (v1 == null || v2 == null) {
+                return false;
+            }
+
+            // 正常对比(支持日期、数字、字符串等)
+            if (!v1.equals(v2)) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+
+
 
 }