前端传入Excel解析并保存入数据库
业务需求,前端传回Excel,解析并更新数据库
引入
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-base</artifactId>
<version>4.1.3</version>
</dependency>
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-web</artifactId>
<version>4.1.3</version>
</dependency>
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-annotation</artifactId>
<version>4.1.3</version>
</dependency>
Controller层
/** * 食品检测参数导入,用来更新单价 */ @PostMapping("/import") public R importExcel(@RequestParam("file") MultipartFile file, HttpServletResponse response, HttpServletRequest request) { foodInspectParameterService.importExcel(file,response,request); return R.ok(); }
Service层
/** * @Author Zhang jianwei * @Description 导入EXCEL 用于更新食品参数的单价 * @Date 9:16 2022/3/24 */ @Override public void importExcel(MultipartFile file, HttpServletResponse response, HttpServletRequest request) { JSONArray jsonArray; try { // 获取文件的输入流 InputStream inputStream = file.getInputStream(); // 获取文件名数组的长度 Integer length = file.getOriginalFilename().split("\\.").length; // 取得文件后缀名 String suffix = file.getOriginalFilename().split("\\.")[length - 1]; if (ExcelResolve.XLS.equalsIgnoreCase("."+suffix)) { // 如果后缀为.xls则用HSSFWorkbook jsonArray = ExcelResolve.hssfDeal(inputStream); } else if (ExcelResolve.XLSX.equalsIgnoreCase("."+suffix)) { // 后缀为.xlsx则用XSSFWorkbook jsonArray = ExcelResolve.xssfDeal(file); }else { throw new RRException("文件格式仅支持后缀为:xls 或 xlsx"); } List<FoodInspectParameterEntity> foodInspectParameterEntityList=JSONObject.parseArray(jsonArray.toJSONString(),FoodInspectParameterEntity.class); //批量更新 this.updateBatchById(foodInspectParameterEntityList); System.out.println("更新成功!"); } catch (Exception e) { e.printStackTrace(); } }
工具类
package com.lyjp.common.utils.excel; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.lyjp.common.exception.RRException; import org.apache.poi.hssf.usermodel.HSSFDateUtil; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.poifs.filesystem.POIFSFileSystem; import org.apache.poi.ss.usermodel.*; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.springframework.stereotype.Component; import org.springframework.web.multipart.MultipartFile; import java.io.*; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.Map; @Component public class ExcelResolve { public static final String XLSX = ".xlsx"; public static final String XLS = ".xls"; /** * 获取Excel文件(.xls和.xlsx都支持) * * @param file * @return 解析excle后的Json数据 * @throws IOException * @throws FileNotFoundException * @throws InvalidFormatException */ public static JSONArray readExcel(File file) throws Exception { int res = checkFile(file); if (res == 0) { System.out.println("File not found"); } else if (res == 1) { return readXLSX(file); } else if (res == 2) { return readXLS(file); } JSONArray array = new JSONArray(); return array; } /** * 判断File文件的类型 * * @param file 传入的文件 * @return 0-文件为空,1-XLSX文件,2-XLS文件,3-其他文件 */ public static int checkFile(File file) { if (file == null) { return 0; } String flieName = file.getName(); if (flieName.endsWith(XLSX)) { return 1; } if (flieName.endsWith(XLS)) { return 2; } return 3; } /** * 读取XLSX文件 * * @param file * @return * @throws IOException * @throws InvalidFormatException */ public static JSONArray readXLSX(File file) throws InvalidFormatException, IOException { Workbook book = new XSSFWorkbook(file); Sheet sheet = book.getSheetAt(0); return read(sheet, book); } /** * 读取XLS文件 * * @param file * @return * @throws IOException * @throws FileNotFoundException */ public static JSONArray readXLS(File file) throws FileNotFoundException, IOException { POIFSFileSystem poifsFileSystem = new POIFSFileSystem(new FileInputStream(file)); Workbook book = new HSSFWorkbook(poifsFileSystem); Sheet sheet = book.getSheetAt(0); return read(sheet, book); } /** * 解析数据 * * @param sheet 表格sheet对象 * @param book 用于流关闭 * @return * @throws IOException */ public static JSONArray read(Sheet sheet, Workbook book) throws IOException { int rowStart = sheet.getFirstRowNum(); // 首行下标 int rowEnd = sheet.getLastRowNum(); // 尾行下标 // 如果首行与尾行相同,表明只有一行,直接返回空数组 if (rowStart == rowEnd) { book.close(); return new JSONArray(); } // 获取第一行JSON对象键 Row firstRow = sheet.getRow(rowStart); int cellStart = firstRow.getFirstCellNum(); int cellEnd = firstRow.getLastCellNum(); Map<Integer, String> keyMap = new HashMap<>(); for (int j = cellStart; j < cellEnd; j++) { keyMap.put(j, getValue(firstRow.getCell(j), rowStart, j, book, true)); } // 获取每行JSON对象的值 JSONArray array = new JSONArray(); for (int i = rowStart + 1; i <= rowEnd; i++) { Row eachRow = sheet.getRow(i); JSONObject obj = new JSONObject(); StringBuffer sb = new StringBuffer(); for (int k = cellStart; k < cellEnd; k++) { if (eachRow != null) { String val = getValue(eachRow.getCell(k), i, k, book, false); sb.append(val); // 所有数据添加到里面,用于判断该行是否为空 obj.put(keyMap.get(k), val); } } if (sb.toString().length() > 0) { array.add(obj); } } book.close(); return array; } /** * 获取每个单元格的数据 * * @param cell 单元格对象 * @param rowNum 第几行 * @param index 该行第几个 * @param book 主要用于关闭流 * @param isKey 是否为键:true-是,false-不是。 如果解析Json键,值为空时报错;如果不是Json键,值为空不报错 * @return * @throws IOException */ public static String getValue(Cell cell, int rowNum, int index, Workbook book, boolean isKey) throws IOException { // 空白或空 if (cell == null || cell.getCellType() == CellType._NONE) { if (isKey) { book.close(); throw new NullPointerException(String.format("the key on row %s index %s is null ", ++rowNum, ++index)); } else { return ""; } } // 0. 数字 类型 if (cell.getCellType() == CellType.NUMERIC) { if (HSSFDateUtil.isCellDateFormatted(cell)) { Date date = cell.getDateCellValue(); DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); return df.format(date); } String val = cell.getNumericCellValue() + ""; val = val.toUpperCase(); if (val.contains("E")) { val = val.split("E")[0].replace(".", ""); } return val; } // 1. String类型 if (cell.getCellType() == CellType.STRING) { String val = cell.getStringCellValue(); if (val == null || val.trim().length() == 0) { if (book != null) { book.close(); } return ""; } //对字符串进行替换,替换成对应的字段,用户对象的接收 val=replaceChineseToEnglish(val); return val.trim(); } // 2. 公式 CELL_TYPE_FORMULA if (cell.getCellType() == CellType.FORMULA) { return cell.getStringCellValue(); } // 4. 布尔值 CELL_TYPE_BOOLEAN if (cell.getCellType() == CellType.BOOLEAN) { return cell.getBooleanCellValue() + ""; } // 5. 错误 CELL_TYPE_ERROR return ""; } /** * @Author Zhang jianwei * @Description 将汉字替换成 * @Date 8:40 2022/3/24 * @Param * @return */ private static String replaceChineseToEnglish(String val) { if ("参数编号".equals(val)){ return "id"; }else if ("食品大类".equals(val)){ return "first_kind_name"; }else if ("食品亚类".equals(val)){ return "second_kind_name"; }else if ("食品品种".equals(val)){ return "third_kind_name"; }else if ("食品细类".equals(val)){ return "fourth_kind_name"; }else if ("名称".equals(val)){ return "name"; }else if ("分析方法名称".equals(val)){ return "analysis_method_name"; }else if ("创建时间".equals(val)){ return "create_time"; }else if ("单价".equals(val)){ return "price"; } return val; } /** * *.xlsx文件用XSSFWorkbook处理 * * @return */ public static JSONArray xssfDeal(MultipartFile file) throws IOException { // 创建workbook对象,读取整个文档 XSSFWorkbook workbook = new XSSFWorkbook(file.getInputStream()); Sheet sheet = workbook.getSheetAt(0); // 获取sheet的最大row下标 int lastRowNum = sheet.getLastRowNum(); // 判断第一列标题是否包含 “物料代码” String title = sheet.getRow(0).getCell(0).getStringCellValue(); if (title.indexOf("参数编号") < 0) { throw new RRException("请注意,首列标题须为参数编号!"); } else if (lastRowNum <= 0) { throw new RRException("您导入的excel文件为空,请重新导入!"); } return ExcelResolve.read(sheet,workbook); } /** * *.xls文件用HSSFWorkbook处理 * * @return */ public static JSONArray hssfDeal(InputStream inputStream) throws IOException { // 创建workbook对象,读取整个文档 POIFSFileSystem poifsFileSystem = new POIFSFileSystem(inputStream); HSSFWorkbook wb = new HSSFWorkbook(poifsFileSystem); // 读取页脚sheet HSSFSheet sheetAt = wb.getSheetAt(0); // 判断第一列标题是否包含 “物料代码” String title = sheetAt.getRow(0).getCell(0).getStringCellValue(); if (title.indexOf("参数编号") < 0) { throw new RRException("请注意,首列标题须为参数编号!"); } return ExcelResolve.read(sheetAt,wb); } }
浙公网安备 33010602011771号