package com.steerinfo.dil.util; import org.apache.commons.lang3.StringUtils; import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFDataFormat; import org.apache.poi.hssf.usermodel.HSSFDateUtil; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.usermodel.*; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.apache.tomcat.util.http.fileupload.FileItem; import org.apache.tomcat.util.http.fileupload.FileItemFactory; import org.apache.tomcat.util.http.fileupload.disk.DiskFileItemFactory; import org.springframework.web.multipart.MultipartFile; import java.io.*; import java.text.DecimalFormat; import java.text.NumberFormat; import java.text.SimpleDateFormat; import java.util.*; /** * @Author fubo * @Description excel导入 * @Date 2020/6/10 8:46 **/ public class ExcelToolUtils { /** * MultipartFile转 FileItem 并删除本地临时文件 **/ public static FileItem MultipartFileItem(MultipartFile file) throws Exception { File files = multipartFileToFile(file); FileItem fielitem = createFileItem(files, files.getName()); delteTempFile(files); return fielitem; } /* 创建FileItem */ public static FileItem createFileItem(File file, String fieldName) { FileItemFactory factory = new DiskFileItemFactory(16, null); FileItem item = factory.createItem(fieldName, "text/plain", true, file.getName()); int bytesRead = 0; byte[] buffer = new byte[8192]; try { FileInputStream fis = new FileInputStream(file); OutputStream os = item.getOutputStream(); while ((bytesRead = fis.read(buffer, 0, 8192)) != -1) { os.write(buffer, 0, bytesRead); } os.close(); fis.close(); } catch (IOException e) { e.printStackTrace(); } return item; } /** * MultipartFile 转 File * * @param file * @throws Exception */ public static File multipartFileToFile(MultipartFile file) throws Exception { File toFile = null; if (file.equals("") || file.getSize() <= 0) { file = null; } else { InputStream ins = null; ins = file.getInputStream(); toFile = new File(file.getOriginalFilename()); inputStreamToFile(ins, toFile); ins.close(); } return toFile; } //获取流文件 private static void inputStreamToFile(InputStream ins, File file) { try { OutputStream os = new FileOutputStream(file); int bytesRead = 0; byte[] buffer = new byte[8192]; while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) { os.write(buffer, 0, bytesRead); } os.close(); ins.close(); } catch (Exception e) { e.printStackTrace(); } } /** * 删除本地临时文件 * * @param file */ public static void delteTempFile(File file) { if (file != null) { File del = new File(file.toURI()); del.delete(); } } private static NumberFormat numberFormat = NumberFormat.getInstance(); static { numberFormat.setGroupingUsed(false); } /** * 解析文件的方法. * * @param inputStream 文件输入流, 要解析的Excel文件输入流 * @param fileName 文件名. * @param startRow 从第几行开始读取数据. * @return List 集合中的一个元素对应一行解析的数据. * 元素为字符串数组类型. 数组中的每个元素对应一列数据. * @throws IOException */ public static List parseExcel(InputStream inputStream, String fileName, int startRow) throws Exception { // 1. 定义excel对象变量 Workbook workbook = null; //获取后缀 String suffix = fileName.substring(fileName.lastIndexOf(".")); // 2. 判断后缀.决定使用的解析方式. 决定如何创建具体的对象 if (".xls".equals(suffix)) { // 2003 workbook = new HSSFWorkbook(inputStream); } else if (".xlsx".equals(suffix)) { // 2007 workbook = new XSSFWorkbook(inputStream); } else { // 未知内容 throw new Exception("请选择xls或者xlsx文件!"); } // 获取工作表 excel分为若干个表. sheet Sheet sheet = workbook.getSheetAt(0); if (sheet == null) { return null; } // 获取表格中最后一行的行号 int lastRowNum = sheet.getLastRowNum(); // 最后一行的行号小于startRow if (lastRowNum < startRow) { throw new Exception("请输入数据"); } List result = new ArrayList<>(); // 定义行变量和单元格变量 Row row = null; Cell cell = null; // 循环读取 try{ for (int rowNum = startRow; rowNum <= lastRowNum; rowNum++) { row = sheet.getRow(rowNum); // 获取当前行的第一列和最后一列的标记(列数) short firstCellNum = row.getFirstCellNum();//第一列从0开始 short lastCellNum = row.getLastCellNum();//最后一列 if (lastCellNum != 0) { String[] rowArray = new String[lastCellNum]; for (int cellNum = firstCellNum; cellNum < lastCellNum; cellNum++) { cell = row.getCell(cellNum); // 判断单元格是否有数据 if (cell == null) { rowArray[cellNum] = null; } else { rowArray[cellNum] = parseCell(cell); } } if(rowArray[0] != null || !rowArray[0].equals("")){ result.add(rowArray); } } } } catch (Exception e){ throw new Exception("文件存在隐藏行或合并列!"); } return result; } /** * 解析文件的方法. * * @param inputStream 文件输入流, 要解析的Excel文件输入流 * @param fileName 文件名. * @param startRow 从第几行开始读取数据. * @return List 集合中的一个元素对应一行解析的数据. * 元素为字符串数组类型. 数组中的每个元素对应一列数据. * @throws IOException */ public static List> parseExcels(InputStream inputStream, String fileName, int startRow) throws Exception { // 1. 定义excel对象变量 Workbook workbook = null; //获取后缀 String suffix = fileName.substring(fileName.lastIndexOf(".")); // 2. 判断后缀.决定使用的解析方式. 决定如何创建具体的对象 if (".xls".equals(suffix)) { // 2003 workbook = new HSSFWorkbook(inputStream); } else if (".xlsx".equals(suffix)) { // 2007 workbook = new XSSFWorkbook(inputStream); } else { // 未知内容 throw new Exception("请选择xls或者xlsx文件!"); } List> result = new ArrayList<>(); for (int k = 0; k < workbook.getNumberOfSheets();k++) { // 获取工作表 excel分为若干个表. sheet Sheet sheet = workbook.getSheetAt(k); if (sheet == null) { return null; } // 获取表格中最后一行的行号 int lastRowNum = sheet.getLastRowNum(); // 最后一行的行号小于startRow if (lastRowNum < startRow) { throw new Exception("请输入数据"); } List res = new ArrayList<>(); // 定义行变量和单元格变量 Row row = null; Cell cell = null; // 循环读取 try { for (int rowNum = startRow; rowNum <= lastRowNum; rowNum++) { row = sheet.getRow(rowNum); // 获取当前行的第一列和最后一列的标记(列数) short firstCellNum = row.getFirstCellNum();//第一列从0开始 short lastCellNum = row.getLastCellNum();//最后一列 if (lastCellNum != 0) { String[] rowArray = new String[lastCellNum]; for (int cellNum = firstCellNum; cellNum < lastCellNum; cellNum++) { cell = row.getCell(cellNum); // 判断单元格是否有数据 if (cell == null) { rowArray[cellNum] = null; } else { rowArray[cellNum] = parseCell(cell); } } res.add(rowArray); if (rowArray[0] != null && !"".equals(rowArray[0])) { res.add(rowArray); } } } result.add(res); } catch (Exception e) { e.printStackTrace(); throw new Exception("文件存在隐藏行或合并列!"); } } return result; } /** * 解析单元格 * * @return String 单元格数据 */ private static String parseCell(Cell cell) { //空返回空 if(cell == null){ return null; } String result = null; switch (cell.getCellType()) { case HSSFCell.CELL_TYPE_NUMERIC:// 判断单元格的值是否为数字类型 if (HSSFDateUtil.isCellDateFormatted(cell)) {// 处理日期格式、时间格式 SimpleDateFormat sdf = null; if (cell.getCellStyle().getDataFormat() == HSSFDataFormat .getBuiltinFormat("h:mm")) { sdf = new SimpleDateFormat("HH:mm"); } else {// 日期 sdf = new SimpleDateFormat("yyyy-MM-dd"); } Date date = cell.getDateCellValue(); result = sdf.format(date); } else if (cell.getCellStyle().getDataFormat() == 58) { // 处理自定义日期格式:m月d日(通过判断单元格的格式id解决,id的值是58) /*yyyy年m月d日----->31 yyyy-MM-dd----- 14 yyyy年m月------- 57 m月d日 ----------58 HH:mm-----------20 h时mm分 ------- 32*/ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); double value = cell.getNumericCellValue(); Date date = DateUtil .getJavaDate(value); result = sdf.format(date); } else { // 返回数值类型的值 Object inputValue = null;// 单元格值 Long longVal = Math.round(cell.getNumericCellValue()); Double doubleVal = cell.getNumericCellValue(); if (Double.parseDouble(longVal + ".0") == doubleVal) { //判断是否含有小数位.0 inputValue = longVal; } else { inputValue = doubleVal; } DecimalFormat df = new DecimalFormat("#.##"); //格式化为四位小数,按自己需求选择; result = String.valueOf(df.format(inputValue)); //返回String类型 // double value = cell.getNumericCellValue(); // CellStyle style = cell.getCellStyle(); // DecimalFormat format = new DecimalFormat("0.00"); // String temp = style.getDataFormatString(); // // 单元格设置成常规 // if (temp.equals("General")) { // format.applyPattern("#"); // } // result = format.format(value); } break; case HSSFCell.CELL_TYPE_STRING:// 判断单元格的值是否为String类型 result = cell.getRichStringCellValue().toString(); break; case HSSFCell.CELL_TYPE_BLANK://判断单元格的值是否为布尔类型 result = ""; default: result = ""; break; } return result; } /** * 生成随机数:当前年月日时分秒+四位随机数 * * @return */ public static String getRandom() { SimpleDateFormat simpleDateFormat; simpleDateFormat = new SimpleDateFormat("yyyyMMdd"); Date date = new Date(); String str = simpleDateFormat.format(date);//当前年月日 Random random = new Random(); int rannum = (int) (random.nextDouble() * (9999 - 1000 + 1)) + 1000;// 获取5位随机数 return str + rannum; } /** * 发货单页面生成的随机发货单编号-按前端设定 * * @return */ public static String Random() { SimpleDateFormat simpleDateFormat; simpleDateFormat = new SimpleDateFormat("yyyyMMdd"); Date date = new Date(); String str = simpleDateFormat.format(date);//当前年月日 Random random = new Random(); int rannum = (int) (random.nextDouble() * (99999 - 10000 + 1)) + 10000;// 获取5位随机数 return "CX-" + str + rannum; } //截取字符串中数字-按MEs规则来(前八位位年月日,后面拼编号和英文做辨识) public static String getNumberText(String str){ if(StringUtils.isBlank(str)){ throw new RuntimeException("参数str不能为空"); } StringBuffer number = new StringBuffer(""); String[] strArray = str.split(""); for (String string : strArray) { //if(!StringUtils.isBlank(string) && RegUtils.isNumberText(string)){ // number.append(string); //} } return number.toString()+"XG"; } /** * 获取Excel中的对象数组 * @param file * @param startRow 默认0 * @return * @throws Exception */ public static List> getExcelList(MultipartFile file, int startRow) throws Exception { File excel = multipartFileToFile(file); FileInputStream inputStream = null; String fileName = excel.getName(); // 解决fileName兼容性问题 int lastindex = fileName.lastIndexOf("\\"); fileName = fileName.substring(lastindex + 1); if (fileName != null && fileName.length() > 0) { inputStream = new FileInputStream(excel); } //构建返回数组 List> list = new ArrayList<>(); // 1. 创建工作簿 Workbook workbook = null; // 2. 根据格式解析文件 if (fileName.endsWith(".xls")) { workbook = new HSSFWorkbook(inputStream); }else if(fileName.endsWith(".xlsx")){ workbook = new XSSFWorkbook(inputStream); }else { throw new Exception("请选择xls或者xlsx文件!"); } for (int sheetIndex = 0; sheetIndex < workbook.getNumberOfSheets();sheetIndex++) { // 获取工作表 excel分为若干个表. sheet Sheet sheet = workbook.getSheetAt(sheetIndex); if (sheet == null) { break; } // 获取表格中最后一行的行号 int lastRowNum = sheet.getLastRowNum(); if (lastRowNum < startRow) { throw new Exception("第"+sheetIndex+"个工作簿无数据!请检查Excel!"); } // 定义行变量和单元格变量 Row row = null; Cell cell = null; //获取表头 Row titlesRow = sheet.getRow(startRow); // 获取当前行的第一列和最后一列的标记(列数) int firstCellNum = titlesRow.getFirstCellNum();//第一列 int lastCellNum = titlesRow.getLastCellNum();//最后一列 String[] titles = new String[lastCellNum]; if (lastCellNum > firstCellNum) { for (int cellNum = firstCellNum; cellNum < lastCellNum; cellNum++) { cell = titlesRow.getCell(cellNum); // 判断单元格是否有数据 if (cell == null) { titles[cellNum] = null; } else { titles[cellNum] = parseCell(cell); } } }else { throw new Exception("第"+sheetIndex+"个工作簿无表头数据!请检查Excel!"); } try { //遍历除表头外的所有行 for (int rowNum = startRow+1; rowNum <= lastRowNum; rowNum++) { row = sheet.getRow(rowNum); //遍历行的所有列 Map item = new HashMap<>(); for (int cellNum = firstCellNum; cellNum < lastCellNum; cellNum++) { cell = row.getCell(cellNum); //获取表头对应数据 if (titles[cellNum] != null && !titles[cellNum].equals("") && cell !=null && !cell.toString().equals("")) { item.put(titles[cellNum],parseCell(cell)); } } if(item.keySet().toArray().length >0 ){ list.add(item); } } } catch (Exception e) { e.printStackTrace(); throw new Exception("文件存在隐藏行或合并列!"); } } return list; } }