package com.ruoyi.quality.service.impl; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.ruoyi.quality.dto.QualityInspectExportDTO; import com.ruoyi.quality.dto.QualityInspectExportVO; import com.ruoyi.quality.mapper.QualityInspectMapper; import com.ruoyi.quality.pojo.QualityInspect; import com.ruoyi.quality.pojo.QualityInspectParam; import com.ruoyi.quality.service.IQualityInspectParamService; import org.apache.poi.ss.usermodel.*; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import javax.annotation.Resource; import javax.servlet.http.HttpServletResponse; import java.io.OutputStream; import java.net.URLEncoder; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; /** * 质量检验导出处理类 */ @Component public class QualityInspectExportHandle { @Resource private QualityInspectMapper qualityInspectMapper; @Resource private IQualityInspectParamService qualityInspectParamService; /** * 查询检验记录(支持选中导出和全部导出) * @param exportDTO 导出参数 * @return 检验记录列表 */ public List queryInspectList(QualityInspectExportDTO exportDTO) { QualityInspect qualityInspect = new QualityInspect(); qualityInspect.setInspectType(exportDTO.getInspectType()); qualityInspect.setSupplier(exportDTO.getSupplier()); qualityInspect.setProcess(exportDTO.getProcess()); qualityInspect.setProductName(exportDTO.getProductName()); qualityInspect.setEntryDateStart(exportDTO.getEntryDateStart()); qualityInspect.setEntryDateEnd(exportDTO.getEntryDateEnd()); if (!CollectionUtils.isEmpty(exportDTO.getIds())) { return qualityInspectMapper.qualityInspectExportByIds(exportDTO.getIds(), qualityInspect); } else { return qualityInspectMapper.qualityInspectExportByIds(null, qualityInspect); } } /** * 构建导出数据(每个检验参数一行) * 同一检验记录的多个参数行,只在第一行显示左侧基础信息,后续行留空 * @param qualityInspects 检验记录列表 * @param inspectType 检验类型 * @return 导出数据列表 */ public List buildExportData(List qualityInspects, Integer inspectType) { if (CollectionUtils.isEmpty(qualityInspects)) { return new ArrayList<>(); } // 获取所有检验记录的ID,批量查询检验参数 List inspectIds = qualityInspects.stream().map(QualityInspect::getId).collect(Collectors.toList()); List allParams = qualityInspectParamService.list( Wrappers.lambdaQuery().in(QualityInspectParam::getInspectId, inspectIds) ); // 按inspectId分组 Map> paramMap = allParams.stream() .collect(Collectors.groupingBy(QualityInspectParam::getInspectId)); // 构建导出数据:每个检验参数一行 List exportList = new ArrayList<>(); for (QualityInspect inspect : qualityInspects) { List params = paramMap.getOrDefault(inspect.getId(), new ArrayList<>()); if (params.isEmpty()) { // 没有检验参数,也输出一行 QualityInspectExportVO vo = buildVO(inspect, null, inspectType, true); exportList.add(vo); } else { // 有检验参数,每个参数一行,第一行显示基础信息,后续行左侧留空 boolean isFirst = true; for (QualityInspectParam param : params) { QualityInspectExportVO vo = buildVO(inspect, param, inspectType, isFirst); exportList.add(vo); isFirst = false; } } } return exportList; } /** * 构建单行导出数据 * @param inspect 检验记录 * @param param 检验参数(可为null) * @param inspectType 检验类型 * @param showBaseInfo 是否显示左侧基础信息(同一检验记录的多行,只在第一行显示) */ private QualityInspectExportVO buildVO(QualityInspect inspect, QualityInspectParam param, Integer inspectType, boolean showBaseInfo) { QualityInspectExportVO vo = new QualityInspectExportVO(); // 只有第一行显示左侧基础信息,后续行留空 if (showBaseInfo) { vo.setCheckTime(inspect.getCheckTime()); vo.setCheckName(inspect.getCheckName()); vo.setProductName(inspect.getProductName()); vo.setModel(inspect.getModel()); vo.setUnit(inspect.getUnit()); vo.setQuantity(inspect.getQuantity()); vo.setCheckCompany(inspect.getCheckCompany()); vo.setCheckResult(inspect.getCheckResult()); // 设置订单号和供应商/工序 if (inspectType == 0) { vo.setOrderNo(inspect.getPurchaseContractNo()); vo.setSupplierOrProcess(inspect.getSupplier()); } else if (inspectType == 1) { vo.setOrderNo(inspect.getWorkOrderNo()); vo.setSupplierOrProcess(inspect.getProcess()); } else { vo.setOrderNo(inspect.getWorkOrderNo()); vo.setSupplierOrProcess(""); } } // 设置检验参数(每行都要显示) if (param != null) { vo.setParameterItem(param.getParameterItem()); vo.setParamUnit(param.getUnit()); vo.setStandardValue(param.getStandardValue()); vo.setControlValue(param.getControlValue()); vo.setTestValue(param.getTestValue()); } return vo; } /** * 导出Excel * @param response 响应 * @param exportList 导出数据 * @param inspectType 检验类型 */ public void exportExcel(HttpServletResponse response, List exportList, Integer inspectType) { try { Workbook workbook = new XSSFWorkbook(); Sheet sheet = workbook.createSheet(); // 创建样式 CellStyle headerStyle = createHeaderStyle(workbook); CellStyle dataStyle = createDataStyle(workbook); // 构建表头 Row headerRow = sheet.createRow(0); String[] headers = {"检测日期", "订单号", "供应商/工序", "检验员", "产品名称", "规格型号", "单位", "数量", "检测单位", "检测结果", "指标", "指标单位", "标准值", "内控值", "检验值"}; for (int i = 0; i < headers.length; i++) { Cell cell = headerRow.createCell(i); cell.setCellValue(headers[i]); cell.setCellStyle(headerStyle); } // 填充数据 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); int rowIndex = 1; for (QualityInspectExportVO vo : exportList) { Row dataRow = sheet.createRow(rowIndex++); createCell(dataRow, 0, vo.getCheckTime() != null ? sdf.format(vo.getCheckTime()) : "", dataStyle); createCell(dataRow, 1, vo.getOrderNo() != null ? vo.getOrderNo() : "", dataStyle); createCell(dataRow, 2, vo.getSupplierOrProcess() != null ? vo.getSupplierOrProcess() : "", dataStyle); createCell(dataRow, 3, vo.getCheckName() != null ? vo.getCheckName() : "", dataStyle); createCell(dataRow, 4, vo.getProductName() != null ? vo.getProductName() : "", dataStyle); createCell(dataRow, 5, vo.getModel() != null ? vo.getModel() : "", dataStyle); createCell(dataRow, 6, vo.getUnit() != null ? vo.getUnit() : "", dataStyle); createCell(dataRow, 7, vo.getQuantity() != null ? vo.getQuantity().toString() : "", dataStyle); createCell(dataRow, 8, vo.getCheckCompany() != null ? vo.getCheckCompany() : "", dataStyle); createCell(dataRow, 9, vo.getCheckResult() != null ? vo.getCheckResult() : "", dataStyle); createCell(dataRow, 10, vo.getParameterItem() != null ? vo.getParameterItem() : "", dataStyle); createCell(dataRow, 11, vo.getParamUnit() != null ? vo.getParamUnit() : "", dataStyle); createCell(dataRow, 12, vo.getStandardValue() != null ? vo.getStandardValue() : "", dataStyle); createCell(dataRow, 13, vo.getControlValue() != null ? vo.getControlValue() : "", dataStyle); createCell(dataRow, 14, vo.getTestValue() != null ? vo.getTestValue() : "", dataStyle); } // 设置列宽 for (int i = 0; i < headers.length; i++) { sheet.setColumnWidth(i, 15 * 256); } // 导出文件名 String fileName = getFileName(inspectType); // 输出 response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); response.setHeader("Access-Control-Expose-Headers", "Content-Disposition"); response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName + ".xlsx", "UTF-8")); OutputStream os = response.getOutputStream(); workbook.write(os); os.flush(); os.close(); workbook.close(); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("导出失败: " + e.getMessage()); } } /** * 创建表头样式 */ private CellStyle createHeaderStyle(Workbook workbook) { CellStyle style = workbook.createCellStyle(); style.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex()); style.setFillPattern(FillPatternType.SOLID_FOREGROUND); style.setAlignment(HorizontalAlignment.CENTER); style.setBorderBottom(BorderStyle.THIN); style.setBorderTop(BorderStyle.THIN); style.setBorderLeft(BorderStyle.THIN); style.setBorderRight(BorderStyle.THIN); Font font = workbook.createFont(); font.setBold(true); style.setFont(font); return style; } /** * 创建数据样式 */ private CellStyle createDataStyle(Workbook workbook) { CellStyle style = workbook.createCellStyle(); style.setAlignment(HorizontalAlignment.CENTER); style.setBorderBottom(BorderStyle.THIN); style.setBorderTop(BorderStyle.THIN); style.setBorderLeft(BorderStyle.THIN); style.setBorderRight(BorderStyle.THIN); return style; } /** * 创建单元格并设置值 */ private void createCell(Row row, int colIndex, String value, CellStyle style) { Cell cell = row.createCell(colIndex); cell.setCellValue(value); cell.setCellStyle(style); } /** * 获取导出文件名 */ private String getFileName(Integer inspectType) { if (inspectType == null) { return "检验导出"; } switch (inspectType) { case 0: return "原材料检验导出"; case 1: return "过程检验导出"; case 2: return "出厂检验导出"; default: return "检验导出"; } } }