From a5024f2dd2f9f3db66ac1ef1111b7300eca6fdb9 Mon Sep 17 00:00:00 2001 From: fumeiai Date: Wed, 20 May 2020 23:57:07 +0800 Subject: [PATCH] add file upload method --- ...=> Maven__commons_io_commons_io_1_3_2.xml} | 8 +- .idea/workspace.xml | 38 +- lz_management.iml | 2 +- pom.xml | 6 + .../java/com/lz/common/utils/DateUtils.java | 4 + .../java/com/lz/common/utils/ExcelUtil.java | 1118 +++++++++++++++++ .../com/lz/common/utils/excel/ExcelCell.java | 90 ++ .../com/lz/common/utils/excel/ExcelLog.java | 100 ++ .../com/lz/common/utils/excel/ExcelLogs.java | 82 ++ .../com/lz/common/utils/excel/ExcelSheet.java | 87 ++ .../common/utils/excel/FieldForSortting.java | 80 ++ .../app/controller/StaffController.java | 86 +- .../lz/modules/app/service/StaffService.java | 1 + .../app/service/impl/StaffServiceImpl.java | 83 +- ...tsJob.java => SyncnizeFlybookDataJob.java} | 8 +- src/test/java/com/lz/FumeiaiTest.java | 9 +- .../lz/modules/sys/oauth2/OAuth2Filter.class | Bin 3694 -> 3898 bytes 17 files changed, 1750 insertions(+), 52 deletions(-) rename .idea/libraries/{Maven__commons_io_commons_io_2_5.xml => Maven__commons_io_commons_io_1_3_2.xml} (64%) create mode 100644 src/main/java/com/lz/common/utils/ExcelUtil.java create mode 100644 src/main/java/com/lz/common/utils/excel/ExcelCell.java create mode 100644 src/main/java/com/lz/common/utils/excel/ExcelLog.java create mode 100644 src/main/java/com/lz/common/utils/excel/ExcelLogs.java create mode 100644 src/main/java/com/lz/common/utils/excel/ExcelSheet.java create mode 100644 src/main/java/com/lz/common/utils/excel/FieldForSortting.java rename src/main/java/com/lz/modules/job/task/{GetFeishuDepartmentsJob.java => SyncnizeFlybookDataJob.java} (76%) diff --git a/.idea/libraries/Maven__commons_io_commons_io_2_5.xml b/.idea/libraries/Maven__commons_io_commons_io_1_3_2.xml similarity index 64% rename from .idea/libraries/Maven__commons_io_commons_io_2_5.xml rename to .idea/libraries/Maven__commons_io_commons_io_1_3_2.xml index 9c180e5f..f06fc4b3 100644 --- a/.idea/libraries/Maven__commons_io_commons_io_2_5.xml +++ b/.idea/libraries/Maven__commons_io_commons_io_1_3_2.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 3c563aa3..4fdbe5fd 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -2,17 +2,23 @@ + + + + + + + + + + - - - - - - - + + + + - + + + @@ -160,7 +169,7 @@ - + @@ -190,7 +199,7 @@ file://$PROJECT_DIR$/src/test/java/com/lz/FumeiaiTest.java - 190 + 191 @@ -215,7 +224,7 @@ file://$PROJECT_DIR$/src/main/java/com/lz/modules/app/service/impl/StaffServiceImpl.java - 83 + 93 @@ -228,11 +237,6 @@ 80 - - file://$PROJECT_DIR$/src/main/java/com/lz/modules/app/controller/StaffController.java - 191 - diff --git a/lz_management.iml b/lz_management.iml index 13d0f30d..df5c3c5c 100644 --- a/lz_management.iml +++ b/lz_management.iml @@ -124,7 +124,7 @@ - + diff --git a/pom.xml b/pom.xml index 5dd54fe0..5e906214 100644 --- a/pom.xml +++ b/pom.xml @@ -26,6 +26,7 @@ 2.5 1.10 1.10 + 1.3.2 1.4.0 0.7.0 0.0.9 @@ -146,6 +147,11 @@ shiro-spring ${shiro.version} + + org.apache.commons + commons-io + ${commons.io.version} + io.jsonwebtoken jjwt diff --git a/src/main/java/com/lz/common/utils/DateUtils.java b/src/main/java/com/lz/common/utils/DateUtils.java index 31e56627..b604ae28 100644 --- a/src/main/java/com/lz/common/utils/DateUtils.java +++ b/src/main/java/com/lz/common/utils/DateUtils.java @@ -27,6 +27,10 @@ public class DateUtils { public final static String DATE_PATTERN = "yyyy-MM-dd"; /** 时间格式(yyyy-MM-dd HH:mm:ss) */ public final static String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss"; + /** + * yyyyMMdd + */ + public static final String DEFAULT_PATTERN = "yyyyMMdd"; /** * 日期格式化 日期格式为:yyyy-MM-dd diff --git a/src/main/java/com/lz/common/utils/ExcelUtil.java b/src/main/java/com/lz/common/utils/ExcelUtil.java new file mode 100644 index 00000000..85677fd7 --- /dev/null +++ b/src/main/java/com/lz/common/utils/ExcelUtil.java @@ -0,0 +1,1118 @@ +package com.lz.common.utils; + +import com.google.common.collect.Lists; +import com.lz.common.utils.excel.*; +import com.lz.modules.app.enums.ExcelStaffHeardEnum; +import com.lz.modules.app.enums.GenderEnum; +import com.lz.modules.app.enums.MaritalStatusEnum; +import org.apache.commons.beanutils.BeanComparator; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.collections.ComparatorUtils; +import org.apache.commons.collections.comparators.ComparableComparator; +import org.apache.commons.collections.comparators.ComparatorChain; +import org.apache.poi.hssf.usermodel.*; +import org.apache.poi.openxml4j.exceptions.InvalidFormatException; +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.ss.util.CellReference; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.servlet.http.HttpServletResponse; +import java.io.*; +import java.lang.reflect.Field; +import java.text.DecimalFormat; +import java.text.MessageFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.*; + +/** + * @BelongsProject: ltapi + * @BelongsPackage: com.lz.lt.api.common.util + * @Author: gui.quanwang + * @CreateTime: 2018-11-27 16:38 + * @Description: excel工具类,支持文件的导入、导出 与 {@link ExcelCell}搭配使用 + * @注意:本内容仅限于杭州霖梓网络科技有限公司内部传阅,禁止外泄以及用于其他的商业目的 + */ +public class ExcelUtil { + + private static Logger logger = LoggerFactory.getLogger(ExcelUtil.class); + private static final String excel2003L = ".xls";//2003- 版本的excel + private static final String excel2007U = ".xlsx";//2007+ 版本的excel + + /** + * 用来验证excel与Vo中的类型是否一致
+ * Map<栏位类型,只能是哪些Cell类型> + */ + private static Map, CellType[]> validateMap = new HashMap<>(); + + static { + validateMap.put(String[].class, new CellType[]{CellType.STRING}); + validateMap.put(Double[].class, new CellType[]{CellType.NUMERIC}); + validateMap.put(String.class, new CellType[]{CellType.STRING}); + validateMap.put(Double.class, new CellType[]{CellType.NUMERIC}); + validateMap.put(Date.class, new CellType[]{CellType.NUMERIC, CellType.STRING}); + validateMap.put(Integer.class, new CellType[]{CellType.NUMERIC}); + validateMap.put(Float.class, new CellType[]{CellType.NUMERIC}); + validateMap.put(Long.class, new CellType[]{CellType.NUMERIC}); + validateMap.put(Boolean.class, new CellType[]{CellType.BOOLEAN}); + } + + /** + * 通过class获取对应的字段 + * + * @param clazz 类 + * @return map + */ + public static Map getHeaderMap(Class clazz) { + Map headerMap = new LinkedHashMap<>(); + Field[] fields = clazz.getDeclaredFields(); + for (Field field : fields) { + headerMap.put(field.getName(), field.getName()); + } + return headerMap; + } + + + /** + * 利用JAVA的反射机制,将放置在JAVA集合中并且符号一定条件的数据以EXCEL 的形式输出到指定IO设备上 + * 用于单个sheet + * + * @param 表示传参有泛型 + * @param headers 表格属性列名数组 + * @param dataSet 需要显示的数据集合,集合中一定要放置符合javabean风格的类的对象。此方法支持的 + * javabean属性的数据类型有基本数据类型及String,Date,String[],Double[] + * @param out 与输出设备关联的流对象,可以将EXCEL文档导出到本地文件或者网络中 + */ + public static void exportExcel(Map headers, Collection dataSet, OutputStream out) { + exportExcel(headers, dataSet, out, null); + } + + /** + * 利用JAVA的反射机制,将放置在JAVA集合中并且符号一定条件的数据以EXCEL 的形式输出到指定IO设备上
+ * 用于单个sheet + * + * @param + * @param headers 表格属性列名数组 + * @param dataSet 需要显示的数据集合,集合中一定要放置符合javabean风格的类的对象。此方法支持的 + * javabean属性的数据类型有基本数据类型及String,Date,String[],Double[] + * @param out 与输出设备关联的流对象,可以将EXCEL文档导出到本地文件或者网络中 + * @param pattern 如果有时间数据,设定输出格式。默认为"yyy-MM-dd" + */ + public static void exportExcel(Map headers, Collection dataSet, OutputStream out, + String pattern) { + // 声明一个工作薄 + HSSFWorkbook workbook = new HSSFWorkbook(); + // 生成一个表格 + HSSFSheet sheet = workbook.createSheet(); + + write2Sheet(sheet, headers, dataSet, pattern); + try { + workbook.write(out); + } catch (IOException e) { + logger.error(e.toString(), e); + } + } + + /** + * 导出excel文件 + * + * @param datalist 数据列表 + * @param out 数据流输出 + */ + public static void exportExcel(String[][] datalist, OutputStream out) { + try { + // 声明一个工作薄 + HSSFWorkbook workbook = new HSSFWorkbook(); + // 生成一个表格 + HSSFSheet sheet = workbook.createSheet(); + + //保存数据 + for (int i = 0; i < datalist.length; i++) { + String[] r = datalist[i]; + HSSFRow row = sheet.createRow(i); + for (int j = 0; j < r.length; j++) { + HSSFCell cell = row.createCell(j); + //cell max length 32767 + if (r[j].length() > 32767) { + r[j] = "--此字段过长(超过32767),已被截断--" + r[j]; + r[j] = r[j].substring(0, 32766); + } + cell.setCellValue(r[j]); + } + } + //自动列宽 + if (datalist.length > 0) { + int colcount = datalist[0].length; + for (int i = 0; i < colcount; i++) { + sheet.autoSizeColumn(i); + } + } + workbook.write(out); + } catch (IOException e) { + logger.error(e.toString(), e); + } + } + + /** + * 利用JAVA的反射机制,将放置在JAVA集合中并且符号一定条件的数据以EXCEL 的形式输出到指定IO设备上
+ * 用于多个sheet + * + * @param + * @param sheetList {@link ExcelSheet}的集合 + * @param out 与输出设备关联的流对象,可以将EXCEL文档导出到本地文件或者网络中 + */ + public static void exportExcel(List> sheetList, OutputStream out) { + exportExcel(sheetList, out, null); + } + + /** + * excel导出并下载 + * + * @param sheetList 数据列表 + * @param response 回调 + * @param fileName 下载的文件名称(不需传递 .xls 文件后缀) + * @param + * @throws IOException + */ + public static void exportExcel(List> sheetList + , String fileName, HttpServletResponse response) throws IOException, NullPointerException { + if (StringUtil.isEmpty(fileName)) { + throw new NullPointerException("文件名不能为空!!"); + } + //设置请求头,同时处理文件名不能出现中文的问题 + String headStr = "attachment; filename=" + new String(fileName.getBytes(), "iso-8859-1").concat(".xls"); + response.setContentType("APPLICATION/OCTET-STREAM"); + response.setHeader("Content-Disposition", headStr); + OutputStream outputStream = response.getOutputStream(); + exportExcel(sheetList, outputStream); + } + + /** + * 利用JAVA的反射机制,将放置在JAVA集合中并且符号一定条件的数据以EXCEL 的形式输出到指定IO设备上 + * 用于多个sheet + * + * @param + * @param sheets {@link ExcelSheet}的集合 + * @param out 与输出设备关联的流对象,可以将EXCEL文档导出到本地文件或者网络中 + * @param pattern 如果有时间数据,设定输出格式。默认为"yyy-MM-dd" + */ + public static void exportExcel(List> sheets, OutputStream out, String pattern) { + if (CollectionUtils.isEmpty(sheets)) { + return; + } + // 声明一个工作薄 + HSSFWorkbook workbook = new HSSFWorkbook(); + for (ExcelSheet sheet : sheets) { + // 生成一个表格 + HSSFSheet hssfSheet = workbook.createSheet(sheet.getSheetName()); + write2Sheet(hssfSheet, sheet.getHeaders(), sheet.getDataset(), pattern); + } + try { + workbook.write(out); + } catch (IOException e) { + logger.error(e.toString(), e); + } + } + + /** + * 根据文件路径解析 + * + * @param clazz 解析类 + * @param file excel文件 + * @param pattern 时间转换格式 + * @param logs 错误日志 + * @param arrayCount 数值数组 + * @param sheetName 工作表名称 + * @param + * @return + */ + public static Collection importExcel(Class clazz, File file + , String pattern, ExcelLogs logs, String sheetName, Integer... arrayCount) { + InputStream inputStream = null; + try { + inputStream = new FileInputStream(file); + return importExcel(clazz, inputStream, pattern, logs, sheetName, arrayCount); + } catch (FileNotFoundException e) { + e.printStackTrace(); + return null; + } + } + + + public static List> loadExcel(String filepath, int count) { + // 创建Excel工作簿文件的引用 + HSSFWorkbook wookbook = null; + try { + wookbook = new HSSFWorkbook(new FileInputStream(filepath));// 根据路劲创建引用 + } catch (FileNotFoundException e) { + logger.error("读取excel失败", e); + } catch (IOException e) { + logger.error("读取excel失败", e); + } + List> li = new ArrayList>(); + try { + // 在excel文档中,第一个工作表的缺省索引是0 + HSSFSheet sheet = wookbook.getSheetAt(count); + // 获取到excel文件中的有效行数 + int rows = sheet.getPhysicalNumberOfRows(); + + //获得总列数 + int cells = sheet.getRow(0).getPhysicalNumberOfCells(); + + // boolean boo = false; + for (int i = 1; i < rows; i++) { + HSSFRow row = sheet.getRow(i); + if (row != null) { + // 获取文件中的所有列 +// int cells = row.getPhysicalNumberOfCells();//此方法是获取有效列数,空值不计算在内 + Map map = new HashMap<>(); + // 遍历列 + for (int j = 0; j < cells; j++) { + HSSFCell cell = row.getCell(j); + if (cell != null) { + cell.setCellType(Cell.CELL_TYPE_STRING); + HSSFRow title = sheet.getRow(0); + HSSFCell titleCell = title.getCell(cell.getColumnIndex()); + map.put(titleCell.getStringCellValue().trim(), cell.getStringCellValue()); + } + } + li.add(map); + } + } + } catch (Exception e) { + logger.error("读取excel失败", e); + } + return li; + } + + /** + * 把Excel的数据封装成voList(单sheet) + * + * @param clazz vo的Class + * @param inputStream excel输入流 + * @param pattern 如果有时间数据,设定输入格式。默认为"yyyy-MM-dd" + * @param logs 错误log集合 + * @param sheetName 需要查找的工作表名称 + * @param arrayCount 如果vo中有数组类型,那就按照index顺序,把数组应该有几个值写上. + * @return voList + * @throws RuntimeException + */ + public static Collection importExcel(Class clazz, InputStream inputStream + , String pattern, ExcelLogs logs, String sheetName, Integer... arrayCount) { + Workbook workBook; + + //sheet(工作表) + Sheet sheet; + + try { + workBook = WorkbookFactory.create(inputStream); + } catch (Exception e) { + logger.error("load excel file error", e); + return null; + } + + if (StringUtil.isEmpty(pattern)) { + pattern = DateUtils.DEFAULT_PATTERN; + } + + List list = new ArrayList<>(); + + if (StringUtil.isEmpty(sheetName)) { + sheet = workBook.getSheetAt(0); + } else { + //获取首个sheet + sheet = workBook.getSheet(sheetName); + //如果获取失败 + if (sheet == null) { + throw new NullPointerException("can not get Sheet by sheetName"); + } + } + + Iterator rowIterator = sheet.rowIterator(); + + try { + List logList = new ArrayList<>(); + + Map titleMap = new LinkedHashMap<>(); + + while (rowIterator.hasNext()) { + Row row = rowIterator.next(); + //首行获取标题信息 + if (row.getRowNum() == 0) { + if (clazz == Map.class) { + // 解析map用的key,就是excel标题行 + Iterator cellIterator = row.cellIterator(); + Integer index = 0; + while (cellIterator.hasNext()) { + String value = cellIterator.next().getStringCellValue(); + if (titleMap.containsKey(value)) { + throw new RuntimeException(MessageFormat + .format("出现相同列名:{0},位于第{1}列及第{2}列" + , value, titleMap.get(value) + 1, index + 1)); + } + titleMap.put(value, index); + index++; + } + } + continue; + } + // 整行都空,就跳过 + boolean allRowIsNull = true; + Iterator cellIterator = row.cellIterator(); + while (cellIterator.hasNext()) { + Object cellValue = getCellValue(cellIterator.next()); + if (cellValue != null) { + allRowIsNull = false; + break; + } + } + if (allRowIsNull) { + logger.warn("Excel row " + row.getRowNum() + " all row value is null!"); + continue; + } + StringBuilder log = new StringBuilder(); + if (clazz == Map.class) { + Map map = new LinkedHashMap<>(); + for (String k : titleMap.keySet()) { + Integer index = titleMap.get(k); + Cell cell = row.getCell(index); + // 判空 + if (cell == null) { + map.put(k, null); + } else { + cell.setCellType(CellType.STRING); + String value = cell.getStringCellValue(); + map.put(k, value); + } + } + list.add((T) map); + } else { + //获取当前类的实例化(注意:需要有无参构造) + T instanceData = clazz.newInstance(); + + // 标识当前第几个数组了 + int arrayIndex = 0; + // 标识当前读到这一行的第几个cell了 + int cellIndex = 0; + + //获取类中所有字段集合 +// List fields = sortFieldByAnno(clazz); + List fields = sortFieldNoAnnoCheck(clazz); + + for (FieldForSortting ffs : fields) { + Field field = ffs.getField(); + field.setAccessible(true); + if (field.getType().isArray()) { + + //获取该field需要存储几个值 + Integer count = arrayCount[arrayIndex]; + + Object[] valueArray; + if (field.getType().equals(String[].class)) { + valueArray = new String[count]; + } else { + // 目前只支持String[]和Double[] + valueArray = new Double[count]; + } + + //存储field对应的值 + for (int i = 0; i < count; i++) { + Cell cell = row.getCell(cellIndex); + String errMsg = validateCell(cell, field, cellIndex, false); + if (StringUtil.isBlank(errMsg)) { + valueArray[i] = getCellValue(cell); + } else { + log.append(errMsg); + log.append(";"); + if (logs != null) { + logs.setHasError(true); + } + + } + cellIndex++; + } + field.set(instanceData, valueArray); + arrayIndex++; + } else { + //获取cell + Cell cell = row.getCell(cellIndex); + //校验cell + String errMsg = validateCell(cell, field, cellIndex, false); + + if (StringUtil.isBlank(errMsg)) { + Object value = null; + // 处理特殊情况,Excel中的String,转换成Bean的Date + if (field.getType().equals(Date.class) + && cell.getCellTypeEnum() == CellType.STRING) { + Object strDate = getCellValue(cell); + try { + value = new SimpleDateFormat(pattern).parse(strDate.toString()); + } catch (ParseException e) { + try { + value = new SimpleDateFormat(DateUtils.DEFAULT_PATTERN).parse(strDate.toString()); + } catch (Exception e1) { + errMsg = MessageFormat.format("the cell [{0}]" + + " can not be converted to a date " + , CellReference.convertNumToColString(cell.getColumnIndex())); + } + } + } else { + value = getCellValue(cell); + + //处理特殊情况,excel的value为String,且bean中为其他,且defaultValue不为空,那就=defaultValue + ExcelCell annoCell = field.getAnnotation(ExcelCell.class); + if (value instanceof String && !field.getType().equals(String.class) + && (annoCell != null && StringUtil.isNotBlank(annoCell.defaultValue()))) { + value = annoCell.defaultValue(); + } + } + field.set(instanceData, value); + } + if (StringUtil.isNotBlank(errMsg)) { + log.append(errMsg); + log.append(";"); + if (logs != null) { + logs.setHasError(true); + } + + } + cellIndex++; + } + } + list.add(instanceData); + logList.add(new ExcelLog(instanceData, log.toString(), row.getRowNum() + 1)); + } + } + if (logs != null) { + logs.setLogList(logList); + } + } catch (InstantiationException e) { + throw new RuntimeException(MessageFormat.format("can not instance class:{0}", + clazz.getSimpleName()), e); + } catch (IllegalAccessException e) { + throw new RuntimeException(MessageFormat.format("can not instance class:{0}", + clazz.getSimpleName()), e); + } + return list; + } + + /** + * @param filePath + * @return + * @描述:是否是2003的excel,返回true是2003 + */ + public static boolean isExcel2003(String filePath) { + return filePath.matches("^.+\\.(?i)(xls)$"); + } + + /** + * @param filePath + * @return + * @描述:是否是2007的excel,返回true是2007 + */ + public static boolean isExcel2007(String filePath) { + return filePath.matches("^.+\\.(?i)(xlsx)$"); + } + + /** + * 验证是否是EXCEL文件 + * + * @param filePath + * @return + */ + public static boolean validateExcel(String filePath) { + if (filePath == null || !(isExcel2003(filePath) || isExcel2007(filePath))) { + return false; + } + return true; + } + + /** + * 将数据写入当前sheet中 + * + * @param sheet 页签 + * @param headers 表头 + * @param dataSet 数据集合 + * @param pattern 日期转换格式(如果为空,则为yyyyMMdd) + */ + private static void write2Sheet(HSSFSheet sheet, Map headers, Collection dataSet, + String pattern) { + //时间格式默认"yyyy-MM-dd" + if (StringUtil.isEmpty(pattern)) { + pattern = DateUtils.DATE_PATTERN; + } + // 产生表格标题行 + HSSFRow row = sheet.createRow(0); + // 标题行转中文 + Set keys = headers.keySet(); + Iterator iterator = keys.iterator(); + //存放临时键变量 + String key = ""; + //标题列数 + int c = 0; + + //设置标题头 + while (iterator.hasNext()) { + key = iterator.next(); + if (headers.containsKey(key)) { + HSSFCell cell = row.createCell(c); + HSSFRichTextString text = new HSSFRichTextString(headers.get(key)); + cell.setCellValue(text); + c++; + } + } + + // 遍历集合数据,产生数据行 + Iterator it = dataSet.iterator(); + int index = 0; + while (it.hasNext()) { + index++; + row = sheet.createRow(index); + //获取数据源一条数据 + T data = it.next(); + try { + //若 + if (data instanceof Map) { + @SuppressWarnings("unchecked") + Map map = (Map) data; + int cellNum = 0; + //遍历列名 + Iterator it2 = keys.iterator(); + while (it2.hasNext()) { + key = it2.next(); + + //todo:这样并不会将当前项空出,而是所有值向前移动一位 + if (!headers.containsKey(key)) { + logger.error("Map 中 不存在 key [" + key + "]"); + continue; + } + Object value = map.get(key); + HSSFCell cell = row.createCell(cellNum); + + cellNum = setCellValue(cell, value, pattern, cellNum, null, row); + + cellNum++; + } + } else { + + //获取对应字段 +// List fields = sortFieldByAnno(data.getClass()); + List fields = sortFieldNoAnnoCheck(data.getClass()); + + int cellNum = 0; + for (FieldForSortting field1 : fields) { + HSSFCell cell = row.createCell(cellNum); + //获取当前字段属性 + Field field = field1.getField(); + field.setAccessible(true); + Object value = field.get(data); + + cellNum = setCellValue(cell, value, pattern, cellNum, field, row); + + cellNum++; + } + } + } catch (Exception e) { + logger.error(e.toString(), e); + } + } + // 设定自动宽度 + for (int i = 0; i < headers.size(); i++) { + sheet.autoSizeColumn(i); + } + } + + /** + * 获取cell类型的文字描述 + * + * @param cellType + * @return + */ + private static String getCellTypeByInt(CellType cellType) { + if (cellType == CellType.BLANK) { + return "Null type"; + } else if (cellType == CellType.BOOLEAN) { + return "Boolean type"; + } else if (cellType == CellType.ERROR) { + return "Error type"; + } else if (cellType == CellType.FORMULA) { + return "Formula type"; + } else if (cellType == CellType.NUMERIC) { + return "Numeric type"; + } else if (cellType == CellType.STRING) { + return "String type"; + } else { + return "Unknown type"; + } + } + + /** + * 功能描述: 获取单元格值 + * + * @param cell 单元格 + * @return String + */ + public static String getCellValueNew(Cell cell) { + String value = ""; + if (cell != null) { + switch (cell.getCellTypeEnum()) { + case STRING: + value = cell.getRichStringCellValue().getString(); + break; + case NUMERIC: + //System.out.println(" "+cell.getCellStyle().getDataFormatString()+" "); + if ("yyyy/m/d;@".equals(cell.getCellStyle().getDataFormatString()) || "yyyy\\-mm\\-dd".equals(cell.getCellStyle().getDataFormatString()) || "yyyymmdd".equals(cell.getCellStyle().getDataFormatString())) { + value = DateUtils.format(cell.getDateCellValue()); + } else { + DecimalFormat df = new DecimalFormat("#"); + value = df.format(cell.getNumericCellValue()); + } + break; + case BOOLEAN: + value = String.valueOf(cell.getBooleanCellValue()); + break; + default: + break; + } + } + return value.trim(); + } + /** + * 获取单元格值 + * + * @param cell + * @return + */ + private static Object getCellValue(Cell cell) { + if (cell == null + || (cell.getCellTypeEnum() == CellType.STRING && StringUtil.isBlank(cell.getStringCellValue()))) { + return null; + } + CellType cellType = cell.getCellTypeEnum(); + if (cellType == CellType.BLANK) { + return null; + } else if (cellType == CellType.BOOLEAN) { + return cell.getBooleanCellValue(); + } else if (cellType == CellType.ERROR) { + return cell.getErrorCellValue(); + } else if (cellType == CellType.FORMULA) { + try { + if (HSSFDateUtil.isCellDateFormatted(cell)) { + return cell.getDateCellValue(); + } else { + return cell.getNumericCellValue(); + } + } catch (IllegalStateException e) { + return cell.getRichStringCellValue(); + } + } else if (cellType == CellType.NUMERIC) { + if (org.apache.poi.ss.usermodel.DateUtil.isCellDateFormatted(cell)) { + return cell.getDateCellValue(); + } else { + return cell.getNumericCellValue(); + } + } else if (cellType == CellType.STRING) { + return cell.getStringCellValue(); + } else { + return null; + } + } + + /** + * 将cell赋值后保存到excel当前行中 + * + * @param cell 当前选中项 + * @param value 插入值 + * @param pattern 时间转换格式 + * @param cellNum 当前选中项所在的index(即列数) + * @param field 对应的字段对象 + * @param row 当前选中项所在的行 + * @return 返回更新后的最新列数· + */ + private static int setCellValue(HSSFCell cell, Object value, String pattern + , int cellNum, Field field, HSSFRow row) { + String textValue = null; + if (value instanceof Integer) { + int intValue = (Integer) value; + cell.setCellValue(intValue); + } else if (value instanceof Float) { + float fValue = (Float) value; + cell.setCellValue(fValue); + } else if (value instanceof Double) { + double dValue = (Double) value; + cell.setCellValue(dValue); + } else if (value instanceof Long) { + long longValue = (Long) value; + cell.setCellValue(longValue); + } else if (value instanceof Boolean) { + boolean bValue = (Boolean) value; + cell.setCellValue(bValue); + } else if (value instanceof Date) { + Date date = (Date) value; + SimpleDateFormat sdf = new SimpleDateFormat(pattern); + textValue = sdf.format(date); + } else if (value instanceof String[]) { + String[] strArr = (String[]) value; + for (int j = 0; j < strArr.length; j++) { + String str = strArr[j]; + cell.setCellValue(str); + if (j != strArr.length - 1) { + cellNum++; + cell = row.createCell(cellNum); + } + } + } else if (value instanceof Double[]) { + Double[] douArr = (Double[]) value; + for (int j = 0; j < douArr.length; j++) { + Double val = douArr[j]; + // 值不为空则set Value + if (val != null) { + cell.setCellValue(val); + } + + if (j != douArr.length - 1) { + cellNum++; + cell = row.createCell(cellNum); + } + } + } else { + // 其它数据类型都当作字符串简单处理 + String empty = StringUtil.EMPTY; + if (field != null) { + ExcelCell anno = field.getAnnotation(ExcelCell.class); + if (anno != null) { + empty = anno.defaultValue(); + } + } + textValue = value == null ? empty : value.toString(); + } + if (textValue != null) { + HSSFRichTextString richString = new HSSFRichTextString(textValue); + cell.setCellValue(richString); + } + return cellNum; + } + + /** + * 校验cell类型的正确性 + * + * @param cell cell单元格 + * @param field 栏位 + * @param cellNum 栏位索引,用于errMsg + * @param checkAnno 是否根据注解{@link ExcelCell}校验 + * @return + */ + private static String validateCell(Cell cell, Field field, int cellNum, boolean checkAnno) { + + //获取当前列名(例如:cellNum=3时,返回"D") + String columnName = CellReference.convertNumToColString(cellNum); + + //返回的数据 + String result = null; + + ExcelCell annoCell = null; + + //查看字段是否在支持范围内 + CellType[] cellTypeArr = validateMap.get(field.getType()); + if (cellTypeArr == null) { + result = MessageFormat.format("Unsupported type [{0}]", field.getType().getSimpleName()); + return result; + } + + //判断是否校验注解 + if (checkAnno) { + annoCell = field.getAnnotation(ExcelCell.class); + } + + //若cell为null或(cell数据类别是String且cell的值为空) + if (cell == null || (cell.getCellTypeEnum() == CellType.STRING + && StringUtil.isBlank(cell.getStringCellValue()))) { + if (annoCell != null && !annoCell.valid().allowNull()) { + result = MessageFormat.format("the cell [{0}] can not null", columnName); + } + //若cell的类别是空 + } else if (cell.getCellTypeEnum() == CellType.BLANK && (annoCell != null && annoCell.valid().allowNull())) { + return result; + } else { + List cellTypes = Arrays.asList(cellTypeArr); + + //如果类型不在指定范围内,且无默认值 + if (!(cellTypes.contains(cell.getCellTypeEnum())) + || (annoCell != null && StringUtil.isNotBlank(annoCell.defaultValue())) + && cell.getCellTypeEnum() == CellType.STRING) { + StringBuilder strType = new StringBuilder(); + for (int i = 0; i < cellTypes.size(); i++) { + CellType cellType = cellTypes.get(i); + strType.append(getCellTypeByInt(cellType)); + if (i != cellTypes.size() - 1) { + strType.append(","); + } + } + result = MessageFormat.format("the cell [{0}] type must [{1}]", columnName, strType.toString()); + } else { + // 类型符合验证,但值不在要求范围内的 + //若cell类型为String + if (annoCell != null && annoCell.valid().in().length != 0 && cell.getCellTypeEnum() == CellType.STRING) { + String[] in = annoCell.valid().in(); + String cellValue = cell.getStringCellValue(); + boolean isIn = false; + for (String str : in) { + if (str.equals(cellValue)) { + isIn = true; + } + } + if (!isIn) { + result = MessageFormat.format("the cell [{0}] value must in {1}", columnName, in); + } + } + //cell类型是数字型 + if (cell.getCellTypeEnum() == CellType.NUMERIC) { + double cellValue = cell.getNumericCellValue(); + // 小于 + if (annoCell != null && !Double.isNaN(annoCell.valid().lt())) { + if (!(cellValue < annoCell.valid().lt())) { + result = MessageFormat.format("the cell [{0}] value must less than [{1}]" + , columnName, annoCell.valid().lt()); + } + } + // 大于 + if (annoCell != null && !Double.isNaN(annoCell.valid().gt())) { + if (!(cellValue > annoCell.valid().gt())) { + result = MessageFormat.format("the cell [{0}] value must greater than [{1}]" + , columnName, annoCell.valid().gt()); + } + } + // 小于等于 + if (annoCell != null && !Double.isNaN(annoCell.valid().le())) { + if (!(cellValue <= annoCell.valid().le())) { + result = MessageFormat.format("the cell [{0}] value must less than or equal [{1}]" + , columnName, annoCell.valid().le()); + } + } + // 大于等于 + if (annoCell != null && !Double.isNaN(annoCell.valid().ge())) { + if (!(cellValue >= annoCell.valid().ge())) { + result = MessageFormat.format("the cell [{0}] value must greater than or equal [{1}]" + , columnName, annoCell.valid().ge()); + } + } + } + } + } + return result; + } + + /** + * 根据annotation的seq排序后的栏位 + * + * @param clazz 数据接收的封装类 + * @return + */ + private static List sortFieldByAnno(Class clazz) { + //获取类内所有字段 + Field[] fieldsArr = clazz.getDeclaredFields(); + //字段集合 + List fields = new ArrayList<>(); + + List annoNullFields = new ArrayList<>(); + for (Field field : fieldsArr) { + ExcelCell ec = field.getAnnotation(ExcelCell.class); + if (ec == null) { + // 没有ExcelCell Annotation 视为不汇入 + continue; + } + int index = ec.index(); + fields.add(new FieldForSortting(field, index)); + } + fields.addAll(annoNullFields); + sortByProperties(fields, true, false, "index"); + return fields; + } + + /** + * 直接排序(不做注解校验) + * + * @param clazz 数据接收的封装类 + * @return + */ + private static List sortFieldNoAnnoCheck(Class clazz) { + //获取类内所有字段(不获取父类字段) + Field[] fieldsArr = clazz.getDeclaredFields(); + //字段集合 + List fields = new ArrayList<>(); + + int index = 0; + for (Field field : fieldsArr) { + fields.add(new FieldForSortting(field, index++)); + } + sortByProperties(fields, true, false, "index"); + return fields; + } + + /** + * 根据配置排序 + * + * @param list 数据集合 + * @param isNullHigh 是否将null放最前 + * @param isReversed 是否排序(倒序) + * @param props 排序字段设置(以哪些字段排序(首个优先级最高)) + */ + private static void sortByProperties(List list, boolean isNullHigh, + boolean isReversed, String... props) { + if (CollectionUtils.isNotEmpty(list)) { + Comparator typeComp = ComparableComparator.getInstance(); + if (isNullHigh) { + typeComp = ComparatorUtils.nullHighComparator(typeComp); + } else { + typeComp = ComparatorUtils.nullLowComparator(typeComp); + } + if (isReversed) { + typeComp = ComparatorUtils.reversedComparator(typeComp); + } + + List sortCols = new ArrayList(); + + if (props != null) { + for (String prop : props) { + sortCols.add(new BeanComparator(prop, typeComp)); + } + } + if (sortCols.size() > 0) { + //排序链 + Comparator sortChain = new ComparatorChain(sortCols); + //根据配置项排序 + Collections.sort(list, sortChain); + } + } + } + + /** + * 获取excel中的数据 + */ + public static List> readExcelData(InputStream in, String filename) throws Exception { + List> list; + + //创建Excel工作薄 + Workbook work = getWorkbook(in, filename); + if (null == work) { + throw new Exception("创建Excel工作薄为空!"); + } + Sheet sheet = null; + Row row = null; + Cell cell = null; + + list = new ArrayList>(); + //遍历Excel中所有的sheet + for (int i = 0; i < work.getNumberOfSheets(); i++) { + sheet = work.getSheetAt(i); + if (sheet == null) { + continue; + } + + //遍历当前sheet中的所有行 + for (int j = sheet.getFirstRowNum(); j <= sheet.getLastRowNum(); j++) { + row = sheet.getRow(j); + if (row == null || row.getFirstCellNum() == j) { + continue; + } + + //遍历所有的列 + List li = new ArrayList(); + for (int y = row.getFirstCellNum(); y < row.getLastCellNum(); y++) { + cell = row.getCell(y); + //通过getCellValue方法获取当前行每一列中的数据 + li.add(getCellValue(cell)); + } + //将每一行的数据添加到list + list.add(li); + } + } + in.close(); + return list; + } + + /** + * 根据文件后缀,自适应上传文件的版本 + */ + private static Workbook getWorkbook(InputStream inStr, String filename) throws Exception { + Workbook workbook; + String fileType = filename.substring(filename.lastIndexOf(".")); + if (excel2003L.equals(fileType)) { + workbook = new HSSFWorkbook(inStr);//2003- + } else if (excel2007U.equals(fileType)) { + workbook = new XSSFWorkbook(inStr);//2007+ + } else { + throw new Exception("解析的文件格式有误"); + } + return workbook; + } + + public static void getExcelData(InputStream inputStream, List> sheet12List, List> sheet3List, List> sheet4List) { + // 获得工作簿 + Workbook workbook = null; + try { + workbook = WorkbookFactory.create(inputStream); + } catch (IOException e) { + e.printStackTrace(); + } catch (InvalidFormatException e) { + e.printStackTrace(); + } + // 获得工作表个数 + int sheetCount = workbook.getNumberOfSheets(); + + // 遍历工作表 + for (int i = 0; i < sheetCount; i++) { + Sheet sheet = workbook.getSheetAt(i); + // 获得行数 + int rows = sheet.getLastRowNum() + 1; + // 获得列数,先获得一行,在得到改行列数 + Row tmp = sheet.getRow(0); + if (tmp == null) { + continue; + } + int cols = tmp.getPhysicalNumberOfCells(); + List headList = Lists.newArrayList(); + // 读取数据 + for (int row = 0; row < rows; row++) { + Row r = sheet.getRow(row); + Map dataMap = new HashMap(); + for (int col = 0; col < cols; col++) { + String cellValue = getCellValueNew(r.getCell(col)); + //System.out.print(" " + cellValue); + if (row == 0) { + headList.add(cellValue); + } else { + if (StringUtil.equals(GenderEnum.female.getName(), cellValue) || StringUtil.equals(GenderEnum.male.getName(), cellValue)) { + cellValue = GenderEnum.findCodeByName(cellValue).toString(); + } else if (StringUtil.equals(MaritalStatusEnum.unmarried.getName(), cellValue) || StringUtil.equals(MaritalStatusEnum.married.getName(), cellValue)) { + cellValue = MaritalStatusEnum.findCodeByName(cellValue).toString(); + } + dataMap.put(ExcelStaffHeardEnum.findFieldByName(headList.get(col)), cellValue); + } + } + + if (dataMap.size() > 0) { + if (i == 1) { + dataMap.put("staffStatus", "1"); + } + switch (i) { + case 0: + case 1: + sheet12List.add(dataMap); + break; + case 2: + sheet3List.add(dataMap); + break; + case 3: + sheet4List.add(dataMap); + break; + default: + break; + } + } + } + } + } +} diff --git a/src/main/java/com/lz/common/utils/excel/ExcelCell.java b/src/main/java/com/lz/common/utils/excel/ExcelCell.java new file mode 100644 index 00000000..e95b7779 --- /dev/null +++ b/src/main/java/com/lz/common/utils/excel/ExcelCell.java @@ -0,0 +1,90 @@ +package com.lz.common.utils.excel; + + +import com.lz.common.utils.StringUtil; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * @BelongsProject: ltapi + * @BelongsPackage: com.lz.lt.api.common.util.excel + * @Author: gui.quanwang + * @CreateTime: 2018-11-27 16:53 + * @Description: 数值型的栏位只能使用Double(自定义注解) + * @注意:本内容仅限于杭州霖梓网络科技有限公司内部传阅,禁止外泄以及用于其他的商业目的 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface ExcelCell { + + /** + * 顺序 default 100 + * + * @return index + */ + int index(); + + /** + * 当值为null时要显示的值 default StringUtils.EMPTY + * + * @return defaultValue + */ + String defaultValue() default StringUtil.EMPTY; + + /** + * 用于验证 + * + * @return valid + */ + Valid valid() default @Valid(); + + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.FIELD) + @interface Valid { + /** + * 必须与in中String相符,目前仅支持String类型 + * + * @return e.g. {"key","value"} + */ + String[] in() default {}; + + /** + * 是否允许为空,用于验证数据 default true + * + * @return allowNull + */ + boolean allowNull() default true; + + /** + * Apply a "greater than" constraint to the named property + * + * @return gt + */ + double gt() default Double.NaN; + + /** + * Apply a "less than" constraint to the named property + * + * @return lt + */ + double lt() default Double.NaN; + + /** + * Apply a "greater than or equal" constraint to the named property + * + * @return ge + */ + double ge() default Double.NaN; + + /** + * Apply a "less than or equal" constraint to the named property + * + * @return le + */ + double le() default Double.NaN; + } + +} diff --git a/src/main/java/com/lz/common/utils/excel/ExcelLog.java b/src/main/java/com/lz/common/utils/excel/ExcelLog.java new file mode 100644 index 00000000..0f4664e5 --- /dev/null +++ b/src/main/java/com/lz/common/utils/excel/ExcelLog.java @@ -0,0 +1,100 @@ +package com.lz.common.utils.excel; + +/** + * @BelongsProject: ltapi + * @BelongsPackage: com.lz.lt.api.common.util.excel + * @Author: gui.quanwang + * @CreateTime: 2018-11-27 16:43 + * @Description: excel输出 + * @注意:本内容仅限于杭州霖梓网络科技有限公司内部传阅,禁止外泄以及用于其他的商业目的 + */ +public class ExcelLog { + + /** + * 行数 + */ + private Integer rowNum; + + /** + * 数据 + */ + private Object object; + + /** + * 记录 + */ + private String log; + + /** + * @param object + * @param log + */ + public ExcelLog(Object object, String log) { + super(); + this.object = object; + this.log = log; + } + + /** + * @param rowNum + * @param object + * @param log + */ + public ExcelLog(Object object, String log, Integer rowNum) { + super(); + this.rowNum = rowNum; + this.object = object; + this.log = log; + } + + /** + * @return the rowNum + */ + public Integer getRowNum() { + return rowNum; + } + + /** + * @param rowNum the rowNum to set + */ + public void setRowNum(Integer rowNum) { + this.rowNum = rowNum; + } + + /** + * @return the object + */ + public Object getObject() { + return object; + } + + /** + * @param object the object to set + */ + public void setObject(Object object) { + this.object = object; + } + + /** + * @return the log + */ + public String getLog() { + return log; + } + + /** + * @param log the log to set + */ + public void setLog(String log) { + this.log = log; + } + + @Override + public String toString() { + return "ExcelLog{" + + "rowNum=" + rowNum + + ", object=" + object + + ", log='" + log + '\'' + + '}'; + } +} diff --git a/src/main/java/com/lz/common/utils/excel/ExcelLogs.java b/src/main/java/com/lz/common/utils/excel/ExcelLogs.java new file mode 100644 index 00000000..08121687 --- /dev/null +++ b/src/main/java/com/lz/common/utils/excel/ExcelLogs.java @@ -0,0 +1,82 @@ +package com.lz.common.utils.excel; + +import com.lz.common.utils.StringUtil; + +import java.util.ArrayList; +import java.util.List; + +/** + * @BelongsProject: ltapi + * @BelongsPackage: com.lz.lt.api.common.util.excel + * @Author: gui.quanwang + * @CreateTime: 2018-11-27 16:45 + * @Description: excel错误日志记录 + * @注意:本内容仅限于杭州霖梓网络科技有限公司内部传阅,禁止外泄以及用于其他的商业目的 + */ +public class ExcelLogs { + + /** + * 是否出错 + */ + private Boolean hasError; + + /** + * excel集合 + */ + private List logList; + + public ExcelLogs() { + super(); + hasError = false; + } + + /** + * @return the hasError + */ + public Boolean getHasError() { + return hasError; + } + + /** + * @param hasError the hasError to set + */ + public void setHasError(Boolean hasError) { + this.hasError = hasError; + } + + /** + * @return the logList + */ + public List getLogList() { + return logList; + } + + /** + * @param logList the logList to set + */ + public void setLogList(List logList) { + this.logList = logList; + } + + /** + * 获取错误excel集合 + * @return + */ + public List getErrorLogList() { + List errList = new ArrayList<>(); + for (ExcelLog log : this.logList) { + if (log != null && StringUtil.isNotBlank(log.getLog())) { + errList.add(log); + } + } + return errList; + } + + @Override + public String toString() { + return "ExcelLogs{" + + "hasError=" + hasError + + ", logList=" + logList + + '}'; + } +} diff --git a/src/main/java/com/lz/common/utils/excel/ExcelSheet.java b/src/main/java/com/lz/common/utils/excel/ExcelSheet.java new file mode 100644 index 00000000..ba0f4a29 --- /dev/null +++ b/src/main/java/com/lz/common/utils/excel/ExcelSheet.java @@ -0,0 +1,87 @@ +package com.lz.common.utils.excel; + +import java.util.Collection; +import java.util.Map; + +/** + * @BelongsProject: ltapi + * @BelongsPackage: com.lz.lt.api.common.util.excel + * @Author: gui.quanwang + * @CreateTime: 2018-11-27 16:49 + * @Description: 用于汇出多个sheet的Vo + * @注意:本内容仅限于杭州霖梓网络科技有限公司内部传阅,禁止外泄以及用于其他的商业目的 + */ +public class ExcelSheet { + + /** + * sheet名 + */ + private String sheetName; + + /** + * 头部集合(字段属性) + */ + private Map headers; + + /** + * 数据源 + */ + private Collection dataset; + + /** + * @return the sheetName + */ + public String getSheetName() { + return sheetName; + } + + /** + * Excel页签名称 + * + * @param sheetName the sheetName to set + */ + public void setSheetName(String sheetName) { + this.sheetName = sheetName; + } + + /** + * Excel表头 + * + * @return the headers + */ + public Map getHeaders() { + return headers; + } + + /** + * @param headers the headers to set + */ + public void setHeaders(Map headers) { + this.headers = headers; + } + + /** + * Excel数据集合 + * + * @return the dataset + */ + public Collection getDataset() { + return dataset; + } + + /** + * @param dataset the dataset to set + */ + public void setDataset(Collection dataset) { + this.dataset = dataset; + } + + @Override + public String toString() { + return "ExcelSheet{" + + "sheetName='" + sheetName + '\'' + + ", headers=" + headers + + ", dataset=" + dataset + + '}'; + } +} diff --git a/src/main/java/com/lz/common/utils/excel/FieldForSortting.java b/src/main/java/com/lz/common/utils/excel/FieldForSortting.java new file mode 100644 index 00000000..712cf1ce --- /dev/null +++ b/src/main/java/com/lz/common/utils/excel/FieldForSortting.java @@ -0,0 +1,80 @@ +package com.lz.common.utils.excel; + +import java.lang.reflect.Field; + +/** + * @BelongsProject: ltapi + * @BelongsPackage: com.lz.lt.api.common.util.excel + * @Author: gui.quanwang + * @CreateTime: 2018-11-27 16:52 + * @Description: 泛型类反射后的字段封装类 + * @注意:本内容仅限于杭州霖梓网络科技有限公司内部传阅,禁止外泄以及用于其他的商业目的 + */ +public class FieldForSortting { + + /** + * 泛型反射 + */ + private Field field; + + /** + * 索引 + */ + private int index; + + /** + * @param field + */ + public FieldForSortting(Field field) { + super(); + this.field = field; + } + + /** + * @param field + * @param index + */ + public FieldForSortting(Field field, int index) { + super(); + this.field = field; + this.index = index; + } + + /** + * @return the field + */ + public Field getField() { + return field; + } + + /** + * @param field + * the field to set + */ + public void setField(Field field) { + this.field = field; + } + + /** + * @return the index + */ + public int getIndex() { + return index; + } + + /** + * @param index + * the index to set + */ + public void setIndex(int index) { + this.index = index; + } + + @Override + public String toString() { + return "FieldForSortting{" + + "field=" + field + + ", index=" + index + + '}'; + } +} diff --git a/src/main/java/com/lz/modules/app/controller/StaffController.java b/src/main/java/com/lz/modules/app/controller/StaffController.java index b85648e3..2e43b118 100644 --- a/src/main/java/com/lz/modules/app/controller/StaffController.java +++ b/src/main/java/com/lz/modules/app/controller/StaffController.java @@ -1,29 +1,28 @@ package com.lz.modules.app.controller; +import com.alibaba.fastjson.JSON; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.google.common.collect.Lists; +import com.lz.common.utils.*; +import com.lz.modules.app.Dto.*; +import com.lz.modules.app.entity.DepartmentsEntity; +import com.lz.modules.app.entity.StaffEntity; +import com.lz.modules.app.service.*; +import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.ss.usermodel.WorkbookFactory; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; -import com.alibaba.fastjson.JSON; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.lz.common.utils.DateUtils; -import com.lz.modules.app.Dto.*; -import com.lz.modules.app.entity.DepartmentsEntity; -import com.lz.modules.app.service.*; -import com.lz.modules.sys.entity.SysCaptchaEntity; -import org.apache.shiro.authz.annotation.RequiresPermissions; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -import com.lz.modules.app.entity.StaffEntity; -import com.lz.common.utils.PageUtils; -import com.lz.common.utils.R; - /** * 员工基本信息表 * @@ -188,12 +187,59 @@ public class StaffController { educationDistribution.setRows(educationRows); data.put("educationDistribution", educationDistribution); - R ret = R.ok(); ret.put("data", data); return ret; } + + /** + * 上传Excel,读取Excel中内容 + * + * @param file 文件 + * @return + * @throws IOException + */ + @RequestMapping(value = "/batchImport") +// @RequiresPermissions("user:ltuserrewardlog:upload") + public R batchImport(@RequestParam(value = "file") MultipartFile file) { + + InputStream inputStream; + try { + //判断文件是否为空 + if (file == null) { + return R.error("文件不能为空"); + } + + //获取文件名 + String name = file.getOriginalFilename(); + + //进一步判断文件是否为空(即判断其大小是否为0或其名称是否为null)验证文件名是否合格 + long size = file.getSize(); + if (StringUtil.isBlank(name) || size == 0 || !ExcelUtil.validateExcel(name)) { + return R.error("文件格式不正确!请使用.xls或.xlsx后缀文档。"); + } + + if (name.lastIndexOf(".csv") != -1 || name.lastIndexOf(".CSV") != -1) { + inputStream = new ByteArrayInputStream(file.getBytes()); + } else { + inputStream = file.getInputStream(); + } + List> sheet12List = Lists.newArrayList(); + List> sheet3List = Lists.newArrayList(); + List> sheet4List = Lists.newArrayList(); + + ExcelUtil.getExcelData(inputStream, sheet12List, sheet3List, sheet4List); + + staffService.enterDatabase(sheet12List, sheet3List, sheet4List); + + return R.ok(); + } catch (IOException e) { + return R.error(); + } + } + + /** * 保存 */ diff --git a/src/main/java/com/lz/modules/app/service/StaffService.java b/src/main/java/com/lz/modules/app/service/StaffService.java index 5f03d655..cf3a9a90 100644 --- a/src/main/java/com/lz/modules/app/service/StaffService.java +++ b/src/main/java/com/lz/modules/app/service/StaffService.java @@ -47,5 +47,6 @@ public interface StaffService extends IService { List getEducationData(String departmentId, String beginDate, String endDate); + void enterDatabase(List> sheet12List, List> sheet3List, List> sheet4List); } diff --git a/src/main/java/com/lz/modules/app/service/impl/StaffServiceImpl.java b/src/main/java/com/lz/modules/app/service/impl/StaffServiceImpl.java index eabb0cd2..a6a123f2 100644 --- a/src/main/java/com/lz/modules/app/service/impl/StaffServiceImpl.java +++ b/src/main/java/com/lz/modules/app/service/impl/StaffServiceImpl.java @@ -1,7 +1,9 @@ package com.lz.modules.app.service.impl; import cn.hutool.core.util.NumberUtil; +import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.google.common.collect.Lists; @@ -12,8 +14,8 @@ import com.lz.modules.app.Dto.StaffBaseInfoDto; import com.lz.modules.app.Dto.StaffDto; import com.lz.modules.app.Dto.StaffStatisticalDto; import com.lz.modules.app.dao.StaffDao; -import com.lz.modules.app.entity.StaffEntity; -import com.lz.modules.app.service.StaffService; +import com.lz.modules.app.entity.*; +import com.lz.modules.app.service.*; import com.lz.modules.job.model.responseBo.DepartmentStaffBo; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; @@ -31,6 +33,14 @@ public class StaffServiceImpl extends ServiceImpl impleme @Resource StaffDao staffDao; + @Resource + StaffOccupationService staffOccupationService; + @Resource + StaffEducationService staffEducationService; + @Resource + StaffProjectExperienceService staffProjectExperienceService; + @Resource + StaffWorkTransferRecordService staffWorkTransferRecordService; @Override public PageUtils queryPage(Map params) { @@ -161,6 +171,75 @@ public class StaffServiceImpl extends ServiceImpl impleme return graphicsStatisticals; } + @Override + public void enterDatabase(List> sheet12List, List> sheet3List, List> sheet4List) { + for (Map map : sheet12List) { + StaffEntity staffEntity = JSON.parseObject(JSON.toJSONString(map), StaffEntity.class); + StaffOccupationEntity occupationEntity = JSON.parseObject(JSON.toJSONString(map), StaffOccupationEntity.class); + StaffEducationEntity educationEntity = JSON.parseObject(JSON.toJSONString(map), StaffEducationEntity.class); + StaffEntity Staff = this.getByName(staffEntity.getName()); + if (Staff == null) { + this.save(staffEntity); + } else { + staffEntity.setId(Staff.getId()); + this.updateById(staffEntity); + } + StaffOccupationEntity occupation = staffOccupationService.getOne(new QueryWrapper().eq("staff_id", staffEntity.getId())); + if (occupation == null) { + occupationEntity.setStaffId(staffEntity.getId()); + staffOccupationService.save(occupationEntity); + } else { + occupationEntity.setId(occupation.getId()); + staffOccupationService.updateById(occupationEntity); + } + + StaffEducationEntity education = staffEducationService.getOne(new QueryWrapper().eq("staff_id", staffEntity.getId())); + if (education == null) { + educationEntity.setStaffId(staffEntity.getId()); + staffEducationService.save(educationEntity); + } else { + educationEntity.setId(education.getId()); + staffEducationService.updateById(educationEntity); + } + } + for (Map map : sheet3List) { + StaffProjectExperienceEntity staffProjectExperienceEntity = JSON.parseObject(JSON.toJSONString(map), StaffProjectExperienceEntity.class); + StaffEntity Staff = this.getByName(map.get("name")); + if (Staff == null) { + continue; + } else { + staffProjectExperienceService.update(new UpdateWrapper().set("is_delete", 1).eq("staff_id", Staff.getId())); + StaffProjectExperienceEntity projectExperienceEntity = staffProjectExperienceService.getOne(new QueryWrapper().eq("staff_id", Staff.getId()).eq("project_name", staffProjectExperienceEntity.getProjectName())); + if (projectExperienceEntity == null) { + staffProjectExperienceEntity.setStaffId(Staff.getId()); + staffProjectExperienceService.save(staffProjectExperienceEntity); + } else { + staffProjectExperienceEntity.setId(projectExperienceEntity.getId()); + staffProjectExperienceEntity.setIsDelete(0); + staffProjectExperienceService.updateById(staffProjectExperienceEntity); + } + } + } + for (Map map : sheet4List) { + StaffWorkTransferRecordEntity staffWorkTransferRecordEntity = JSON.parseObject(JSON.toJSONString(map), StaffWorkTransferRecordEntity.class); + StaffEntity Staff = this.getByName(map.get("name")); + if (Staff == null) { + continue; + } else { + staffWorkTransferRecordService.update(new UpdateWrapper().set("is_delete", 1).eq("staff_id", Staff.getId())); + StaffWorkTransferRecordEntity workTransferRecordEntity = staffWorkTransferRecordService.getOne(new QueryWrapper().eq("staff_id", Staff.getId()).eq("transfer_time", staffWorkTransferRecordEntity.getTransferTime())); + if (workTransferRecordEntity == null) { + staffWorkTransferRecordEntity.setStaffId(Staff.getId()); + staffWorkTransferRecordService.save(staffWorkTransferRecordEntity); + } else { + staffWorkTransferRecordEntity.setId(workTransferRecordEntity.getId()); + staffWorkTransferRecordEntity.setIsDelete(0); + staffWorkTransferRecordService.updateById(staffWorkTransferRecordEntity); + } + } + } + } + private StaffEntity convertStaffEntity(DepartmentStaffBo staffBo) { StaffEntity staffEntity = new StaffEntity(); staffEntity.setName(staffBo.getName());//员工姓名 diff --git a/src/main/java/com/lz/modules/job/task/GetFeishuDepartmentsJob.java b/src/main/java/com/lz/modules/job/task/SyncnizeFlybookDataJob.java similarity index 76% rename from src/main/java/com/lz/modules/job/task/GetFeishuDepartmentsJob.java rename to src/main/java/com/lz/modules/job/task/SyncnizeFlybookDataJob.java index a5a274db..9c9ca8e4 100644 --- a/src/main/java/com/lz/modules/job/task/GetFeishuDepartmentsJob.java +++ b/src/main/java/com/lz/modules/job/task/SyncnizeFlybookDataJob.java @@ -22,8 +22,8 @@ import org.springframework.stereotype.Component; * * @author fumeiai 20200429 */ -@Component("getFeishuDepartmentsJob") -public class GetFeishuDepartmentsJob { +@Component("syncnizeFlybookDataJob") +public class SyncnizeFlybookDataJob { private Logger logger = LoggerFactory.getLogger(getClass()); @Autowired @@ -31,9 +31,9 @@ public class GetFeishuDepartmentsJob { public void run() { - logger.info("borrowAndRepayMonitorJob start date == {}", DateUtils.getCurrentDate()); + logger.info("syncnizeFlybookDataJob start date == {}", DateUtils.getCurrentDate()); feishuBusiness.getFeishuDepartmentsIntoData(); - logger.info("borrowAndRepayMonitorJob end date == {}", DateUtils.getCurrentDate()); + logger.info("syncnizeFlybookDataJob end date == {}", DateUtils.getCurrentDate()); } diff --git a/src/test/java/com/lz/FumeiaiTest.java b/src/test/java/com/lz/FumeiaiTest.java index 784562a8..5b0fc285 100644 --- a/src/test/java/com/lz/FumeiaiTest.java +++ b/src/test/java/com/lz/FumeiaiTest.java @@ -41,15 +41,16 @@ public class FumeiaiTest { feishuBusiness.getFeishuDepartmentsIntoData(); File xlsFile = new File("/Users/fumeiai/tmp/员工档案字段表-0427.xlsx"); - // 获得工作簿 - Workbook workbook = WorkbookFactory.create(xlsFile); - // 获得工作表个数 - int sheetCount = workbook.getNumberOfSheets(); List> sheet12List = Lists.newArrayList(); List> sheet3List = Lists.newArrayList(); List> sheet4List = Lists.newArrayList(); + // 获得工作簿 + Workbook workbook = WorkbookFactory.create(xlsFile); + // 获得工作表个数 + int sheetCount = workbook.getNumberOfSheets(); + // 遍历工作表 for (int i = 0; i < sheetCount; i++) { Sheet sheet = workbook.getSheetAt(i); diff --git a/target/classes/com/lz/modules/sys/oauth2/OAuth2Filter.class b/target/classes/com/lz/modules/sys/oauth2/OAuth2Filter.class index 3632a31756bb1b9b9a89658e9f66d0b7a903fa53..64186ed4fb978473a9cd193d1304d8a77578ddf1 100644 GIT binary patch delta 1522 zcmaJ>TXR!Y6#jP3WhbX6rHPhu8ZPNw(zLY|p^c!HS}qC{1*<4pYfUk2O==TLQ8a+{ zu4vt&;stbk=mQ-`#+hDl#^J?r#z%jFzrYuL@PT3c_GwIKeDKViz1G@iUB310wa*_L zuW#=8_15*D0BplI4jOPo;;4gqJnCQ&k4Zf4z{0T#1n@)%PvW@4B&MSm(5GOqBaEnRAXkh6fno~xvUBqe~F~pY$R2uxg#X;jKr%IPc;$%u2lO;tjm%;w^2Qaq%|Z5ol&u+|Ez3 zY+5zi$*u3=J%L#7$VfV$Z|lot3sbp?w%&<}+^M#KsmzH?R^ojZ7ci^7vuo5jdsBx% zIFp?op2$2GFXYD4bojuT>AkIyXI&9ywV^AIK4z zKxIB%(3sQN!qL-{X@PdN#b{EKMo5i?wy6=P|8PA|Tt7AhNF3K@S{;;v(n>5rT%!^| zOUVg{;|}WXsspwnLCZudk}!zrZzoyQzESRh2}6vmVnmc4IxgYw$4YTP3~gxlbH!Np zPF4!hw-a5=b{GAF5H}H(oX)#xne^O_9n?Yr25O{wvl~4O)X1kO)wdN5K88x>0CQF| zUkx*?)%VKvy>fl8R3Gq=!ab$>21JctFl>|yru?Eiu}gPM{dY>6axl?)1A!$NhuVtE zFfU&ia+qJ=m$!cnhi>dr0Ciq@_m7GOhb6j*B%u)U4H zKqlw;Qcc+;!?PE$iF~AFi6BpEYJ#4%N==Z|%)?6A#sa6I1w(iin@a?>^B)7!AXR<1 zrKr#QI01FjtB=&!=tnKzJ&-uU3D$fBHQX{EqwIaJKaHcbV)qeC-Km@!~x;YOT^sEWMCSU2PdHaN2N*4Q|hF#*65ZM#Q7=d&y4Ha yb=v-(pLy_VU1iNa-AjBmpo})g!#+&3|K6Cu+Kut_ndy6C2|9sJ4|5IRk$(VpQQ&_7 delta 1307 zcmaKrTXR!Y6vu!2Bq#gi-jEog?W0lHuZm)=eN})0*eV+0-ZGu1ZIK$_P z8%D~Gh+@%J3qsbuLv(K~fOc*XE6S~8h|n6eCbFt6=ub2qHc=VzKuaykXdPt3 z%oc8Ar__y;61dwX_YR44P*+K5cCkCGs^sE2MT=XKh@=>(yVxU%t--H}Ox3j2D9K2P zjZ&gX60QOJbzr{^?AL(7r;EF5z!6kah}00NBXxyndG0a9M1N2kH%M0Wypd)k)o^go z8-k|S+;vdX^cq{M2Kqm&?&Uti3RJt4i3`H0AH6~%Z~J!2TcyE5l*ZJ$Rn|w0np`1u zFf_8uZ1@G8U6Q}3`B+k&@ng$uTwzmQ|47rJOWf$|W&FJ3+p9Dyd}o=KCG31Ga$ab) zGt3b-3vgTTXT$EQ8R3vL(IuYyc|ch9&@2OZ2+e@({$UxnV_K|p9hEJ1hnpSc5s9`! zui7Z&n`uFZ#8c}>xl zj?|V_wp#RMSBNg+h4xLx{z2TrMPw?xz@x&Y#CpbL>66#(>iWy<<4Ng1yvKH-XI(o; T-yEblLtD`&k7B<_iv#}wSERfY