Browse Source

excel导入bug

liuyc 2 years ago
parent
commit
4fa85fdd6a

+ 148 - 55
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/WbsTreeContractController.java

@@ -2,19 +2,24 @@ package org.springblade.manager.controller;
 
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+import com.spire.xls.FileFormat;
+import com.spire.xls.Worksheet;
 import io.swagger.annotations.*;
 import lombok.AllArgsConstructor;
 import org.apache.commons.lang.StringUtils;
-import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
-import org.apache.poi.ss.usermodel.*;
 import org.jsoup.Jsoup;
 import org.jsoup.nodes.Document;
 import org.jsoup.nodes.Element;
 import org.jsoup.select.Elements;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springblade.common.utils.CommonUtil;
+import org.springblade.common.utils.SnowFlakeUtil;
 import org.springblade.core.boot.ctrl.BladeController;
 import org.springblade.core.log.exception.ServiceException;
 import org.springblade.core.tool.api.R;
+import org.springblade.core.tool.utils.IoUtil;
+import org.springblade.core.tool.utils.ResourceUtil;
 import org.springblade.manager.dto.WbsTreeContractDTO2;
 import org.springblade.manager.entity.ContractInfo;
 import org.springblade.manager.entity.ExcelTab;
@@ -22,8 +27,9 @@ import org.springblade.manager.entity.WbsTreeContract;
 import org.springblade.manager.feign.ContractClient;
 import org.springblade.manager.service.IWbsTreeContractService;
 import org.springblade.manager.service.impl.WbsTreeContractServiceImpl;
-import org.springblade.manager.utils.ExcelParser;
+import org.springblade.manager.utils.FileUtils;
 import org.springblade.manager.vo.*;
+import org.springblade.resource.feign.NewIOSSClient;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.redis.core.StringRedisTemplate;
 import org.springframework.jdbc.core.BeanPropertyRowMapper;
@@ -35,9 +41,13 @@ import javax.servlet.ServletOutputStream;
 import javax.servlet.http.HttpServletResponse;
 import java.io.*;
 import java.net.URLEncoder;
-import java.text.ParseException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
 import java.text.SimpleDateFormat;
 import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 @RestController
 @AllArgsConstructor
@@ -48,9 +58,11 @@ public class WbsTreeContractController extends BladeController {
     @Autowired
     StringRedisTemplate redisTemplate;
     private final JdbcTemplate jdbcTemplate;
+    private final NewIOSSClient newIOSSClient;
     private final IWbsTreeContractService iWbsTreeContractService;
     private final WbsTreeContractServiceImpl wbsTreeContractServiceImpl;
     private final ContractClient contractClient;
+    private static Logger logger = LoggerFactory.getLogger(WbsTreeContractController.class);
 
     @GetMapping("/search-node-tables")
     @ApiOperationSupport(order = 1)
@@ -224,7 +236,7 @@ public class WbsTreeContractController extends BladeController {
         if (StringUtils.isNotEmpty(primaryKeyId)) {
             parentId = primaryKeyId;
         }
-        List<WbsTreeContractLazyVO> vos = iWbsTreeContractService.imageLazyQueryContractWbsTree(parentId, contractId, contractIdRelation,classId);
+        List<WbsTreeContractLazyVO> vos = iWbsTreeContractService.imageLazyQueryContractWbsTree(parentId, contractId, contractIdRelation, classId);
         return R.data(vos);
     }
 
@@ -333,77 +345,158 @@ public class WbsTreeContractController extends BladeController {
     @ApiOperation(value = "客户端-导入excel数据到对应元素表中", notes = "传入表的pKeyId、excel文件file")
     public R<Map<String, Object>> importExcel(@RequestParam String pKeyId, @RequestPart MultipartFile file) throws Exception {
         //获取当前表htmlString
-        String htmlString = wbsTreeContractServiceImpl.getHtmlString(pKeyId);
-        if (StringUtils.isEmpty(htmlString)) {
+        String htmlString_1 = wbsTreeContractServiceImpl.getHtmlString(pKeyId);
+        if (StringUtils.isEmpty(htmlString_1)) {
             throw new ServiceException("获取元素表html信息失败");
         }
 
-        //获取excel数据
-        Map<String, String> stringStringMap = ExcelParser.parseExcel(file);
-
-        //匹配定位
-        Map<String, Object> resultDataMap = new LinkedHashMap<>();
-        Document doc = Jsoup.parse(htmlString);
-        for (Map.Entry<String, String> stringStringEntry : stringStringMap.entrySet()) {
-            String value = stringStringEntry.getValue();
-            if (StringUtils.isNotEmpty(value)) {
-                String[] split = stringStringEntry.getKey().split("_");
-                int row = Integer.parseInt(split[0]) + 1;
-                int cell = Integer.parseInt(split[1]) + 1;
-                String selectorValue = "td:has(el-date-picker[x1=" + cell + "][y1=" + row + "])," +
-                        "td:has(el-input[x1=" + cell + "][y1=" + row + "])," +
-                        "td:has(hc-form-select-search[x1=" + cell + "][y1=" + row + "])," +
-                        "td:has(hc-table-form-upload[x1=" + cell + "][y1=" + row + "])," +
-                        "td:has(hc-form-checkbox-group[x1=" + cell + "][y1=" + row + "])," +
-                        "td:has(el-radio-group[x1=" + cell + "][y1=" + row + "])," +
-                        "td:has(el-select[x1=" + cell + "][y1=" + row + "])";
-                Elements tdElementsValues = doc.select(selectorValue);
-                if (!tdElementsValues.isEmpty()) {
-                    Elements childElements = tdElementsValues.select("el-input, el-date-picker, hc-form-select-search, hc-table-form-upload, hc-form-checkbox-group, el-radio-group, el-select");
-                    for (Element childElement : childElements) {
-                        String keyName = childElement.attr("keyname");
-                        if (StringUtils.isNotEmpty(keyName)) {
-                            String dateFormatPattern = "yyyy年MM月dd日-yyyy年MM月dd日";
-                            if (isValidDateFormat(value, dateFormatPattern)) {
-                                //解析日期格式是否为范围格式,范围日期返回数组
-                                String[] splitDate = value.split("-");
-                                List<String> strings = Arrays.asList(splitDate[0], splitDate[1]);
-                                resultDataMap.put(keyName, strings);
-                            } else if (value.contains("年") && value.contains("月") && value.contains("日")) {
-                                //解析日期格式是否为单日期格式,那么剔除空格返回
-                                String replace = value.replace(" ", "");
-                                if (!replace.equals("年月日")) {//如果为空那么不返回
-                                    resultDataMap.put(keyName, replace);
+        //结果集
+        Map<String, Object> stringStringMap = new HashMap<>();
+
+        //日期格式正则
+        String doubleSlashRegex_XG = ".*\\/[^\\/]*\\/.*"; //匹配包含两个斜杠且不相邻的字符串
+        String dateFormatRegex_yyyyMdd = "\\d{4}/\\d{1,2}/\\d{1,2}"; //yyyy/M/dd格式
+        String dateFormatRegex_yyyyMMdd = "\\d{4}/\\d{2}/\\d{2}";   //yyyy/MM/dd格式
+        SimpleDateFormat inputDateFormat = new SimpleDateFormat("yyyy/M/dd");
+        SimpleDateFormat outputDateFormat = new SimpleDateFormat("yyyy年MM月dd日");
+
+        //把导入的excel转换为html
+        Long id = SnowFlakeUtil.getId();
+        String importExcelFilePath = FileUtils.getSysLocalFileUrl();
+        String importExcelTOHtmlPath = importExcelFilePath + "/pdf//" + id + ".html";
+
+        //解析匹配数据
+        String url_1 = "";
+        com.spire.xls.Workbook workbook = null;
+        try {
+            workbook = new com.spire.xls.Workbook();
+            workbook.loadFromHtml(file.getInputStream());
+            workbook.saveToFile(importExcelTOHtmlPath, FileFormat.HTML);
+            Worksheet sheet = workbook.getWorksheets().get(0); //始终只匹配第一张表
+            //获取转换成功后的html路径
+            url_1 = importExcelTOHtmlPath.split("pdf//")[0];
+            String excelToHtmlFileUrl = url_1 + "/pdf/" + id + "_files/" + sheet.getName() + ".html";
+            String htmlString_2 = IoUtil.readToString(new FileInputStream(ResourceUtil.getFile(excelToHtmlFileUrl)));
+            //循环遍历解析tr、td
+            Document doc_1 = Jsoup.parse(htmlString_1);
+            Document doc_2 = Jsoup.parse(htmlString_2);
+            Elements trElements1 = doc_1.select("table tbody tr");
+            Elements trElements2 = doc_2.select("table tbody tr");
+            for (int i = 0; i < trElements1.size(); i++) {
+                Element tr1 = trElements1.get(i);
+                Element tr2 = trElements2.get(i);
+                Elements tdElements1 = tr1.select("td");
+                Elements tdElements2 = tr2.select("td");
+                for (int j = 0; j < tdElements1.size(); j++) {
+                    Element td1 = tdElements1.get(j);
+                    Element td2 = tdElements2.get(j);
+                    //String x1 = getX1Attribute(td1);
+                    //String y1 = getY1Attribute(td1);
+                    String keyName = getKeyNameFromChildElement(td1);
+                    if (StringUtils.isNotEmpty(keyName)/*&& StringUtils.isNotEmpty(x1) && StringUtils.isNotEmpty(y1)*/) {
+                        String divValue = td2.select("div").text();
+                        if (StringUtils.isNotEmpty(divValue)) {
+                            //判断是否存在两个斜杠,且不在一起,那么视为日期格式
+                            Pattern pattern_XG = Pattern.compile(doubleSlashRegex_XG);
+                            Matcher matcher_XG = pattern_XG.matcher(divValue);
+                            if (matcher_XG.matches()) {
+                                //判断日期格式yyyy/M/dd、yyyy/MM/dd
+                                Pattern pattern_yyyyMdd = Pattern.compile(dateFormatRegex_yyyyMdd);
+                                Pattern pattern_yyyyMMdd = Pattern.compile(dateFormatRegex_yyyyMMdd);
+                                Matcher matcher_yyyyMdd = pattern_yyyyMdd.matcher(divValue);
+                                Matcher matcher_yyyyMMdd = pattern_yyyyMMdd.matcher(divValue);
+                                if (matcher_yyyyMdd.matches()) {
+                                    Date date = inputDateFormat.parse(divValue);
+                                    divValue = outputDateFormat.format(date);
+                                } else if (matcher_yyyyMMdd.matches()) {
+                                    Date date = inputDateFormat.parse(divValue);
+                                    divValue = outputDateFormat.format(date);
                                 }
-                            } else {
-                                resultDataMap.put(keyName, value);
                             }
+                            //String mapKey = keyName + "***" + x1 + "_" + y1;
+                            stringStringMap.put(keyName, divValue);
                         }
                     }
                 }
             }
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            if (workbook != null) {
+                workbook.dispose();
+            }
         }
-        if (resultDataMap.size() > 0) {
-            List<Map.Entry<String, Object>> entryList = new ArrayList<>(resultDataMap.entrySet());
+        if (stringStringMap.size() > 0) {
+            List<Map.Entry<String, Object>> entryList = new ArrayList<>(stringStringMap.entrySet());
             entryList.sort(new KeyComparator());
             LinkedHashMap<String, Object> sortedMap = new LinkedHashMap<>();
             for (Map.Entry<String, Object> entry : entryList) {
                 sortedMap.put(entry.getKey(), entry.getValue());
             }
+            //删除临时文件信息
+            if (deleteFolder(Paths.get(importExcelTOHtmlPath))) {
+                logger.info("执行方法【importExcel】结束,删除临时文件成功!");
+            } else {
+                logger.info("执行方法【importExcel】结束,删除临时文件失败!");
+            }
+            if (StringUtils.isNotEmpty(url_1)) {
+                //删除临时文件夹
+                if (deleteFolderAndContents(Paths.get(url_1 + "/pdf/" + id + "_files"))) {
+                    logger.info("执行方法【importExcel】结束,删除临时文件夹成功!");
+                } else {
+                    logger.info("执行方法【importExcel】结束,删除临时文件夹失败!");
+                }
+            }
             return R.data(sortedMap);
         }
         return R.fail("没有获取到填写的数据");
     }
 
-    private static boolean isValidDateFormat(String dateString, String formatPattern) {
-        SimpleDateFormat sdf = new SimpleDateFormat(formatPattern);
-        sdf.setLenient(false);
-        try {
-            Date date = sdf.parse(dateString);
-            return date != null && sdf.format(date).equals(dateString);
-        } catch (ParseException e) {
-            return false;
+    private static boolean deleteFolder(Path folderPath) throws IOException {
+        if (Files.exists(folderPath)) {
+            Files.walk(folderPath)
+                    .sorted(Comparator.reverseOrder())
+                    .map(Path::toFile)
+                    .forEach(File::delete);
+            return true;
+        }
+        return false;
+    }
+
+    private static boolean deleteFolderAndContents(Path folderPath) throws IOException {
+        if (Files.exists(folderPath)) {
+            Files.walk(folderPath)
+                    .sorted(Comparator.reverseOrder())
+                    .map(Path::toFile)
+                    .forEach(File::delete);
+            return true;
+        }
+        return false;
+    }
+
+    private static String getX1Attribute(Element element) {
+        return element.select("[x1]").attr("x1");
+    }
+
+    private static String getY1Attribute(Element element) {
+        return element.select("[y1]").attr("y1");
+    }
+
+    private static String getKeyNameFromChildElement(Element element) {
+        //TODO Element UI的时间标签待补全
+        String[] tagNames = {"el-input", "el-date-picker", "el-time-picker", "hc-form-select-search", "hc-table-form-upload", "hc-form-checkbox-group", "el-radio-group", "el-select"};
+        for (String tagName : tagNames) {
+            Element childElement = element.select(tagName).first();
+            if (childElement != null) {
+                String keyName = childElement.attr("keyname");
+                if (StringUtils.isNotEmpty(keyName)) {
+                    return keyName;
+                } else {
+                    return childElement.attr("id");
+                }
+            }
         }
+        return "";
     }
 
     static class KeyComparator implements Comparator<Map.Entry<String, Object>> {

+ 0 - 95
blade-service/blade-manager/src/main/java/org/springblade/manager/utils/ExcelParser.java

@@ -1,95 +0,0 @@
-package org.springblade.manager.utils;
-
-import com.mixsmart.utils.StringUtils;
-import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
-import org.apache.poi.ss.usermodel.*;
-import org.springframework.web.multipart.MultipartFile;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.text.DecimalFormat;
-import java.text.NumberFormat;
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-public class ExcelParser {
-
-    private static final NumberFormat numberFormat = NumberFormat.getNumberInstance();
-
-    static {
-        //格式化后不包含千位分隔符
-        numberFormat.setGroupingUsed(false);
-    }
-
-    public static Map<String, String> parseExcel(MultipartFile file) throws IOException {
-        Map<String, String> cellValueMap = new LinkedHashMap<>();
-        try (InputStream inputStream = file.getInputStream()) {
-            Workbook workbook = WorkbookFactory.create(inputStream);
-            Sheet sheet = workbook.getSheetAt(0); //获取第一个工作表
-            for (Row row : sheet) {
-                for (Cell cell : row) {
-                    String cellValue = getCellValue(cell);
-                    if (StringUtils.isNotEmpty(cellValue)) {
-                        String cellCoordinate = getCellCoordinate(cell);
-                        cellValueMap.put(cellCoordinate, cellValue);
-                    }
-                }
-            }
-        } catch (InvalidFormatException e) {
-            e.printStackTrace();
-        }
-        return cellValueMap;
-    }
-
-    private static String getCellValue(Cell cell) {
-        Object value;
-        if (cell == null) return "";
-        switch (cell.getCellTypeEnum()) {
-            case STRING:
-                return cell.getStringCellValue();
-            case BOOLEAN:
-                return String.valueOf(cell.getBooleanCellValue());
-            case FORMULA:
-                //公式单元格
-                return evaluateFormulaCell(cell);
-            case NUMERIC:
-                //浮点数单元格
-                double d = cell.getNumericCellValue();
-                if (d == 0.0) {
-                    return "";
-                }
-                value = numberFormat.format(d);
-                return value.toString();
-            default:
-                return "";
-        }
-    }
-
-    private static String evaluateFormulaCell(Cell cell) {
-        FormulaEvaluator evaluator = cell.getSheet().getWorkbook().getCreationHelper().createFormulaEvaluator();
-        CellValue cellValue = evaluator.evaluate(cell);
-        Object value;
-        if (cellValue == null) return "";
-        switch (cellValue.getCellTypeEnum()) {
-            //解决公式内部是浮点数问题
-            case NUMERIC:
-                double d = cell.getNumericCellValue();
-                if (d == 0.0) {
-                    return "";
-                }
-                value = numberFormat.format(d);
-                return value.toString();
-            case STRING:
-                return cell.getStringCellValue();
-            default:
-                return "";
-        }
-    }
-
-    private static String getCellCoordinate(Cell cell) {
-        int row = cell.getRowIndex();
-        int col = cell.getColumnIndex();
-        return row + "_" + col;
-    }
-
-}