From cfc5be122eeafd659a2847b1ed950d9b09540b74 Mon Sep 17 00:00:00 2001 From: caihaohan Date: Fri, 3 Nov 2023 14:25:42 +0800 Subject: [PATCH] fix: 77875 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 企业标准--导入--导入一个空excel文件提示语不友好 --- .../laws/common/constant/ResultCommon.java | 4 + .../service/impl/LawsCommonServiceImpl.java | 152 +++++++----------- .../util/EnterpriseStandardUtil.java | 29 ++++ .../main/resources/i18n/messages.properties | 4 +- .../resources/i18n/messages_en.properties | 4 +- .../resources/i18n/messages_zh.properties | 4 +- 6 files changed, 100 insertions(+), 97 deletions(-) diff --git a/laws-modules/src/main/java/com/jero/modules/laws/common/constant/ResultCommon.java b/laws-modules/src/main/java/com/jero/modules/laws/common/constant/ResultCommon.java index 9e490a3e..271a7c9a 100644 --- a/laws-modules/src/main/java/com/jero/modules/laws/common/constant/ResultCommon.java +++ b/laws-modules/src/main/java/com/jero/modules/laws/common/constant/ResultCommon.java @@ -65,5 +65,9 @@ public class ResultCommon { public static final String NO_AUTH = "no.auth"; // 只有处理人可以操作 + public static final String IMPORT_TEMPLATE_ERROR = "import.template.error"; // 导入模板错误 + + public static final String ZIP_CHARSET_ERROR = "zip.charset.error"; // zip压缩包编码错误 + } diff --git a/laws-modules/src/main/java/com/jero/modules/laws/common/service/impl/LawsCommonServiceImpl.java b/laws-modules/src/main/java/com/jero/modules/laws/common/service/impl/LawsCommonServiceImpl.java index 56b4dcff..17541939 100644 --- a/laws-modules/src/main/java/com/jero/modules/laws/common/service/impl/LawsCommonServiceImpl.java +++ b/laws-modules/src/main/java/com/jero/modules/laws/common/service/impl/LawsCommonServiceImpl.java @@ -1348,123 +1348,84 @@ public class LawsCommonServiceImpl implements ILawsCommonService { */ private List validDataFormat(List> insertDataList, MultipartFile file, String tableName) throws IOException { List errMsgList = new ArrayList<>(); - // 判断上传的是不是压缩包 if (!Objects.requireNonNull(file.getOriginalFilename()).toLowerCase().endsWith(".zip")) { throw new JeroBootException(MessageUtils.getMessage(ResultCommon.PLEASE_UPLOAD_ZIP)); } - Path tempDirWithPrefix = Files.createTempDirectory("temp"); File tempFile = new File(tempDirWithPrefix.toFile(), Objects.requireNonNull(file.getOriginalFilename())); file.transferTo(tempFile); - int folderCount = 0; - int excelCount = 0; ZipEntry targetExcelEntry = null; - Charset correctCharset = null; - - // 尝试不同的编码来找到正确的字符集 - String[] charsetsToBeTested = {"UTF-8", "GB2312", "GBK", "UTF-16"}; - for (String charset : charsetsToBeTested) { - try (ZipFile zipFile = new ZipFile(tempFile, Charset.forName(charset))) { - if (zipFile.size() > 0) { - correctCharset = Charset.forName(charset); - log.info("【标准带文件导入】尝试使用{}编码打开压缩包成功", charset); - break; - } - } catch (Exception ignored) { - log.error("【标准带文件导入】尝试使用{}编码打开压缩包失败", charset); - } - } - - if (correctCharset == null) { - errMsgList.add("无法确定压缩包的字符编码"); - return errMsgList; - } Map fileMap = new HashMap<>(); - try (ZipFile zipFile = new ZipFile(tempFile, correctCharset)) { + try (ZipFile zipFile = new ZipFile(tempFile, Charset.forName("GBK"))) { Enumeration entries = zipFile.entries(); + // 文件数量校验 + boolean foundExcel = false; // 初始化标志以检测是否存在Excel文件 // 文件数量校验 while (entries.hasMoreElements()) { ZipEntry entry = entries.nextElement(); String entryName = entry.getName(); - boolean isRootLevel = !entryName.contains("/"); // '/' 作为目录分隔符 + boolean isRootLevel = !entryName.contains("/"); // '/' 作为目录分隔符 - if (entry.isDirectory()) { - folderCount++; - } - if (folderCount > 1 && isRootLevel) { - errMsgList.add("压缩包根目录下仅能存在一个文件夹"); - return errMsgList; - } - if (!entry.isDirectory() && entryName.endsWith(".xlsx") && isRootLevel) { - excelCount++; - targetExcelEntry = entry; - } - if (excelCount > 1) { - errMsgList.add("压缩包根目录下仅能存在一个 excel 为导入数据"); - return errMsgList; - } - - if (!entry.isDirectory()) { - String relativePath = entry.getName(); // Use the entry's name as the relative path - - File tempOutputFile = Files.createTempFile("tempFile_", "_" + new File(relativePath).getName()).toFile(); - try (InputStream is = zipFile.getInputStream(entry); - OutputStream os = Files.newOutputStream(tempOutputFile.toPath())) { - byte[] buffer = new byte[1024]; - int length; - while ((length = is.read(buffer)) > 0) { - os.write(buffer, 0, length); - } + // 检查根目录下的Excel文件数量 + if (!entry.isDirectory() && isRootLevel && (entryName.endsWith(".xlsx") || entryName.endsWith(".xls"))) { + if (foundExcel) { // 如果已找到Excel文件,则添加错误信息 + throw new JeroBootException("压缩包根目录下仅能存在一个 Excel 为导入数据"); + } else { + foundExcel = true; // 找到Excel文件,更新标志 + targetExcelEntry = entry; } - fileMap.put(relativePath, tempOutputFile); //使用相对路径作为Key } } + if (targetExcelEntry == null) { + throw new JeroBootException(MessageUtils.getMessage(ResultCommon.IMPORT_TEMPLATE_ERROR)); + } // 数据内容格式校验 - if (targetExcelEntry != null) { - try (Workbook workbook = new XSSFWorkbook(zipFile.getInputStream(targetExcelEntry))) { - Sheet sheet = workbook.getSheetAt(0); - // 获取标题行中文 转换为LawsTag对象 - Row hearderRow = sheet.getRow(0); - // 获取全部字段 - List fieldList = lawsCommonMapper.getFieldList(tableName); - // 筛选表单显示的字段 - // 找到所有标题Map - Map headerMap = fieldList.stream().filter(lawsTag -> YesOrNoEnum.YES.getValue() - .equals(lawsTag.getIsShowForm().toString())).collect(Collectors.toMap( - LawsTag::getDbFieldTxt, lawsTag -> lawsTag - )); - // 按照实际顺序创建headerList - List headerList = new ArrayList<>(); - for (Cell cell : hearderRow) { - headerList.add(headerMap.get(cell.toString().replace("*", ""))); - } - // 如果是企标的话手动添加稽查内容字段 - if (TableNameEnum.ENTERPRISE_STANDARDS.getTableName().equals(tableName)) { - LawsTag inspectContentTag = new LawsTag(); - inspectContentTag.setDbFieldTxt("稽查内容"); - inspectContentTag.setFieldShowType(FieldShowTypeEnum.INSPECT_CONTENT_FILE_UPLOAD.getValue()); - inspectContentTag.setDbFieldName(FieldCommon.CHECK_LIST); - inspectContentTag.setFieldMustInput(YesOrNoEnum.NO.getValue()); - headerList.remove(headerList.size() - 1); - headerList.add(inspectContentTag); - } - // 从数据行开始遍历 - for (int i = 3; i < sheet.getPhysicalNumberOfRows(); i++) { - Map parameterMap = new HashMap<>(); - for (int j = 0; j < headerList.size(); j++) { - // 获取当前单元格 - Cell cell = sheet.getRow(i).getCell(j); - // 获取当前单元格内容对应的字段 - LawsTag tag = headerList.get(j); - // 调用导入工具类的校验方法 - errMsgList.addAll(importUtil.allColumnValid(cell, tag, i, j, parameterMap, fileMap)); - } - insertDataList.add(parameterMap); + try (Workbook workbook = new XSSFWorkbook(zipFile.getInputStream(targetExcelEntry))) { + // 检测是否是空Excel + Sheet sheet = workbook.getSheetAt(0); + // 验证前三行是否有数据 + esUtil.isEmptyExcel(sheet); + // 获取标题行中文 转换为LawsTag对象 + Row hearderRow = sheet.getRow(0); + // 获取全部字段 + List fieldList = lawsCommonMapper.getFieldList(tableName); + // 筛选表单显示的字段 + // 找到所有标题Map + Map headerMap = fieldList.stream().filter(lawsTag -> YesOrNoEnum.YES.getValue() + .equals(lawsTag.getIsShowForm().toString())).collect(Collectors.toMap( + LawsTag::getDbFieldTxt, lawsTag -> lawsTag + )); + // 按照实际顺序创建headerList + List headerList = new ArrayList<>(); + for (Cell cell : hearderRow) { + headerList.add(headerMap.get(cell.toString().replace("*", ""))); + } + // 如果是企标的话手动添加稽查内容字段 + if (TableNameEnum.ENTERPRISE_STANDARDS.getTableName().equals(tableName)) { + LawsTag inspectContentTag = new LawsTag(); + inspectContentTag.setDbFieldTxt("稽查内容"); + inspectContentTag.setFieldShowType(FieldShowTypeEnum.INSPECT_CONTENT_FILE_UPLOAD.getValue()); + inspectContentTag.setDbFieldName(FieldCommon.CHECK_LIST); + inspectContentTag.setFieldMustInput(YesOrNoEnum.NO.getValue()); + headerList.remove(headerList.size() - 1); + headerList.add(inspectContentTag); + } + // 从数据行开始遍历 + for (int i = 3; i < sheet.getPhysicalNumberOfRows(); i++) { + Map parameterMap = new HashMap<>(); + for (int j = 0; j < headerList.size(); j++) { + // 获取当前单元格 + Cell cell = sheet.getRow(i).getCell(j); + // 获取当前单元格内容对应的字段 + LawsTag tag = headerList.get(j); + // 调用导入工具类的校验方法 + errMsgList.addAll(importUtil.allColumnValid(cell, tag, i, j, parameterMap, fileMap)); } + insertDataList.add(parameterMap); } } return errMsgList; @@ -1961,6 +1922,7 @@ public class LawsCommonServiceImpl implements ILawsCommonService { /** * 创建企标导入模板的Workbook + * * @return */ private Workbook createEsExcelTemplate() { @@ -1991,6 +1953,7 @@ public class LawsCommonServiceImpl implements ILawsCommonService { /** * 创建稽查内容模板的Workbook + * * @return */ private Workbook createInspectContentExcelTemplate() { @@ -2015,6 +1978,7 @@ public class LawsCommonServiceImpl implements ILawsCommonService { /** * 通用创建WorkBook方法 + * * @param fieldList * @return */ diff --git a/laws-modules/src/main/java/com/jero/modules/laws/enterprise/util/EnterpriseStandardUtil.java b/laws-modules/src/main/java/com/jero/modules/laws/enterprise/util/EnterpriseStandardUtil.java index 65d9b5ea..51ae7527 100644 --- a/laws-modules/src/main/java/com/jero/modules/laws/enterprise/util/EnterpriseStandardUtil.java +++ b/laws-modules/src/main/java/com/jero/modules/laws/enterprise/util/EnterpriseStandardUtil.java @@ -3,14 +3,17 @@ package com.jero.modules.laws.enterprise.util; import com.jero.common.exception.JeroBootException; import com.jero.common.system.api.ISysBaseAPI; import com.jero.common.system.vo.DictModel; +import com.jero.common.util.MessageUtils; import com.jero.modules.activiti.process.esInitChange.entity.ProcessEsInitChange; import com.jero.modules.activiti.process.esInitChange.service.ProcessEsInitChangeService; import com.jero.modules.laws.common.constant.FieldCommon; +import com.jero.modules.laws.common.constant.ResultCommon; import com.jero.modules.laws.enterprise.service.ESSequenceNumberProvider; import com.jero.modules.laws.standard.entity.LawsEnterpriseStandard; import com.jero.modules.laws.standard.service.ILawsEnterpriseStandardService; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang.StringUtils; +import org.apache.poi.ss.usermodel.*; import org.springframework.stereotype.Component; import javax.annotation.Resource; @@ -181,4 +184,30 @@ public class EnterpriseStandardUtil { numList.addAll(initChangeService.list().stream().map(ProcessEsInitChange::getNewEnStandardNo).collect(Collectors.toList())); return !numList.contains(StandardNumber); } + + // 判断是否是空Excel + public void isEmptyExcel(Sheet sheet) { + // 验证前三行是否有数据 + for (int rowIndex = 0; rowIndex < 3; rowIndex++) { + Row row = sheet.getRow(rowIndex); + if (row == null) { + // 如果行对象为null,表示这一行不存在,抛出异常 + throw new JeroBootException(MessageUtils.getMessage(ResultCommon.IMPORT_TEMPLATE_ERROR)); + } else { + boolean isRowEmpty = true; + for (int cellIndex = row.getFirstCellNum(); cellIndex < row.getLastCellNum(); cellIndex++) { + Cell cell = row.getCell(cellIndex); + if (cell != null && cell.getCellType() != CellType.BLANK) { + // 如果找到非空单元格,设置标志为false并跳出循环 + isRowEmpty = false; + break; + } + } + if (isRowEmpty) { + // 如果行是空的,抛出异常 + throw new JeroBootException(MessageUtils.getMessage(ResultCommon.IMPORT_TEMPLATE_ERROR)); + } + } + } + } } diff --git a/laws-single-startup/src/main/resources/i18n/messages.properties b/laws-single-startup/src/main/resources/i18n/messages.properties index 49538475..31618b02 100644 --- a/laws-single-startup/src/main/resources/i18n/messages.properties +++ b/laws-single-startup/src/main/resources/i18n/messages.properties @@ -48,4 +48,6 @@ export.error=\u5BFC\u51FA\u9519\u8BEF import.error=\u5BFC\u5165\u9519\u8BEF please.upload.zip.archive=\u6570\u636E\u5BFC\u5165\u5931\u8D25\uFF0C\u8BF7\u4E0A\u4F20zip\u538B\u7F29\u5305 task.handler.error=\u53EA\u6709\u5904\u7406\u4EBA\u53EF\u4EE5\u64CD\u4F5C -no.auth=\u6CA1\u6709\u64CD\u4F5C\u6743\u9650 \ No newline at end of file +no.auth=\u6CA1\u6709\u64CD\u4F5C\u6743\u9650 +import.template.error=\u5BFC\u5165\u6A21\u677F\u9519\u8BEF +zip.charset.error=zip\u538B\u7F29\u5305\u7F16\u7801\u9519\u8BEF diff --git a/laws-single-startup/src/main/resources/i18n/messages_en.properties b/laws-single-startup/src/main/resources/i18n/messages_en.properties index 14439c6e..66769569 100644 --- a/laws-single-startup/src/main/resources/i18n/messages_en.properties +++ b/laws-single-startup/src/main/resources/i18n/messages_en.properties @@ -51,4 +51,6 @@ export.error=Export error import.error=Import error please.upload.zip.archive=Data import failed, please upload zip archive task.handler.error=Only the handler can operate -no.auth=No permission to operate \ No newline at end of file +no.auth=No permission to operate +import.template.error=Import template error +zip.charset.error=Zip charset error \ No newline at end of file diff --git a/laws-single-startup/src/main/resources/i18n/messages_zh.properties b/laws-single-startup/src/main/resources/i18n/messages_zh.properties index 3f7f1a3d..ce630aa9 100644 --- a/laws-single-startup/src/main/resources/i18n/messages_zh.properties +++ b/laws-single-startup/src/main/resources/i18n/messages_zh.properties @@ -50,4 +50,6 @@ export.zip.archive.error=\u5BFC\u51FA\u9519\u8BEF import.zip.archive.error=\u5BFC\u5165\u9519\u8BEF please.upload.zip.archive=\u6570\u636E\u5BFC\u5165\u5931\u8D25\uFF0C\u8BF7\u4E0A\u4F20zip\u538B\u7F29\u5305 task.handler.error=\u53EA\u6709\u5904\u7406\u4EBA\u53EF\u4EE5\u64CD\u4F5C -no.auth=\u6CA1\u6709\u64CD\u4F5C\u6743\u9650 \ No newline at end of file +no.auth=\u6CA1\u6709\u64CD\u4F5C\u6743\u9650 +import.template.error=\u5BFC\u5165\u6A21\u677F\u9519\u8BEF +zip.charset.error=zip\u538B\u7F29\u5305\u7F16\u7801\u9519\u8BEF