|
|
@@ -0,0 +1,317 @@
|
|
|
+package com.ruoyi.interfaces.utils;
|
|
|
+
|
|
|
+import com.ruoyi.interfaces.domain.MdDataSetParam;
|
|
|
+import org.apache.poi.ss.usermodel.*;
|
|
|
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
|
|
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
|
|
+
|
|
|
+import java.io.File;
|
|
|
+import java.io.FileInputStream;
|
|
|
+import java.util.*;
|
|
|
+import java.util.function.Predicate;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 增强的Excel解析工具类 - 支持数据检索
|
|
|
+ */
|
|
|
+public class ExcelParser {
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据参数配置解析Excel数据
|
|
|
+ *
|
|
|
+ * @param file Excel文件
|
|
|
+ * @param params 查询参数配置列表
|
|
|
+ * @return 符合条件的数据列表
|
|
|
+ */
|
|
|
+ public static List<Map<String, String>> parseExcelWithParams(File file, List<MdDataSetParam> params) throws Exception {
|
|
|
+ Predicate<Map<String, String>> filter = buildFilterFromParams(params);
|
|
|
+ return parseExcel(file, filter);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据参数配置解析Excel数据(支持排序)
|
|
|
+ *
|
|
|
+ * @param file Excel文件
|
|
|
+ * @param params 查询参数配置列表
|
|
|
+ * @param sortParams 排序参数
|
|
|
+ * @return 符合条件并排序的数据列表
|
|
|
+ */
|
|
|
+ public static List<Map<String, String>> parseExcelWithParams(File file,
|
|
|
+ List<MdDataSetParam> params,
|
|
|
+ List<MdDataSetParam> sortParams) throws Exception {
|
|
|
+ List<Map<String, String>> result = parseExcelWithParams(file, params);
|
|
|
+
|
|
|
+ if (sortParams != null && !sortParams.isEmpty()) {
|
|
|
+ result = sortData(result, sortParams);
|
|
|
+ }
|
|
|
+
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 从参数配置构建过滤条件
|
|
|
+ */
|
|
|
+ private static Predicate<Map<String, String>> buildFilterFromParams(List<MdDataSetParam> params) {
|
|
|
+ if (params == null || params.isEmpty()) {
|
|
|
+ return record -> true; // 无参数时返回所有记录
|
|
|
+ }
|
|
|
+
|
|
|
+ Predicate<Map<String, String>> filter = record -> true;
|
|
|
+
|
|
|
+ for (MdDataSetParam param : params) {
|
|
|
+ if (param.getParamCode() == null || param.getSymbol() == null) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ Predicate<Map<String, String>> condition = buildSingleCondition(param);
|
|
|
+ filter = filter.and(condition);
|
|
|
+ }
|
|
|
+
|
|
|
+ return filter;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 构建单个查询条件
|
|
|
+ */
|
|
|
+ private static Predicate<Map<String, String>> buildSingleCondition(MdDataSetParam param) {
|
|
|
+ String columnName = param.getParamCode(); // 使用paramCode作为列名
|
|
|
+ String symbol = param.getSymbol();
|
|
|
+ String value = param.getParamValue();
|
|
|
+
|
|
|
+ return record -> {
|
|
|
+ String recordValue = record.get(columnName);
|
|
|
+ if (recordValue == null) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ switch (symbol) {
|
|
|
+ case "=":
|
|
|
+ return recordValue.equals(value);
|
|
|
+ case "!=":
|
|
|
+ return !recordValue.equals(value);
|
|
|
+ case ">":
|
|
|
+ return compareNumeric(recordValue, value) > 0;
|
|
|
+ case ">=":
|
|
|
+ return compareNumeric(recordValue, value) >= 0;
|
|
|
+ case "<":
|
|
|
+ return compareNumeric(recordValue, value) < 0;
|
|
|
+ case "<=":
|
|
|
+ return compareNumeric(recordValue, value) <= 0;
|
|
|
+ case "contains":
|
|
|
+ return recordValue.contains(value);
|
|
|
+ case "startsWith":
|
|
|
+ return recordValue.startsWith(value);
|
|
|
+ case "endsWith":
|
|
|
+ return recordValue.endsWith(value);
|
|
|
+ case "in":
|
|
|
+ return value != null && Arrays.asList(value.split(",")).contains(recordValue);
|
|
|
+ case "notIn":
|
|
|
+ return value != null && !Arrays.asList(value.split(",")).contains(recordValue);
|
|
|
+ case "like":
|
|
|
+ return likeMatch(recordValue, value);
|
|
|
+ default:
|
|
|
+ return true; // 未知符号默认返回true
|
|
|
+ }
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 数值比较
|
|
|
+ */
|
|
|
+ private static int compareNumeric(String value1, String value2) {
|
|
|
+ try {
|
|
|
+ double num1 = Double.parseDouble(value1);
|
|
|
+ double num2 = Double.parseDouble(value2);
|
|
|
+ return Double.compare(num1, num2);
|
|
|
+ } catch (NumberFormatException e) {
|
|
|
+ // 如果不能转换为数字,则按字符串比较
|
|
|
+ return value1.compareTo(value2);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * SQL LIKE 模式匹配
|
|
|
+ */
|
|
|
+ private static boolean likeMatch(String text, String pattern) {
|
|
|
+ if (text == null || pattern == null) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 将SQL LIKE模式转换为正则表达式
|
|
|
+ String regex = pattern
|
|
|
+ .replace("%", ".*")
|
|
|
+ .replace("_", ".");
|
|
|
+
|
|
|
+ return text.matches(regex);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 数据排序
|
|
|
+ */
|
|
|
+ private static List<Map<String, String>> sortData(List<Map<String, String>> data, List<MdDataSetParam> sortParams) {
|
|
|
+ if (data == null || data.isEmpty() || sortParams == null) {
|
|
|
+ return data;
|
|
|
+ }
|
|
|
+
|
|
|
+ data.sort((map1, map2) -> {
|
|
|
+ for (MdDataSetParam sortParam : sortParams) {
|
|
|
+ String columnName = sortParam.getParamCode();
|
|
|
+ String sortOrder = sortParam.getParamValue(); // 使用paramValue存储排序方向:ASC/DESC
|
|
|
+
|
|
|
+ String value1 = map1.get(columnName);
|
|
|
+ String value2 = map2.get(columnName);
|
|
|
+
|
|
|
+ int comparison;
|
|
|
+
|
|
|
+ // 尝试数值比较
|
|
|
+ try {
|
|
|
+ double num1 = Double.parseDouble(value1);
|
|
|
+ double num2 = Double.parseDouble(value2);
|
|
|
+ comparison = Double.compare(num1, num2);
|
|
|
+ } catch (NumberFormatException e) {
|
|
|
+ // 数值比较失败,使用字符串比较
|
|
|
+ comparison = value1.compareTo(value2);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果是降序,反转比较结果
|
|
|
+ if ("DESC".equalsIgnoreCase(sortOrder)) {
|
|
|
+ comparison = -comparison;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (comparison != 0) {
|
|
|
+ return comparison;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+ });
|
|
|
+
|
|
|
+ return data;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 基础解析方法
|
|
|
+ */
|
|
|
+ private static List<Map<String, String>> parseExcel(File file, Predicate<Map<String, String>> filter) throws Exception {
|
|
|
+ List<Map<String, String>> allData = parseExcelData(file);
|
|
|
+
|
|
|
+ if (filter == null) {
|
|
|
+ return allData;
|
|
|
+ }
|
|
|
+
|
|
|
+ return allData.stream()
|
|
|
+ .filter(filter)
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Excel数据解析核心方法
|
|
|
+ */
|
|
|
+ private static List<Map<String, String>> parseExcelData(File file) throws Exception {
|
|
|
+ // 这里使用你之前提供的Excel解析逻辑
|
|
|
+ List<Map<String, String>> resultList = new ArrayList<>();
|
|
|
+ FileInputStream fis = new FileInputStream(file);
|
|
|
+ Workbook workbook;
|
|
|
+
|
|
|
+ String fileName = file.getName().toLowerCase();
|
|
|
+ if (fileName.endsWith(".xlsx")) {
|
|
|
+ workbook = new XSSFWorkbook(fis);
|
|
|
+ } else if (fileName.endsWith(".xls")) {
|
|
|
+ workbook = new HSSFWorkbook(fis);
|
|
|
+ } else {
|
|
|
+ fis.close();
|
|
|
+ throw new IllegalArgumentException("不支持的文件格式,仅支持.xls和.xlsx格式");
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ Sheet sheet = workbook.getSheetAt(0);
|
|
|
+ Row headerRow = sheet.getRow(0);
|
|
|
+ if (headerRow == null) {
|
|
|
+ throw new RuntimeException("Excel文件没有数据");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 读取所有列名
|
|
|
+ List<String> columnNames = new ArrayList<>();
|
|
|
+ for (int j = 0; j < headerRow.getLastCellNum(); j++) {
|
|
|
+ Cell headerCell = headerRow.getCell(j);
|
|
|
+ if (headerCell != null) {
|
|
|
+ String columnName = getCellValue(headerCell);
|
|
|
+ if (columnName != null && !columnName.trim().isEmpty()) {
|
|
|
+ columnNames.add(columnName);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 读取数据行
|
|
|
+ for (int i = 1; i <= sheet.getLastRowNum(); i++) {
|
|
|
+ Row row = sheet.getRow(i);
|
|
|
+ if (row == null) continue;
|
|
|
+
|
|
|
+ Map<String, String> rowMap = new LinkedHashMap<>();
|
|
|
+ boolean hasData = false;
|
|
|
+
|
|
|
+ for (int j = 0; j < columnNames.size(); j++) {
|
|
|
+ String columnName = columnNames.get(j);
|
|
|
+ Cell dataCell = j < row.getLastCellNum() ? row.getCell(j) : null;
|
|
|
+ String cellValue = dataCell != null ? getCellValue(dataCell) : "";
|
|
|
+
|
|
|
+ if (cellValue != null && !cellValue.trim().isEmpty()) {
|
|
|
+ hasData = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ rowMap.put(columnName, cellValue != null ? cellValue : "");
|
|
|
+ }
|
|
|
+
|
|
|
+ if (hasData) {
|
|
|
+ resultList.add(rowMap);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } finally {
|
|
|
+ workbook.close();
|
|
|
+ fis.close();
|
|
|
+ }
|
|
|
+
|
|
|
+ return resultList;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static String getCellValue(Cell cell) {
|
|
|
+ // 你之前提供的getCellValue方法实现
|
|
|
+ if (cell == null) return "";
|
|
|
+
|
|
|
+ switch (cell.getCellType()) {
|
|
|
+ case STRING:
|
|
|
+ return cell.getStringCellValue().trim();
|
|
|
+ case NUMERIC:
|
|
|
+ if (DateUtil.isCellDateFormatted(cell)) {
|
|
|
+ return cell.getDateCellValue().toString();
|
|
|
+ } else {
|
|
|
+ double num = cell.getNumericCellValue();
|
|
|
+ if (num == (long) num) {
|
|
|
+ return String.valueOf((long) num);
|
|
|
+ } else {
|
|
|
+ return String.valueOf(num);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ case BOOLEAN:
|
|
|
+ return String.valueOf(cell.getBooleanCellValue());
|
|
|
+ case FORMULA:
|
|
|
+ try {
|
|
|
+ FormulaEvaluator evaluator = cell.getSheet().getWorkbook().getCreationHelper().createFormulaEvaluator();
|
|
|
+ CellValue cellValue = evaluator.evaluate(cell);
|
|
|
+ switch (cellValue.getCellType()) {
|
|
|
+ case NUMERIC:
|
|
|
+ return String.valueOf(cellValue.getNumberValue());
|
|
|
+ case STRING:
|
|
|
+ return cellValue.getStringValue();
|
|
|
+ case BOOLEAN:
|
|
|
+ return String.valueOf(cellValue.getBooleanValue());
|
|
|
+ default:
|
|
|
+ return cell.getCellFormula();
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ return cell.getCellFormula();
|
|
|
+ }
|
|
|
+ default:
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|