From 127d6c63ea00967728448a98d5b67b8584ecb436 Mon Sep 17 00:00:00 2001 From: cwchen <1048842385@qq.com> Date: Mon, 3 Nov 2025 11:15:57 +0800 Subject: [PATCH] =?UTF-8?q?excel=E5=AF=BC=E5=85=A5=E5=85=AC=E5=85=B1?= =?UTF-8?q?=E6=96=B9=E6=B3=95=E3=80=81=E5=B7=A5=E5=99=A8=E5=85=B7=E5=AF=BC?= =?UTF-8?q?=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/enterprise/ToolController.java | 11 + .../web/service/enterprise/ToolService.java | 69 ++- .../web/util/ImportExcelJsonDataUtil.java | 24 +- .../com/bonus/web/util/ImportExcelUtils.java | 448 +++++++++++------- .../common/constant/ImportBeanConstants.java | 2 +- .../domain/mainDatabase/dto/ToolDto.java | 1 + .../mainDataBase/mapper/IMDToolMapper.java | 15 +- .../mainDataBase/service/IMDToolService.java | 13 + .../service/impl/MDToolServiceImpl.java | 5 + .../src/main/resources/mapper/ToolMapper.xml | 33 ++ 10 files changed, 426 insertions(+), 195 deletions(-) diff --git a/bonus-admin/src/main/java/com/bonus/web/controller/enterprise/ToolController.java b/bonus-admin/src/main/java/com/bonus/web/controller/enterprise/ToolController.java index 80aa6f6..8785b75 100644 --- a/bonus-admin/src/main/java/com/bonus/web/controller/enterprise/ToolController.java +++ b/bonus-admin/src/main/java/com/bonus/web/controller/enterprise/ToolController.java @@ -11,8 +11,11 @@ import com.bonus.common.enums.OperaType; import com.bonus.web.service.enterprise.ToolService; import io.swagger.annotations.ApiOperation; import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; import java.util.List; /** @@ -70,4 +73,12 @@ public class ToolController extends BaseController { public AjaxResult detailData(ToolDto dto) { return toolService.detailData(dto); } + + @ApiOperation(value = "工器具库", notes = "工器具导入") + @PostMapping("importData") + @SysLog(title = "工器具库", module = "企业知识库->工器具库->工器具导入", businessType = OperaType.IMPORT, details = "工器具导入", logType = 1) + @RequiresPermissions("enterpriseLibrary:tool:import") + public AjaxResult importData(ToolDto dto, MultipartFile file) { + return toolService.importData(dto,file); + } } diff --git a/bonus-admin/src/main/java/com/bonus/web/service/enterprise/ToolService.java b/bonus-admin/src/main/java/com/bonus/web/service/enterprise/ToolService.java index 7e5ee5e..3ca1b85 100644 --- a/bonus-admin/src/main/java/com/bonus/web/service/enterprise/ToolService.java +++ b/bonus-admin/src/main/java/com/bonus/web/service/enterprise/ToolService.java @@ -1,24 +1,37 @@ package com.bonus.web.service.enterprise; +import com.alibaba.fastjson2.JSONObject; import com.bonus.common.constant.TableConstants; import com.bonus.common.core.domain.AjaxResult; import com.bonus.common.domain.file.po.ResourceFilePo; import com.bonus.common.domain.file.vo.ResourceFileVo; import com.bonus.common.domain.mainDatabase.dto.TechnicalDto; import com.bonus.common.domain.mainDatabase.dto.ToolDto; +import com.bonus.common.domain.mainDatabase.importdto.ToolImportDto; import com.bonus.common.domain.mainDatabase.vo.TechnicalVo; import com.bonus.common.domain.mainDatabase.vo.ToolVo; import com.bonus.common.utils.ValidatorsUtils; import com.bonus.file.service.FileUploadService; import com.bonus.file.service.SourceFileService; import com.bonus.mainDataBase.service.IMDToolService; +import com.bonus.web.util.ImportExcelUtils; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.interceptor.TransactionAspectSupport; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.multipart.MultipartHttpServletRequest; +import org.springframework.web.multipart.commons.CommonsMultipartResolver; import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.ArrayList; import java.util.List; /** @@ -42,29 +55,34 @@ public class ToolService { @Resource(name = "FileUploadService") private FileUploadService fileUploadService; + @Resource(name = "ImportExcelUtils") + private ImportExcelUtils importExcelUtils; + @Resource(name = "ValidatorsUtils") private ValidatorsUtils validatorsUtils; /** * 企业知识库->工器具库->查询数据列表 + * * @param dto * @return List * @author cwchen * @date 2025/10/30 13:46 */ public List getList(ToolDto dto) { - return imdToolService.getList(dto); + return imdToolService.getList(dto); } - /** * 企业知识库->工器具库->新增工器具数据 + * * @param dto * @return AjaxResult * @author cwchen * @date 2025/10/30 13:47 */ + @Transactional(rollbackFor = Exception.class) public AjaxResult addData(ToolDto dto) { // 校验数据是否合法 String validResult = validatorsUtils.valid(dto, TechnicalDto.TechnicalDataDto.ADD.class); @@ -74,7 +92,7 @@ public class ToolService { try { // 1.校验工器具名称是否重复 int result = imdToolService.isRepeat(dto); - if(result > 0){ + if (result > 0) { return AjaxResult.error("工器具名称重复"); } // 2.添加工器具数据 @@ -95,11 +113,13 @@ public class ToolService { /** * 企业知识库->工器具库->修改工器具数据 + * * @param dto * @return AjaxResult * @author cwchen * @date 2025/10/30 13:47 */ + @Transactional(rollbackFor = Exception.class) public AjaxResult editData(ToolDto dto) { // 1.校验数据是否合法 String validResult = validatorsUtils.valid(dto, ToolDto.UPDATE.class); @@ -109,7 +129,7 @@ public class ToolService { try { // 1.校验工器具名称是否重复 int result = imdToolService.isRepeat(dto); - if(result > 0){ + if (result > 0) { return AjaxResult.error("工器具名称重复"); } // 2.修改主体库数据 @@ -136,11 +156,13 @@ public class ToolService { /** * 企业知识库->工器具库->删除工器具数据 + * * @param dto * @return AjaxResult * @author cwchen * @date 2025/10/30 13:47 */ + @Transactional(rollbackFor = Exception.class) public AjaxResult delData(ToolDto dto) { // 校验数据是否合法 String validResult = validatorsUtils.valid(dto, ToolDto.DELETE.class); @@ -151,7 +173,7 @@ public class ToolService { // 删除工器具数据 imdToolService.operData(dto, 3); // 删除工器具相关资源文件 - sourceFileService.delResourceFileByTable(dto.getToolId(),TableConstants.TB_ENTERPRISE_TOOL); + sourceFileService.delResourceFileByTable(dto.getToolId(), TableConstants.TB_ENTERPRISE_TOOL); } catch (Exception e) { log.error(e.toString(), e); TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); @@ -162,6 +184,7 @@ public class ToolService { /** * 企业知识库->工器具库->工器具详情 + * * @param dto * @return AjaxResult * @author cwchen @@ -170,10 +193,44 @@ public class ToolService { public AjaxResult detailData(ToolDto dto) { ToolVo vo = new ToolVo(); // 1.查询关联资源文件 - List fileVoList = sourceFileService.getFilesByTable(dto.getToolId(),TableConstants.TB_ENTERPRISE_TOOL); + List fileVoList = sourceFileService.getFilesByTable(dto.getToolId(), TableConstants.TB_ENTERPRISE_TOOL); // 2.取minio中的文件访问路径 List resourceFileVos = fileUploadService.setFile(fileVoList); vo.setResourceFileVoList(resourceFileVos); return AjaxResult.success(vo); } + + /** + * 企业知识库->工器具库->工器具导入 + * @param dto + * @param file + * @return AjaxResult + * @author cwchen + * @date 2025/11/3 9:35 + */ + @Transactional(rollbackFor = Exception.class) + public AjaxResult importData(ToolDto dto, MultipartFile file) { + try { + List lstObj = importExcelUtils.readExcel(file, ToolImportDto.class, null); + ObjectMapper mapper = new ObjectMapper(); + mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + List toolList = mapper.convertValue(lstObj, new TypeReference>() {}); + // 添加工器具数据 + imdToolService.batchImportData(dto,toolList); + // 3.添加文件 + List files = new ArrayList<>(); + for (ToolDto toolDto : toolList) { + for (ResourceFilePo po : toolDto.getFiles()) { + po.setBusinessId(toolDto.getToolId()); // 业务id + po.setSourceTable(TableConstants.TB_ENTERPRISE_TOOL); // 来源表 + files.add(po); + } + } + sourceFileService.saveResourceFile(files); + } catch (Exception e) { + log.error(e.toString(), e); + return AjaxResult.error(e.getMessage()); + } + return AjaxResult.success(); + } } diff --git a/bonus-admin/src/main/java/com/bonus/web/util/ImportExcelJsonDataUtil.java b/bonus-admin/src/main/java/com/bonus/web/util/ImportExcelJsonDataUtil.java index 94fdee3..dce7036 100644 --- a/bonus-admin/src/main/java/com/bonus/web/util/ImportExcelJsonDataUtil.java +++ b/bonus-admin/src/main/java/com/bonus/web/util/ImportExcelJsonDataUtil.java @@ -25,29 +25,29 @@ public class ImportExcelJsonDataUtil { */ public static JSONObject getToolObj(Row row, JSONObject obj, List> filename){ obj.put("rowNo", row.getRowNum() + 1); - if (row.getCell(0) != null) { + if (row.getCell(1) != null) { // 工器具名称 - obj.put("toolName", row.getCell(0).getStringCellValue()); + obj.put("toolName", row.getCell(1).getStringCellValue()); } - if (row.getCell(1) != null) { + if (row.getCell(2) != null) { // 规格型号 - obj.put("model", row.getCell(1).getStringCellValue()); + obj.put("model", row.getCell(2).getStringCellValue()); } - if (row.getCell(1) != null) { + if (row.getCell(3) != null) { // 单位 - obj.put("unit", row.getCell(1).getStringCellValue()); + obj.put("unit", row.getCell(3).getStringCellValue()); } - if (row.getCell(1) != null) { + if (row.getCell(4) != null) { // 技术参数 - obj.put("technicalParameters", row.getCell(1).getStringCellValue()); + obj.put("technicalParameters", row.getCell(4).getStringCellValue()); } - if (row.getCell(1) != null) { + if (row.getCell(5) != null) { // 主要作用 - obj.put("mainFunction", row.getCell(1).getStringCellValue()); + obj.put("mainFunction", row.getCell(5).getStringCellValue()); } - if (row.getCell(1) != null) { + if (row.getCell(6) != null) { // 备注 - obj.put("remark", row.getCell(1).getStringCellValue()); + obj.put("remark", row.getCell(6).getStringCellValue()); } // 工器具图片 String result = "TOOL" + "_" + row.getRowNum(); diff --git a/bonus-admin/src/main/java/com/bonus/web/util/ImportExcelUtils.java b/bonus-admin/src/main/java/com/bonus/web/util/ImportExcelUtils.java index 06a0903..7b15213 100644 --- a/bonus-admin/src/main/java/com/bonus/web/util/ImportExcelUtils.java +++ b/bonus-admin/src/main/java/com/bonus/web/util/ImportExcelUtils.java @@ -34,254 +34,352 @@ public class ImportExcelUtils { private static final Logger log = LoggerFactory.getLogger(ImportExcelUtils.class); - public List readExcel(MultipartFile file, Class mClass, String uploadPath) throws Exception { String fileName = file.getOriginalFilename(); - log.info("OriginalFilename:{}", fileName); + log.info("OriginalFilename: {}", fileName); + + validateFile(fileName); + + String className = mClass.getSimpleName(); + log.info("className: {}", className); + + // 使用 try-with-resources 确保资源正确关闭 + try (InputStream inputStream = file.getInputStream()) { + Workbook workbook = createWorkbook(inputStream, fileName); + Sheet sheet = workbook.getSheetAt(0); + + validateTemplate(sheet, className); + + Map mapData = extractPictures(workbook, sheet, className, fileName); + List> filenames = processImages(mapData, className, uploadPath); + + logExcelInfo(workbook, sheet, filenames); + + return createBeanList(sheet, mClass, filenames); + } catch (Exception e) { + log.error("读取Excel文件失败: {}", fileName, e); + throw e; + } + } + + private void validateFile(String fileName) { + if (StringUtils.isBlank(fileName)) { + throw new ServiceException("文件名不能为空!"); + } if (!StringUtils.endsWithAny(fileName, ".xls", ".xlsx")) { throw new ServiceException("不支持excel以外的文件导入!"); } - List list = new ArrayList<>(); - InputStream inputStream = file.getInputStream(); - String className = mClass.getSimpleName(); - log.info("className:{}", className); - //根据指定的文件输入流导入Excel从而产生Workbook对象 - Workbook workbook = null; - Sheet sheet = null; - Map mapData = null; - if (null != fileName && fileName.endsWith(".xls")) { - workbook = new HSSFWorkbook(inputStream); - //获取Excel文档中的第一个表单 - sheet = workbook.getSheetAt(0); - if (!checkModal(sheet, className)) { - throw new ServiceException("模板错误,请重新选择模板!"); - } - mapData = getPicturesXls((HSSFSheet) sheet, className); + } + + private Workbook createWorkbook(InputStream inputStream, String fileName) throws IOException { + if (fileName.endsWith(".xls")) { + return new HSSFWorkbook(inputStream); + } else if (fileName.endsWith(".xlsx")) { + return new XSSFWorkbook(inputStream); + } else { + throw new ServiceException("不支持的文件格式:" + fileName); } - if (null != fileName && fileName.endsWith(".xlsx")) { - workbook = new XSSFWorkbook(inputStream); - //获取Excel文档中的第一个表单 - sheet = workbook.getSheetAt(0); - if (!checkModal(sheet, className)) { - throw new ServiceException("模板错误,请重新选择模板!"); - } - mapData = getPicturesXlsx((XSSFSheet) sheet, className); + } + + private void validateTemplate(Sheet sheet, String className) { + if (sheet == null || sheet.getRow(0) == null) { + throw new ServiceException("模板为空或格式错误!"); } - List> filenames = new ArrayList<>(); - if (ImportBeanConstants.TOOL_IMPORT_DTO.equals(className)) { // 工器具 - log.info("开始读取并写入图片"); - filenames = writeImg(mapData, className, uploadPath); - log.info("图片:{},写入完成!", filenames); + + if (!checkModal(sheet, className)) { + throw new ServiceException("模板错误,请重新选择模板!"); } - int sheetCount = 0; - if (workbook != null) { - workbook.getNumberOfSheets(); - } - log.info("Sheet(表单)数量:{}", sheetCount); - log.info("filenames:{}", filenames); - //获得最后一条记录得的行号,从0开始 - int totalRowNum = 0; - if (sheet != null) { - totalRowNum = sheet.getLastRowNum(); - } - log.info("总记录数:{}", (totalRowNum + 1)); - list = createBean(sheet, mClass, filenames); - inputStream.close(); - return list; } private static boolean checkModal(Sheet sheet, String className) { - int colNum = sheet.getRow(0).getLastCellNum(); + Row headerRow = sheet.getRow(0); + if (headerRow == null) { + return false; + } + + int colNum = headerRow.getLastCellNum(); if (ImportBeanConstants.TOOL_IMPORT_DTO.equals(className)) { return colNum == ImportBeanConstants.TOOL_IMPORT_DTO_NUM; } + // 可以在这里添加其他类的模板验证 return false; } - private static List createBean(Sheet sheet, Class mClass, List> filename) throws Exception { - if (sheet == null || sheet.getLastRowNum() < 0) { - return null; + private Map extractPictures(Workbook workbook, Sheet sheet, String className, String fileName) throws IOException { + if (fileName.endsWith(".xls")) { + return getPicturesXls((HSSFSheet) sheet, className); + } else { + return getPicturesXlsx((XSSFSheet) sheet, className); } + } + + private List> processImages(Map mapData, String className, String uploadPath) { + if (!ImportBeanConstants.TOOL_IMPORT_DTO.equals(className) || mapData == null || mapData.isEmpty()) { + return new ArrayList<>(); + } + + log.info("开始读取并写入图片,数量:{}", mapData.size()); + try { + List> filenames = writeImg(mapData, className, uploadPath); + log.info("图片写入完成!"); + return filenames; + } catch (IOException e) { + log.error("图片写入失败", e); + return new ArrayList<>(); + } + } + + private void logExcelInfo(Workbook workbook, Sheet sheet, List> filenames) { + if (workbook != null) { + int sheetCount = workbook.getNumberOfSheets(); + log.info("Sheet(表单)数量:{}", sheetCount); + } + + if (sheet != null) { + int totalRowNum = sheet.getLastRowNum(); + log.info("总记录数: {}", totalRowNum + 1); + } + + log.debug("filenames: {}", filenames); + } + + private static List createBeanList(Sheet sheet, Class mClass, List> filename) { + if (sheet == null) { + return Collections.emptyList(); + } + List list = new ArrayList<>(); - int last = sheet.getRow(0).getLastCellNum();// 总列数 - log.info("列数:{}", last); + String className = mClass.getSimpleName(); + int totalColumns = getTotalColumns(sheet); + log.info("列数: {}", totalColumns); + try { for (Row row : sheet) { - if (row == null) { + if (shouldSkipRow(row, className)) { continue; } - // 第一行是标题栏 - if (ImportBeanConstants.TOOL_IMPORT_DTO.equals(mClass.getSimpleName())) { - if (row.getRowNum() < 1) { - continue; - } + + JSONObject obj = processRowData(row, mClass, filename); + if (obj != null) { + list.add(obj); } - boolean isBlankRow = true; - for (Cell c : row) { - if (c.getCellType() != CellType.BLANK) { - isBlankRow = false; - break; - } - } - if (isBlankRow) { - continue; - } - JSONObject obj = new JSONObject(); - if (ImportBeanConstants.TOOL_IMPORT_DTO.equals(mClass.getSimpleName())) { // 工器具 - setExcleTString(5, row); - obj = ImportExcelJsonDataUtil.getToolObj(row, obj, filename); - } - list.add(obj); } } catch (IllegalStateException e) { - e.printStackTrace(); + log.error("处理Excel数据时发生格式错误", e); throw new ServiceException("模板中含有单元格数据格式不正确"); } + return list; } + private static int getTotalColumns(Sheet sheet) { + Row firstRow = sheet.getRow(0); + return firstRow != null ? firstRow.getLastCellNum() : 0; + } + + private static boolean shouldSkipRow(Row row, String className) { + if (row == null || isBlankRow(row)) { + return true; + } + + // 根据不同的DTO类型跳过标题行 + if (ImportBeanConstants.TOOL_IMPORT_DTO.equals(className)) { + return row.getRowNum() < 2; + } + + return false; + } + + private static boolean isBlankRow(Row row) { + for (Cell cell : row) { + if (cell != null && cell.getCellType() != CellType.BLANK) { + return false; + } + } + return true; + } + + private static JSONObject processRowData(Row row, Class mClass, List> filename) { + String className = mClass.getSimpleName(); + + // 设置前6列为字符串类型以避免格式问题 + setCellsToStringType(row, 6); + + if (ImportBeanConstants.TOOL_IMPORT_DTO.equals(className)) { + return ImportExcelJsonDataUtil.getToolObj(row, new JSONObject(), filename); + } + // 可以在这里添加其他类的处理逻辑 + + return null; + } /** * 获取图片和位置 (xlsx) - * - * @param sheet - * @return - * @throws IOException */ public static Map getPicturesXlsx(XSSFSheet sheet, String className) throws IOException { Map map = new HashMap<>(16); List list = sheet.getRelations(); + for (POIXMLDocumentPart part : list) { if (part instanceof XSSFDrawing) { XSSFDrawing drawing = (XSSFDrawing) part; - List shapes = drawing.getShapes(); - - for (XSSFShape shape : shapes) { - XSSFPicture picture = (XSSFPicture) shape; - XSSFClientAnchor anchor = picture.getPreferredSize(); - CTMarker marker = anchor.getFrom(); - Row row = sheet.getRow(marker.getRow()); - if (row == null) { - continue; - } - String key_name = null; - if (ImportBeanConstants.TOOL_IMPORT_DTO.equals(className)) { - key_name = setKey(picture, row, ImportBeanConstants.TOOL_IMPORT_DTO); - } else { - key_name = ""; - } - map.put(key_name, picture.getPictureData()); - } + processXlsxShapes(drawing, sheet, className, map); } } - - return map; } + private static void processXlsxShapes(XSSFDrawing drawing, XSSFSheet sheet, String className, Map map) { + for (XSSFShape shape : drawing.getShapes()) { + if (shape instanceof XSSFPicture) { + XSSFPicture picture = (XSSFPicture) shape; + processXlsxPicture(picture, sheet, className, map); + } + } + } + + private static void processXlsxPicture(XSSFPicture picture, XSSFSheet sheet, String className, Map map) { + XSSFClientAnchor anchor = picture.getPreferredSize(); + CTMarker marker = anchor.getFrom(); + Row row = sheet.getRow(marker.getRow()); + + if (row != null) { + String key = generatePictureKey(picture, row, className); + if (StringUtils.isNotBlank(key)) { + map.put(key, picture.getPictureData()); + } + } + } + /** * 获取图片和位置 (xls) - * - * @param sheet - * @return - * @throws IOException */ public static Map getPicturesXls(HSSFSheet sheet, String className) throws IOException { - int i = 0; - Map map = new HashMap(16); - if (sheet.getDrawingPatriarch() != null) { - List list = sheet.getDrawingPatriarch().getChildren(); - for (HSSFShape shape : list) { + Map map = new HashMap<>(16); + + HSSFPatriarch drawingPatriarch = sheet.getDrawingPatriarch(); + + if (drawingPatriarch != null) { + List shapes = drawingPatriarch.getChildren(); + for (HSSFShape shape : shapes) { if (shape instanceof HSSFPicture) { HSSFPicture picture = (HSSFPicture) shape; - int pictureIndex = ((HSSFPicture) shape).getPictureIndex(); - if (pictureIndex != -1) { - HSSFClientAnchor cAnchor = picture.getClientAnchor(); - Row row = sheet.getRow(cAnchor.getRow1()); - if (row == null) { - continue; - } - String key_name = null; - if (ImportBeanConstants.TOOL_IMPORT_DTO.equals(className)) { // 工器具 - if (cAnchor.getCol1() == 6) { - key_name = "TOOL" + "_" + cAnchor.getRow1(); - } - } - map.put(key_name, picture.getPictureData()); - } + processXlsPicture(picture, sheet, className, map); } } } return map; } - //图片写出 - public List> writeImg(Map mapData, String className, String uploadPath) throws IOException { - int pictureIndex = 0; - if (mapData == null || mapData.size() == 0) { - return new ArrayList<>(); - } - Object[] keyArr = mapData.keySet().toArray(); - ArrayList> filename = new ArrayList<>(); - for (int i = 0; i < mapData.size(); i++) { - Map map = new HashMap<>(16); - // 获取图片流 - PictureData pic = mapData.get(keyArr[i]); - // 获取图片索引 - String picName = keyArr[i].toString(); - byte[] data = pic.getData(); - String picPath = null; - // 获取文件后缀 - String fileExtension = ExcelImageUtils.getFileExtension(pic); - // 生成自定义文件名 - String fileName = String.format("sheet%d_picture%d.%s", - i, pictureIndex++, fileExtension); - String params = null; - if (ImportBeanConstants.TOOL_IMPORT_DTO.equals(className)) { // 工器具 - params = "{\"suffix\":\"tools_database\",\"fileUploadType\":\"tools\"}"; + private static void processXlsPicture(HSSFPicture picture, HSSFSheet sheet, String className, Map map) { + if (picture.getPictureIndex() != -1) { + HSSFClientAnchor anchor = (HSSFClientAnchor) picture.getAnchor(); + Row row = sheet.getRow(anchor.getRow1()); + + if (row != null) { + String key = generatePictureKey(anchor.getCol1(), row.getRowNum(), className); + if (StringUtils.isNotBlank(key)) { + map.put(key, picture.getPictureData()); + } } - MultipartFile multipartFile = FileUtil.byteArrayToMultipartFile(data, fileName); - AjaxResult ajaxResult = commonUploadService.uploadSmallFile(multipartFile, params); - JSONObject objData = (JSONObject) ajaxResult.get("data"); - JSONObject fileRes = objData.getJSONObject("fileRes"); - filename.add(fileRes); } - return filename; } + // 图片写出 + public List> writeImg(Map mapData, String className, String uploadPath) throws IOException { + if (mapData == null || mapData.isEmpty()) { + return new ArrayList<>(); + } - private static String setKey(XSSFPicture picture, Row row, String className) { + List> filenames = new ArrayList<>(); + int pictureIndex = 0; + + // 使用 entrySet 遍历,性能更好 + for (Map.Entry entry : mapData.entrySet()) { + Map map = new HashMap<>(); + Map fileInfo = processSingleImage(entry.getValue(), entry.getKey(), className, pictureIndex++); + if (fileInfo != null) { + map.put(entry.getKey(), Collections.singleton(fileInfo)); + filenames.add(map); + } + } + + return filenames; + } + + private Map processSingleImage(PictureData pic, String picName, String className, int pictureIndex) throws IOException { + try { + byte[] data = pic.getData(); + String fileExtension = ExcelImageUtils.getFileExtension(pic); + String fileName = String.format("sheet_picture%d.%s", pictureIndex, fileExtension); + + String params = getUploadParams(className); + if (params == null) { + return null; + } + + MultipartFile multipartFile = FileUtil.byteArrayToMultipartFile(data, fileName); + AjaxResult ajaxResult = commonUploadService.uploadSmallFile(multipartFile, params); + JSONObject resultData = JSONObject.from(ajaxResult.get("data")); + JSONObject fileRes = resultData.getJSONObject("fileRes"); + if (Objects.nonNull(fileRes)) { + return fileRes; + } + log.warn("上传图片返回结果异常: {}", picName); + return null; + } catch (Exception e) { + log.error(e.toString(), e); + return null; + } + } + + private String getUploadParams(String className) { + if (ImportBeanConstants.TOOL_IMPORT_DTO.equals(className)) { + return "{\"suffix\":\"tools_database\",\"fileUploadType\":\"tools\"}"; + } + // 可以在这里添加其他类的上传参数 + return null; + } + + private static String generatePictureKey(XSSFPicture picture, Row row, String className) { if (row == null) { return null; } - ; + String result = picture.getPreferredSize().toString(); - String pattern = "\\[1-9]\\d*\\<\\/xdr\\:col\\>"; - Pattern r = Pattern.compile(pattern); - String col = ""; - Matcher m = r.matcher(result); - if (m.find()) { - col = m.group(0); + Pattern pattern = Pattern.compile("\\([1-9]\\d*)\\<\\/xdr\\:col\\>"); + Matcher matcher = pattern.matcher(result); + + if (matcher.find()) { + String col = matcher.group(0); + return generatePictureKeyFromCol(col, row.getRowNum(), className); } else { - System.out.println("NO MATCH"); - } - if (ImportBeanConstants.TOOL_IMPORT_DTO.equals(className)) { // 工器具 - switch (col) { - case "6": - return "TOOL" + "_" + row.getRowNum(); - } - } else { - return ""; + log.debug("未匹配到列信息: {}", result); } return null; } - private static void setExcleTString(int j, Row row) { - for (int i = 0; i < j; i++) { - if (row.getCell(i) != null) { - row.getCell(i).setCellType(CellType.STRING); + private static String generatePictureKey(int col, int rowNum, String className) { + if (ImportBeanConstants.TOOL_IMPORT_DTO.equals(className) && col == 7) { + return "TOOL" + "_" + rowNum; + } + return null; + } + + private static String generatePictureKeyFromCol(String col, int rowNum, String className) { + if (ImportBeanConstants.TOOL_IMPORT_DTO.equals(className) && "7".equals(col)) { + return "TOOL" + "_" + rowNum; + } + return null; + } + + private static void setCellsToStringType(Row row, int maxColumnIndex) { + for (int i = 0; i <= maxColumnIndex; i++) { + Cell cell = row.getCell(i); + if (cell != null) { + cell.setCellType(CellType.STRING); } } } -} +} \ No newline at end of file diff --git a/bonus-common/src/main/java/com/bonus/common/constant/ImportBeanConstants.java b/bonus-common/src/main/java/com/bonus/common/constant/ImportBeanConstants.java index 298f9c7..142675f 100644 --- a/bonus-common/src/main/java/com/bonus/common/constant/ImportBeanConstants.java +++ b/bonus-common/src/main/java/com/bonus/common/constant/ImportBeanConstants.java @@ -12,5 +12,5 @@ public class ImportBeanConstants { /**工器具导入实体类*/ public static final String TOOL_IMPORT_DTO = "ToolImportDto"; /**工器具导入实体类列数*/ - public static final int TOOL_IMPORT_DTO_NUM = 7; + public static final int TOOL_IMPORT_DTO_NUM = 8; } diff --git a/bonus-common/src/main/java/com/bonus/common/domain/mainDatabase/dto/ToolDto.java b/bonus-common/src/main/java/com/bonus/common/domain/mainDatabase/dto/ToolDto.java index 3f2a848..b106353 100644 --- a/bonus-common/src/main/java/com/bonus/common/domain/mainDatabase/dto/ToolDto.java +++ b/bonus-common/src/main/java/com/bonus/common/domain/mainDatabase/dto/ToolDto.java @@ -3,6 +3,7 @@ package com.bonus.common.domain.mainDatabase.dto; import com.bonus.common.core.domain.model.LoginUser; import com.bonus.common.domain.file.po.ResourceFilePo; import com.bonus.common.utils.SecurityUtils; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import lombok.Data; import org.hibernate.validator.constraints.Length; diff --git a/bonus-mainDatabase/src/main/java/com/bonus/mainDataBase/mapper/IMDToolMapper.java b/bonus-mainDatabase/src/main/java/com/bonus/mainDataBase/mapper/IMDToolMapper.java index 34721a8..fea82ed 100644 --- a/bonus-mainDatabase/src/main/java/com/bonus/mainDataBase/mapper/IMDToolMapper.java +++ b/bonus-mainDatabase/src/main/java/com/bonus/mainDataBase/mapper/IMDToolMapper.java @@ -19,6 +19,7 @@ import java.util.List; public interface IMDToolMapper { /** * 企业知识库->工器具库->查询数据列表 + * * @param dto * @return List * @author cwchen @@ -28,6 +29,7 @@ public interface IMDToolMapper { /** * 企业知识库->工器具库->查询工器具名称是否重复 + * * @param dto * @return int * @author cwchen @@ -37,11 +39,22 @@ public interface IMDToolMapper { /** * 企业知识库->工器具库->操作工器具数据 + * * @param dto * @param type * @return void * @author cwchen * @date 2025/10/30 14:02 */ - void operData(@Param("params") ToolDto dto, @Param("type")int type); + void operData(@Param("params") ToolDto dto, @Param("type") int type); + + /** + * 企业知识库->工器具库->工器具导入 + * @param dto + * @param toolList + * @return void + * @author cwchen + * @date 2025/11/3 10:56 + */ + void batchImportData(@Param("params")ToolDto dto, @Param("list")List toolList); } diff --git a/bonus-mainDatabase/src/main/java/com/bonus/mainDataBase/service/IMDToolService.java b/bonus-mainDatabase/src/main/java/com/bonus/mainDataBase/service/IMDToolService.java index 651abdf..39fcb66 100644 --- a/bonus-mainDatabase/src/main/java/com/bonus/mainDataBase/service/IMDToolService.java +++ b/bonus-mainDatabase/src/main/java/com/bonus/mainDataBase/service/IMDToolService.java @@ -17,6 +17,7 @@ public interface IMDToolService { /** * 企业知识库->工器具库->查询数据列表 + * * @param dto * @return List * @author cwchen @@ -26,6 +27,7 @@ public interface IMDToolService { /** * 企业知识库->工器具库->操作工器具数据 + * * @param dto * @param type * @return void @@ -36,10 +38,21 @@ public interface IMDToolService { /** * 企业知识库->工器具库->查询工器具名称是否重复 + * * @param dto * @return int * @author cwchen * @date 2025/10/30 14:00 */ int isRepeat(ToolDto dto); + + /** + * 企业知识库->工器具库->工器具导入 + * @param dto + * @param toolList + * @return void + * @author cwchen + * @date 2025/11/3 10:55 + */ + void batchImportData(ToolDto dto, List toolList); } diff --git a/bonus-mainDatabase/src/main/java/com/bonus/mainDataBase/service/impl/MDToolServiceImpl.java b/bonus-mainDatabase/src/main/java/com/bonus/mainDataBase/service/impl/MDToolServiceImpl.java index f5ac019..ee14c31 100644 --- a/bonus-mainDatabase/src/main/java/com/bonus/mainDataBase/service/impl/MDToolServiceImpl.java +++ b/bonus-mainDatabase/src/main/java/com/bonus/mainDataBase/service/impl/MDToolServiceImpl.java @@ -51,4 +51,9 @@ public class MDToolServiceImpl implements IMDToolService { return 0; } } + + @Override + public void batchImportData(ToolDto dto, List toolList) { + imdToolMapper.batchImportData(dto,toolList); + } } diff --git a/bonus-mainDatabase/src/main/resources/mapper/ToolMapper.xml b/bonus-mainDatabase/src/main/resources/mapper/ToolMapper.xml index 25e1fa5..910f89f 100644 --- a/bonus-mainDatabase/src/main/resources/mapper/ToolMapper.xml +++ b/bonus-mainDatabase/src/main/resources/mapper/ToolMapper.xml @@ -49,6 +49,39 @@ UPDATE tb_enterprise_tool SET del_flag = '1' WHERE tool_id = #{params.toolId} + + + INSERT INTO tb_enterprise_tool + + enterprise_id, + tool_name, + model, + unit, + technical_parameters, + main_function, + remark, + create_user_id, + create_user_name, + update_user_id, + update_user_name + + VALUES + + ( + #{params.enterpriseId}, + #{item.toolName}, + #{item.model}, + #{item.unit}, + #{item.technicalParameters}, + #{item.mainFunction}, + #{item.remark}, + #{item.createUserId}, + #{item.createUserName}, + #{item.updateUserId}, + #{item.updateUserName} + ) + +