package com.ruoyi.require.service.impl; import com.alibaba.excel.EasyExcel; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.StringUtils; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.framework.exception.ErrorException; import com.ruoyi.require.excel.FeStandardSubstanceImport; import com.ruoyi.require.mapper.FeStandardSubstanceMapper; import com.ruoyi.require.pojo.FeStandardSubstance; import com.ruoyi.require.service.FeStandardSubstanceService; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletResponse; import java.net.URLEncoder; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Set; import java.util.stream.Collectors; /** *

* 标准物质清单 服务实现类 *

* * @author * @since 2024-11-13 03:58:59 */ @Service public class FeStandardSubstanceServiceImpl extends ServiceImpl implements FeStandardSubstanceService { @Override public IPage page(Page page, FeStandardSubstance feStandardSubstance) { return this.baseMapper.getPage(page,feStandardSubstance); } @Override public void downloadImportTemplate(HttpServletResponse response) { response.reset(); response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); response.setHeader("Access-Control-Expose-Headers", "Content-Disposition"); try { String fileName = URLEncoder.encode("标准物质导入模板.xlsx", "UTF-8"); response.setHeader("Content-Disposition", "attachment;filename=" + fileName); EasyExcel.write(response.getOutputStream(), FeStandardSubstanceImport.class) .sheet("标准物质导入模板") .doWrite(Collections.emptyList()); } catch (Exception e) { throw new RuntimeException("标准物质导入模板下载失败", e); } } @Override @Transactional(rollbackFor = Exception.class) public int importStandardSubstance(MultipartFile file) { if (file == null || file.isEmpty()) { throw new ErrorException("请选择需要导入的Excel文件"); } String fileName = file.getOriginalFilename(); if (fileName == null || !fileName.toLowerCase(Locale.ROOT).endsWith(".xlsx")) { throw new ErrorException("仅支持.xlsx格式文件"); } final List rows; try { rows = EasyExcel.read(file.getInputStream()) .head(FeStandardSubstanceImport.class) .sheet() .doReadSync(); } catch (Exception e) { throw new ErrorException("Excel解析失败,请使用下载的导入模板"); } if (CollectionUtils.isEmpty(rows)) { throw new ErrorException("导入文件没有标准物质数据"); } Set manageNumbers = new HashSet<>(); for (int i = 0; i < rows.size(); i++) { String manageNum = required(rows.get(i).getManageNum(), i + 2, "管理编号"); if (!manageNumbers.add(manageNum)) { throw new ErrorException("第" + (i + 2) + "行:管理编号" + manageNum + "在文件中重复"); } } Set existingNumbers = baseMapper.selectList(Wrappers.lambdaQuery() .in(FeStandardSubstance::getManageNum, manageNumbers) .select(FeStandardSubstance::getManageNum)) .stream().map(FeStandardSubstance::getManageNum).collect(Collectors.toSet()); List substances = new ArrayList<>(); for (int i = 0; i < rows.size(); i++) { int rowNumber = i + 2; FeStandardSubstanceImport row = rows.get(i); String manageNum = required(row.getManageNum(), rowNumber, "管理编号"); if (existingNumbers.contains(manageNum)) { throw new ErrorException("第" + rowNumber + "行:管理编号" + manageNum + "已存在"); } FeStandardSubstance substance = new FeStandardSubstance(); substance.setName(required(row.getName(), rowNumber, "标准物质名称")); substance.setModel(required(row.getModel(), rowNumber, "规格型号")); substance.setFactoryManufacturer(required(row.getFactoryManufacturer(), rowNumber, "生产厂家")); substance.setFactoryNum(required(row.getFactoryNum(), rowNumber, "出厂编号")); substance.setManageNum(manageNum); substance.setUncertainty(required(row.getUncertainty(), rowNumber, "不确定度")); substance.setQuantity(parseQuantity(row.getQuantity(), rowNumber)); substance.setAcquisitionDate(parseDate(row.getAcquisitionDate(), rowNumber, "购置日期")); substance.setEffectiveDate(parseDate(row.getEffectiveDate(), rowNumber, "有效期")); substance.setFileNum(required(row.getFileNum(), rowNumber, "档案编号")); substance.setPosition(required(row.getPosition(), rowNumber, "存放位置")); substance.setRemark(trim(row.getRemark())); substance.setState(0); substances.add(substance); } saveBatch(substances); return substances.size(); } private Long parseQuantity(String input, int rowNumber) { String value = required(input, rowNumber, "数量"); try { long quantity = Long.parseLong(value); if (quantity <= 0) { throw new NumberFormatException(); } return quantity; } catch (NumberFormatException e) { throw new ErrorException("第" + rowNumber + "行:数量必须是大于0的整数"); } } private LocalDateTime parseDate(String input, int rowNumber, String column) { String value = required(input, rowNumber, column); try { return LocalDate.parse(value.substring(0, Math.min(value.length(), 10)).replace('/', '-'), DateTimeFormatter.ofPattern("yyyy-M-d")) .atStartOfDay(); } catch (Exception e) { throw new ErrorException("第" + rowNumber + "行:" + column + "格式应为yyyy-MM-dd"); } } private String required(String input, int rowNumber, String column) { String value = trim(input); if (StringUtils.isBlank(value)) { throw new ErrorException("第" + rowNumber + "行:" + column + "不能为空"); } return value; } private String trim(String value) { return value == null ? null : value.trim(); } }