From 5f2e367acc2072a2fc825867d6167a0dbc2effae Mon Sep 17 00:00:00 2001 From: liuchengqian Date: Mon, 21 Mar 2022 16:58:37 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AF=BC=E5=85=A5=E6=A3=80=E9=AA=8C=E8=A7=84?= =?UTF-8?q?=E6=A0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/xkrs/controller/QcSpecController.java | 17 ++ src/main/java/com/xkrs/dao/CraftItemDao.java | 4 +- src/main/java/com/xkrs/dao/QcItemDao.java | 4 +- src/main/java/com/xkrs/dao/QcSpecDao.java | 12 +- .../com/xkrs/model/bean/ReadSpecHeadBean.java | 51 +++++ .../java/com/xkrs/service/QcSpecService.java | 11 + .../xkrs/service/impl/QcSpecServiceImpl.java | 195 +++++++++++++++++- 7 files changed, 286 insertions(+), 8 deletions(-) create mode 100644 src/main/java/com/xkrs/model/bean/ReadSpecHeadBean.java diff --git a/src/main/java/com/xkrs/controller/QcSpecController.java b/src/main/java/com/xkrs/controller/QcSpecController.java index 007febf..9578b2b 100644 --- a/src/main/java/com/xkrs/controller/QcSpecController.java +++ b/src/main/java/com/xkrs/controller/QcSpecController.java @@ -5,6 +5,7 @@ import com.xkrs.model.qo.QcSpecQoInsert; import com.xkrs.model.qo.QcSpecQoUpdate; import com.xkrs.service.QcSpecService; import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; @@ -46,4 +47,20 @@ public class QcSpecController { return qcSpecService.queryQcSpec(varietyNo, craftItemNo, qcItemNo); } + /** + * 导入检验规格 + */ + @PostMapping("/importSpecExcel") + public String importSpecExcel(@RequestParam(value = "specExcel") MultipartFile specExcel) { + return qcSpecService.importSpecExcel(specExcel); + } + + /** + * 导出检验规格 + */ + @GetMapping("/exportSpecExcel") + public String exportSpecExcel() { + return qcSpecService.exportSpecExcel(); + } + } diff --git a/src/main/java/com/xkrs/dao/CraftItemDao.java b/src/main/java/com/xkrs/dao/CraftItemDao.java index 5b135b5..caa9c37 100644 --- a/src/main/java/com/xkrs/dao/CraftItemDao.java +++ b/src/main/java/com/xkrs/dao/CraftItemDao.java @@ -18,7 +18,9 @@ import java.util.Optional; @Component public interface CraftItemDao extends JpaRepository, JpaSpecificationExecutor { - Optional findByCraftItemNo(String no); + Optional findByCraftItemNo(String craftItemNo); + + Optional findByCraftItemName(String craftItemName); /** * 更新工艺项目名称 diff --git a/src/main/java/com/xkrs/dao/QcItemDao.java b/src/main/java/com/xkrs/dao/QcItemDao.java index f826459..fd765e1 100644 --- a/src/main/java/com/xkrs/dao/QcItemDao.java +++ b/src/main/java/com/xkrs/dao/QcItemDao.java @@ -17,7 +17,9 @@ import java.util.Optional; @Component public interface QcItemDao extends JpaRepository, JpaSpecificationExecutor { - Optional findByQcItemNo(String no); + Optional findByQcItemNo(String qcItemNo); + + Optional findByQcItemName(String qcItemName); /** * 更新检验项目名称 diff --git a/src/main/java/com/xkrs/dao/QcSpecDao.java b/src/main/java/com/xkrs/dao/QcSpecDao.java index a2bf312..ee9d6c1 100644 --- a/src/main/java/com/xkrs/dao/QcSpecDao.java +++ b/src/main/java/com/xkrs/dao/QcSpecDao.java @@ -7,6 +7,7 @@ import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Component; +import javax.transaction.Transactional; import java.util.List; import java.util.Map; import java.util.Optional; @@ -18,12 +19,21 @@ public interface QcSpecDao extends JpaRepository, JpaSpec Optional findExistsQcSpec(String varietyNo, String craftItemNo, String qcItemNo); /** - * 更新检验规格 + * 更新检验规格(Integer id) */ + @Transactional(rollbackOn = Exception.class) @Modifying(clearAutomatically = true) @Query(value = "UPDATE qc_spec SET update_time = ?2, max = ?3, mean = ?4, min = ?5, unit = ?6, method = ?7, standard = ?8, remark = ?9 WHERE id = ?1", nativeQuery = true) void updateQcSpecById(Integer id, String updateTime, String max, String mean, String min, String unit, String method, String standard, String remark); + /** + * 更新检验规格(String varietyNo, String craftItemNo, String qcItemNo) + */ + @Transactional(rollbackOn = Exception.class) + @Modifying(clearAutomatically = true) + @Query(value = "UPDATE qc_spec SET update_time = ?4, max = ?5, mean = ?6, min = ?7, unit = ?8, method = ?9, standard = ?10, remark = ?11 WHERE variety_no = ?1 AND craft_item_no = ?2 AND qc_item_no = ?3", nativeQuery = true) + void updateQcSpecByVCQ(String varietyNo, String craftItemNo, String qcItemNo, String updateTime, String max, String mean, String min, String unit, String method, String standard, String remark); + /** * 查询检验规格 */ diff --git a/src/main/java/com/xkrs/model/bean/ReadSpecHeadBean.java b/src/main/java/com/xkrs/model/bean/ReadSpecHeadBean.java new file mode 100644 index 0000000..556a196 --- /dev/null +++ b/src/main/java/com/xkrs/model/bean/ReadSpecHeadBean.java @@ -0,0 +1,51 @@ +package com.xkrs.model.bean; + +public class ReadSpecHeadBean { + + /** + * 是否成功 + */ + private boolean success; + + /** + * 错误消息 + */ + private String errorMessage; + + /** + * 表头的有效列数 + */ + private long headCount; + + public ReadSpecHeadBean() { + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public String getErrorMessage() { + return errorMessage; + } + + public void setErrorMessage(String errorMessage) { + this.errorMessage = errorMessage; + } + + public long getHeadCount() { + return headCount; + } + + public void setHeadCount(long headCount) { + this.headCount = headCount; + } + + @Override + public String toString() { + return "ReadSpecHeadBean{" + "success=" + success + ", errorMessage='" + errorMessage + '\'' + ", headCount=" + headCount + '}'; + } +} diff --git a/src/main/java/com/xkrs/service/QcSpecService.java b/src/main/java/com/xkrs/service/QcSpecService.java index dfd55ff..727c974 100644 --- a/src/main/java/com/xkrs/service/QcSpecService.java +++ b/src/main/java/com/xkrs/service/QcSpecService.java @@ -3,6 +3,7 @@ package com.xkrs.service; import com.xkrs.model.qo.QcSpecQoDelete; import com.xkrs.model.qo.QcSpecQoInsert; import com.xkrs.model.qo.QcSpecQoUpdate; +import org.springframework.web.multipart.MultipartFile; public interface QcSpecService { @@ -26,4 +27,14 @@ public interface QcSpecService { */ String queryQcSpec(String varietyNo, String craftItemNo, String qcItemNo); + /** + * 导入检验规格 + */ + String importSpecExcel(MultipartFile specExcel); + + /** + * 导出检验规格 + */ + String exportSpecExcel(); + } diff --git a/src/main/java/com/xkrs/service/impl/QcSpecServiceImpl.java b/src/main/java/com/xkrs/service/impl/QcSpecServiceImpl.java index 14a1914..aa85c63 100644 --- a/src/main/java/com/xkrs/service/impl/QcSpecServiceImpl.java +++ b/src/main/java/com/xkrs/service/impl/QcSpecServiceImpl.java @@ -4,6 +4,7 @@ import com.xkrs.dao.CraftItemDao; import com.xkrs.dao.QcItemDao; import com.xkrs.dao.QcSpecDao; import com.xkrs.encapsulation.PromptMessageEnum; +import com.xkrs.model.bean.ReadSpecHeadBean; import com.xkrs.model.entity.CraftItemEntity; import com.xkrs.model.entity.QcItemEntity; import com.xkrs.model.entity.QcSpecEntity; @@ -14,15 +15,18 @@ import com.xkrs.service.QcSpecService; import com.xkrs.util.LocalDateUtils; import com.xkrs.util.LocalStringUtils; import org.apache.http.util.TextUtils; +import org.apache.poi.hssf.usermodel.HSSFDateUtil; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.xssf.usermodel.XSSFSheet; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; import javax.transaction.Transactional; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Optional; +import java.util.*; import static com.xkrs.encapsulation.OutputEncapsulation.outputEncapsulationObject; @@ -105,7 +109,6 @@ public class QcSpecServiceImpl implements QcSpecService { /** * 更新检验规格 */ - @Transactional(rollbackOn = Exception.class) @Override public String updateQcSpec(QcSpecQoUpdate updateQo) { @@ -146,4 +149,186 @@ public class QcSpecServiceImpl implements QcSpecService { } return outputEncapsulationObject(PromptMessageEnum.SUCCESS, resultList, locale); } + + /** + * 导入检验规格 + */ + @Override + public String importSpecExcel(MultipartFile specExcel) { + try { + //1、读取测量规格数据表文件 + XSSFWorkbook workbook = new XSSFWorkbook(specExcel.getInputStream()); + //2、获取工作表对象 + XSSFSheet sheet = workbook.getSheetAt(0); + //3、获取行的迭代器 + Iterator iterator = sheet.iterator(); + long rowNum = 0; + long colNum = -1; + //4、表格数据容器 + List> sheetDataList = new ArrayList<>(); + while (iterator.hasNext()) { + Row row = iterator.next(); + if (rowNum == 0) { + ReadSpecHeadBean readResult = readSpecHead(row); + if (readResult.isSuccess()) { + colNum = readResult.getHeadCount(); + rowNum++; + continue; + } + return outputEncapsulationObject(PromptMessageEnum.DATA_NONE, readResult.getErrorMessage(), locale); + } + List rowDataList = new ArrayList<>(); + for (int i = 0; i < colNum; i++) { + String value = getValue(row.getCell(i)); + if (i == 0) {//机种号数据直接添加 + if (TextUtils.isEmpty(value)) { + return outputEncapsulationObject(PromptMessageEnum.DATA_NONE, "第" + rowNum + "行机种号为空,请先编辑机种号!", locale); + } + rowDataList.add(value); + } else if (i == 1) {//工艺项目数据要添加对应的编号 + Optional craftItemOptional = craftItemDao.findByCraftItemName(value); + if (craftItemOptional.isEmpty()) { + return outputEncapsulationObject(PromptMessageEnum.DATA_NONE, "第" + rowNum + "行工艺项目(" + value + ")不存在,请先添加工艺项目!", locale); + } + rowDataList.add(craftItemOptional.get().getCraftItemNo()); + } else if (i == 2) {//检验项目数据要添加对应的编号 + Optional qcItemOptional = qcItemDao.findByQcItemName(value); + if (qcItemOptional.isEmpty()) { + return outputEncapsulationObject(PromptMessageEnum.DATA_NONE, "第" + rowNum + "行检验项目(" + value + ")不存在,请先添加检验项目!", locale); + } + rowDataList.add(qcItemOptional.get().getQcItemNo()); + } else {//其他数据直接添加 + rowDataList.add(value); + } + } + sheetDataList.add(rowDataList); + rowNum++; + } + //5、表格数据自重复检查 + for (int i = 0; i < sheetDataList.size(); i++) { + List rowDataList = sheetDataList.get(i); + List appearIndexList = checkAppearIndex(sheetDataList, rowDataList.get(0), rowDataList.get(1), rowDataList.get(2)); + if (appearIndexList.size() == 0) { + return outputEncapsulationObject(PromptMessageEnum.DATA_NONE, "系统错误!", locale); + } + if (appearIndexList.size() > 1) { + StringBuilder response = new StringBuilder(); + response.append("测量规格表中:机种号、工艺项目、检验项目三项存在全部相同项,行数:"); + for (Integer appearIndex : appearIndexList) { + response.append("第").append(appearIndex + 2).append("行、"); + } + return outputEncapsulationObject(PromptMessageEnum.DATA_NONE, response.toString(), locale); + } + } + //6、表格的数据已经全部读取完成,并且自检通过,接下来遍历入库即可 + int insertCount = 0; + int updateCount = 0; + for (List rowDataList : sheetDataList) { + String varietyNo = rowDataList.get(0); + String craftItemNo = rowDataList.get(1); + String qcItemNo = rowDataList.get(2); + String max = rowDataList.get(3); + String min = rowDataList.get(4); + String method = rowDataList.get(5); + Optional existsQcSpecOptional = qcSpecDao.findExistsQcSpec(varietyNo, craftItemNo, qcItemNo); + if (existsQcSpecOptional.isPresent()) { + qcSpecDao.updateQcSpecByVCQ(LocalStringUtils.formatEmptyValue(varietyNo), LocalStringUtils.formatEmptyValue(craftItemNo), LocalStringUtils.formatEmptyValue(qcItemNo), LocalDateUtils.getCurrentSecond(), LocalStringUtils.formatEmptyValue(max), "", LocalStringUtils.formatEmptyValue(min), "", LocalStringUtils.formatEmptyValue(method), "", ""); + updateCount++; + } else { + QcSpecEntity entity = new QcSpecEntity(); + entity.setCreateTime(LocalDateUtils.getCurrentSecond()); + entity.setUpdateTime(""); + entity.setVarietyNo(LocalStringUtils.formatEmptyValue(varietyNo)); + entity.setCraftItemNo(LocalStringUtils.formatEmptyValue(craftItemNo)); + entity.setQcItemNo(LocalStringUtils.formatEmptyValue(qcItemNo)); + entity.setMax(LocalStringUtils.formatEmptyValue(max)); + entity.setMean(""); + entity.setMin(LocalStringUtils.formatEmptyValue(min)); + entity.setUnit(""); + entity.setMethod(LocalStringUtils.formatEmptyValue(method)); + entity.setStandard(""); + entity.setRemark(""); + qcSpecDao.save(entity); + insertCount++; + } + } + StringBuilder response = new StringBuilder(); + response.append("导入成功"); + if (insertCount > 0) { + response.append(",新增").append(insertCount).append("条测量规格"); + } + if (updateCount > 0) { + response.append(",更新").append(updateCount).append("条测量规格"); + } + response.append("。"); + return outputEncapsulationObject(PromptMessageEnum.SUCCESS, response.toString(), locale); + } catch (Exception e) { + e.printStackTrace(); + } + return outputEncapsulationObject(PromptMessageEnum.DATA_NONE, "测量规格数据导入失败!", locale); + } + + private List checkAppearIndex(List> sheetDataList, String varietyNo, String craftItemNo, String qcItemNo) { + List appearIndexList = new ArrayList<>(); + for (int i = 0; i < sheetDataList.size(); i++) { + List rowDataList = sheetDataList.get(i); + if (rowDataList.get(0).equals(varietyNo) && rowDataList.get(1).equals(craftItemNo) && rowDataList.get(2).equals(qcItemNo)) { + appearIndexList.add(i); + } + } + return appearIndexList; + } + + List QC_SPEC_HEAD = Arrays.asList("机种号", "工艺项目", "检验项目", "最大值", "最小值", "检验方法"); + + /** + * 读取表头数据 + */ + private ReadSpecHeadBean readSpecHead(Row headRow) { + ReadSpecHeadBean readResult = new ReadSpecHeadBean(); + for (int i = 0; i < 6; i++) { + if (!QC_SPEC_HEAD.get(i).equals(getValue(headRow.getCell(i)))) { + readResult.setSuccess(false); + readResult.setHeadCount(0); + readResult.setErrorMessage("表头第" + (i + 1) + "列应该是:" + QC_SPEC_HEAD.get(i)); + return readResult; + } + } + readResult.setSuccess(true); + readResult.setHeadCount(6); + readResult.setErrorMessage(""); + return readResult; + } + + /** + * 获取单元格内的数据,并进行格式转换 + */ + private String getValue(Cell cell) { + if (cell == null) { + return ""; + } + if (Cell.CELL_TYPE_STRING == cell.getCellType()) { + return cell.getStringCellValue(); + } + if (Cell.CELL_TYPE_BOOLEAN == cell.getCellType()) { + return String.valueOf(cell.getBooleanCellValue()); + } + if (Cell.CELL_TYPE_NUMERIC == cell.getCellType()) {//数值和日期均是此类型,需进一步判断 + if (HSSFDateUtil.isCellDateFormatted(cell)) { + //是日期类型 + return String.valueOf(cell.getDateCellValue().getTime()); + } else { + //是数值类型 + return String.valueOf(cell.getNumericCellValue()); + } + } + return ""; + + } + + + @Override + public String exportSpecExcel() { + return null; + } }