diff --git a/evo-admin/pom.xml b/evo-admin/pom.xml index 7906769..ae0e554 100644 --- a/evo-admin/pom.xml +++ b/evo-admin/pom.xml @@ -214,6 +214,15 @@ nashorn-core 15.4 + + + + com.kingdee.bos + k3cloud-webapi-sdk-java11 + v8.2.0 + system + ${project.basedir}/src/main/resources/lib/k3cloud-webapi-sdk-java11-v8.2.0.jar + diff --git a/evo-admin/src/main/java/com/evo/common/annotation/Excel.java b/evo-admin/src/main/java/com/evo/common/annotation/Excel.java index 1e58bbc..b147861 100644 --- a/evo-admin/src/main/java/com/evo/common/annotation/Excel.java +++ b/evo-admin/src/main/java/com/evo/common/annotation/Excel.java @@ -5,9 +5,11 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.math.BigDecimal; + +import com.evo.common.utils.poi.handler.ExcelFieldHandlerAdapter; import org.apache.poi.ss.usermodel.HorizontalAlignment; import org.apache.poi.ss.usermodel.IndexedColors; -import com.evo.common.utils.poi.ExcelHandlerAdapter; +import com.evo.common.utils.poi.handler.ExcelHandlerAdapter; /** * 自定义导出Excel数据注解 @@ -148,6 +150,15 @@ public @interface Excel */ public Class handler() default ExcelHandlerAdapter.class; + /** + * 自定义数据处理器 + */ + public boolean customExcelField() default false; + /** + * 自定义数据处理器 + */ + public Class excelFieldHandler() default ExcelFieldHandlerAdapter.class; + /** * 自定义数据处理器参数 */ diff --git a/evo-admin/src/main/java/com/evo/common/utils/ParamUtils.java b/evo-admin/src/main/java/com/evo/common/utils/ParamUtils.java index b14e87a..210844a 100644 --- a/evo-admin/src/main/java/com/evo/common/utils/ParamUtils.java +++ b/evo-admin/src/main/java/com/evo/common/utils/ParamUtils.java @@ -284,7 +284,7 @@ public class ParamUtils { * @return */ public static List getFullPaidLeave(){ - RzSysParam param= paramService.getRzSysParam("全薪发放的假期", "full_paid_leave","54,56,58,59,60","全薪发放的假期; 54-年休假,56-婚假,58-陪产假,59-丧假,60-工伤假"); + RzSysParam param= paramService.getRzSysParam("全薪发放的假期", "full_paid_leave","54,56,57,58,59,60","全薪发放的假期; 54-年休假, 56-婚假,57-产假,58-陪产假,59-丧假,60-工伤假 (55-调休假 这是个特殊的假期, 加班会自动抵扣)"); return Collections.asList(param.getParamValue().split(",")).stream().filter(StringUtils::isNotEmpty).map(Long::valueOf).collect(Collectors.toList()); } diff --git a/evo-admin/src/main/java/com/evo/common/utils/poi/ExcelUtil.java b/evo-admin/src/main/java/com/evo/common/utils/poi/ExcelUtil.java index 2733761..f7771bb 100644 --- a/evo-admin/src/main/java/com/evo/common/utils/poi/ExcelUtil.java +++ b/evo-admin/src/main/java/com/evo/common/utils/poi/ExcelUtil.java @@ -24,6 +24,8 @@ import java.util.Set; import java.util.UUID; import java.util.stream.Collectors; import javax.servlet.http.HttpServletResponse; + +import com.evo.common.utils.poi.handler.ExcelHandlerAdapter; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.RegExUtils; import org.apache.commons.lang3.reflect.FieldUtils; diff --git a/evo-admin/src/main/java/com/evo/common/utils/poi/ExcelUtil1.java b/evo-admin/src/main/java/com/evo/common/utils/poi/ExcelUtil1.java new file mode 100644 index 0000000..0b19ce3 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/utils/poi/ExcelUtil1.java @@ -0,0 +1,1889 @@ +package com.evo.common.utils.poi; + +import com.evo.common.annotation.Excel; +import com.evo.common.annotation.Excel.ColumnType; +import com.evo.common.annotation.Excel.Type; +import com.evo.common.annotation.Excels; +import com.evo.common.config.EvoConfig; +import com.evo.common.core.domain.AjaxResult; +import com.evo.common.core.text.Convert; +import com.evo.common.exception.UtilException; +import com.evo.common.utils.Collections; +import com.evo.common.utils.DateUtils; +import com.evo.common.utils.DictUtils; +import com.evo.common.utils.StringUtils; +import com.evo.common.utils.file.FileTypeUtils; +import com.evo.common.utils.file.FileUtils; +import com.evo.common.utils.file.ImageUtils; +import com.evo.common.utils.poi.handler.ExcelHandlerAdapter; +import com.evo.common.utils.reflect.ReflectUtils; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.RegExUtils; +import org.apache.commons.lang3.reflect.FieldUtils; +import org.apache.poi.hssf.usermodel.*; +import org.apache.poi.ooxml.POIXMLDocumentPart; +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.ss.util.CellRangeAddressList; +import org.apache.poi.util.IOUtils; +import org.apache.poi.xssf.streaming.SXSSFWorkbook; +import org.apache.poi.xssf.usermodel.*; +import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTMarker; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.servlet.http.HttpServletResponse; +import java.io.*; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.ParameterizedType; +import java.math.BigDecimal; +import java.text.DecimalFormat; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.*; +import java.util.stream.Collectors; + +/** + * Excel相关处理 + * + * @author evo + */ +public class ExcelUtil1 +{ + private static final Logger log = LoggerFactory.getLogger(ExcelUtil1.class); + + public static final String FORMULA_REGEX_STR = "=|-|\\+|@"; + + public static final String[] FORMULA_STR = { "=", "-", "+", "@" }; + + /** + * 用于dictType属性数据存储,避免重复查缓存 + */ + public Map sysDictMap = new HashMap(); + + /** + * Excel sheet最大行数,默认65536 + */ + public static final int sheetSize = 65536; + + /** + * 工作表名称 + */ + private String sheetName; + + /** + * 导出类型(EXPORT:导出数据;IMPORT:导入模板) + */ + private Type type; + + /** + * 工作薄对象 + */ + private Workbook wb; + + /** + * 工作表对象 + */ + private Sheet sheet; + + /** + * 样式列表 + */ + private Map styles; + + /** + * 导入导出数据列表 + */ + private List list; + + /** + * 注解列表 + */ + private List fields; + + /** + * 当前行号 + */ + private int rownum; + + /** + * 标题 + */ + private String title; + + /** + * 最大高度 + */ + private short maxHeight; + + /** + * 合并后最后行数 + */ + private int subMergedLastRowNum = 0; + + /** + * 合并后开始行数 + */ + private int subMergedFirstRowNum = 1; + + /** + * 对象的子列表方法 + */ + private Method subMethod; + + /** + * 对象的子列表属性 + */ + private List subFields; + + /** + * 统计列表 + */ + private Map statistics = new HashMap(); + + /** + * 数字格式 + */ + private static final DecimalFormat DOUBLE_FORMAT = new DecimalFormat("######0.00"); + + /** + * 实体对象 + */ + public Class clazz; + + /** + * 需要排除列属性 + */ + public String[] excludeFields; + + /** + */ + private Integer tsSize = 0; + + private Map> customTitleMap; + + public ExcelUtil1(Class clazz) + { + this.clazz = clazz; + } + + /** + * 隐藏Excel中列属性 + * + * @param fields 列属性名 示例[单个"name"/多个"id","name"] + * @throws Exception + */ + public void hideColumn(String... fields) + { + this.excludeFields = fields; + } + + public void init(List list, String sheetName, String title, Type type) + { + if (list == null) + { + list = new ArrayList(); + } + this.list = list; + this.sheetName = sheetName; + this.type = type; + this.title = title; + createExcelField(); + createWorkbook(); + createCustom(); + createTitle(); + createSubHead(); + } + + /** + * 获取特殊数据 + */ + public void createCustom(){ + for (Object[] objects : fields) + { + Excel attr = (Excel) objects[1]; + if(attr.customExcelField()){ + if(customTitleMap == null){ + customTitleMap = Collections.emptyMap(); + } + List titles = buildExcelFieldHandler(attr); + customTitleMap.put(attr.name(), titles); + tsSize = tsSize + titles.size(); + } + + } + } + + public List buildExcelFieldHandler(Excel excel){ + try + { + Object instance = excel.excelFieldHandler().newInstance(); + Method formatMethod = excel.excelFieldHandler().getMethod("buildExcel"); + return (List) formatMethod.invoke(instance); + } + catch (Exception e) + { + e.printStackTrace(); + log.error("不能格式化数据 " + excel.handler(), e.getMessage()); + } + return Collections.emptyList(); + } + + /** + * 创建excel第一行标题 + */ + public void createTitle() + { + if (StringUtils.isNotEmpty(title)) + { + subMergedFirstRowNum++; + subMergedLastRowNum++; + int titleLastCol = this.fields.size() - 1 + tsSize; + if (isSubList()) + { + titleLastCol = titleLastCol + subFields.size() - 1; + } + Row titleRow = sheet.createRow(rownum == 0 ? rownum++ : 0); + titleRow.setHeightInPoints(30); + Cell titleCell = titleRow.createCell(0); + titleCell.setCellStyle(styles.get("title")); + titleCell.setCellValue(title); + sheet.addMergedRegion(new CellRangeAddress(titleRow.getRowNum(), titleRow.getRowNum(), titleRow.getRowNum(), titleLastCol)); + } + } + + /** + * 创建对象的子列表名称 + */ + public void createSubHead() + { + if (isSubList()) + { + subMergedFirstRowNum++; + subMergedLastRowNum++; + Row subRow = sheet.createRow(rownum); + int excelNum = 0; + for (Object[] objects : fields) + { + Excel attr = (Excel) objects[1]; + Cell headCell1 = subRow.createCell(excelNum); + headCell1.setCellValue(attr.name()); + headCell1.setCellStyle(styles.get(StringUtils.format("header_{}_{}", attr.headerColor(), attr.headerBackgroundColor()))); + excelNum++; + } + int headFirstRow = excelNum - 1; + int headLastRow = headFirstRow + subFields.size() - 1; + if (headLastRow > headFirstRow) + { + sheet.addMergedRegion(new CellRangeAddress(rownum, rownum, headFirstRow, headLastRow)); + } + rownum++; + } + } + + /** + * 对excel表单默认第一个索引名转换成list + * + * @param is 输入流 + * @return 转换后集合 + */ + public List importExcel(InputStream is) + { + List list = null; + try + { + list = importExcel(is, 0); + } + catch (Exception e) + { + log.error("导入Excel异常{}", e.getMessage()); + throw new UtilException(e.getMessage()); + } + finally + { + IOUtils.closeQuietly(is); + } + return list; + } + + /** + * 对excel表单默认第一个索引名转换成list + * + * @param is 输入流 + * @param titleNum 标题占用行数 + * @return 转换后集合 + */ + public List importExcel(InputStream is, int titleNum) throws Exception + { + return importExcel(StringUtils.EMPTY, is, titleNum); + } + + /** + * 对excel表单指定表格索引名转换成list + * + * @param sheetName 表格索引名 + * @param titleNum 标题占用行数 + * @param is 输入流 + * @return 转换后集合 + */ + public List importExcel(String sheetName, InputStream is, int titleNum) throws Exception + { + this.type = Type.IMPORT; + this.wb = WorkbookFactory.create(is); + List list = new ArrayList(); + // 如果指定sheet名,则取指定sheet中的内容 否则默认指向第1个sheet + Sheet sheet = StringUtils.isNotEmpty(sheetName) ? wb.getSheet(sheetName) : wb.getSheetAt(0); + if (sheet == null) + { + throw new IOException("文件sheet不存在"); + } + boolean isXSSFWorkbook = !(wb instanceof HSSFWorkbook); + Map pictures; + if (isXSSFWorkbook) + { + pictures = getSheetPictures07((XSSFSheet) sheet, (XSSFWorkbook) wb); + } + else + { + pictures = getSheetPictures03((HSSFSheet) sheet, (HSSFWorkbook) wb); + } + // 获取最后一个非空行的行下标,比如总行数为n,则返回的为n-1 + int rows = sheet.getLastRowNum(); + if (rows > 0) + { + // 定义一个map用于存放excel列的序号和field. + Map cellMap = new HashMap(); + // 获取表头 + Row heard = sheet.getRow(titleNum); + for (int i = 0; i < heard.getPhysicalNumberOfCells(); i++) + { + Cell cell = heard.getCell(i); + if (StringUtils.isNotNull(cell)) + { + String value = this.getCellValue(heard, i).toString(); + cellMap.put(value, i); + } + else + { + cellMap.put(null, i); + } + } + // 有数据时才处理 得到类的所有field. + List fields = this.getFields(); + Map fieldsMap = new HashMap(); + for (Object[] objects : fields) + { + Excel attr = (Excel) objects[1]; + Integer column = cellMap.get(attr.name()); + if (column != null) + { + fieldsMap.put(column, objects); + } + } + for (int i = titleNum + 1; i <= rows; i++) + { + // 从第2行开始取数据,默认第一行是表头. + Row row = sheet.getRow(i); + // 判断当前行是否是空行 + if (isRowEmpty(row)) + { + continue; + } + T entity = null; + for (Map.Entry entry : fieldsMap.entrySet()) + { + Object val = this.getCellValue(row, entry.getKey()); + + // 如果不存在实例则新建. + entity = (entity == null ? clazz.newInstance() : entity); + // 从map中得到对应列的field. + Field field = (Field) entry.getValue()[0]; + Excel attr = (Excel) entry.getValue()[1]; + // 取得类型,并根据对象类型设置值. + Class fieldType = field.getType(); + if (String.class == fieldType) + { + String s = Convert.toStr(val); + if (StringUtils.endsWith(s, ".0")) + { + val = StringUtils.substringBefore(s, ".0"); + } + else + { + String dateFormat = field.getAnnotation(Excel.class).dateFormat(); + if (StringUtils.isNotEmpty(dateFormat)) + { + val = parseDateToStr(dateFormat, val); + } + else + { + val = Convert.toStr(val); + } + } + } + else if ((Integer.TYPE == fieldType || Integer.class == fieldType) && StringUtils.isNumeric(Convert.toStr(val))) + { + val = Convert.toInt(val); + } + else if ((Long.TYPE == fieldType || Long.class == fieldType) && StringUtils.isNumeric(Convert.toStr(val))) + { + val = Convert.toLong(val); + } + else if (Double.TYPE == fieldType || Double.class == fieldType) + { + val = Convert.toDouble(val); + } + else if (Float.TYPE == fieldType || Float.class == fieldType) + { + val = Convert.toFloat(val); + } + else if (BigDecimal.class == fieldType) + { + val = Convert.toBigDecimal(val); + } + else if (Date.class == fieldType) + { + if (val instanceof String) + { + val = DateUtils.parseDate(val); + } + else if (val instanceof Double) + { + val = DateUtil.getJavaDate((Double) val); + } + } + else if (Boolean.TYPE == fieldType || Boolean.class == fieldType) + { + val = Convert.toBool(val, false); + } + if (StringUtils.isNotNull(fieldType)) + { + String propertyName = field.getName(); + if (StringUtils.isNotEmpty(attr.targetAttr())) + { + propertyName = field.getName() + "." + attr.targetAttr(); + } + if (StringUtils.isNotEmpty(attr.readConverterExp())) + { + val = reverseByExp(Convert.toStr(val), attr.readConverterExp(), attr.separator()); + } + else if (StringUtils.isNotEmpty(attr.dictType())) + { + if (!sysDictMap.containsKey(attr.dictType() + val)) + { + String dictValue = reverseDictByExp(Convert.toStr(val), attr.dictType(), attr.separator()); + sysDictMap.put(attr.dictType() + val, dictValue); + } + val = sysDictMap.get(attr.dictType() + val); + } + else if (!attr.handler().equals(ExcelHandlerAdapter.class)) + { + val = dataFormatHandlerAdapter(val, attr, null); + } + else if (ColumnType.IMAGE == attr.cellType() && StringUtils.isNotEmpty(pictures)) + { + PictureData image = pictures.get(row.getRowNum() + "_" + entry.getKey()); + if (image == null) + { + val = ""; + } + else + { + byte[] data = image.getData(); + val = FileUtils.writeImportBytes(data); + } + } + ReflectUtils.invokeSetter(entity, propertyName, val); + } + } + list.add(entity); + } + } + return list; + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param list 导出数据集合 + * @param sheetName 工作表的名称 + * @return 结果 + */ + public AjaxResult exportExcel(List list, String sheetName) + { + return exportExcel(list, sheetName, StringUtils.EMPTY); + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param list 导出数据集合 + * @param sheetName 工作表的名称 + * @param title 标题 + * @return 结果 + */ + public AjaxResult exportExcel(List list, String sheetName, String title) + { + this.init(list, sheetName, title, Type.EXPORT); + return exportExcel(); + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param response 返回数据 + * @param list 导出数据集合 + * @param sheetName 工作表的名称 + * @return 结果 + */ + public void exportExcel(HttpServletResponse response, List list, String sheetName) + { + exportExcel(response, list, sheetName, StringUtils.EMPTY); + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param response 返回数据 + * @param list 导出数据集合 + * @param sheetName 工作表的名称 + * @param title 标题 + * @return 结果 + */ + public void exportExcel(HttpServletResponse response, List list, String sheetName, String title) + { + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + response.setCharacterEncoding("utf-8"); + this.init(list, sheetName, title, Type.EXPORT); + exportExcel(response); + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param sheetName 工作表的名称 + * @return 结果 + */ + public AjaxResult importTemplateExcel(String sheetName) + { + return importTemplateExcel(sheetName, StringUtils.EMPTY); + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param sheetName 工作表的名称 + * @param title 标题 + * @return 结果 + */ + public AjaxResult importTemplateExcel(String sheetName, String title) + { + this.init(null, sheetName, title, Type.IMPORT); + return exportExcel(); + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param sheetName 工作表的名称 + * @return 结果 + */ + public void importTemplateExcel(HttpServletResponse response, String sheetName) + { + importTemplateExcel(response, sheetName, StringUtils.EMPTY); + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param sheetName 工作表的名称 + * @param title 标题 + * @return 结果 + */ + public void importTemplateExcel(HttpServletResponse response, String sheetName, String title) + { + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + response.setCharacterEncoding("utf-8"); + this.init(null, sheetName, title, Type.IMPORT); + exportExcel(response); + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @return 结果 + */ + public void exportExcel(HttpServletResponse response) + { + try + { + writeSheet(); + wb.write(response.getOutputStream()); + } + catch (Exception e) + { + log.error("导出Excel异常{}", e.getMessage()); + } + finally + { + IOUtils.closeQuietly(wb); + } + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @return 结果 + */ + public AjaxResult exportExcel() + { + OutputStream out = null; + try + { + writeSheet(); + String filename = encodingFilename(sheetName); + out = new FileOutputStream(getAbsoluteFile(filename)); + wb.write(out); + return AjaxResult.success(filename); + } + catch (Exception e) + { + log.error("导出Excel异常{}", e.getMessage()); + throw new UtilException("导出Excel失败,请联系网站管理员!"); + } + finally + { + IOUtils.closeQuietly(wb); + IOUtils.closeQuietly(out); + } + } + + /** + * 创建写入数据到Sheet + */ + public void writeSheet() + { + // 取出一共有多少个sheet. + int sheetNo = Math.max(1, (int) Math.ceil(list.size() * 1.0 / sheetSize)); + for (int index = 0; index < sheetNo; index++) + { + createSheet(sheetNo, index); + + // 产生一行 + Row row = sheet.createRow(rownum); + int column = 0; + // 写入各个字段的列头名称 + for (Object[] os : fields) + { + Field field = (Field) os[0]; + Excel excel = (Excel) os[1]; + if (Collection.class.isAssignableFrom(field.getType())) + { + for (Field subField : subFields) + { + Excel subExcel = subField.getAnnotation(Excel.class); + this.createHeadCell(null, subExcel, row, column++); + } + }else if(excel.customExcelField()){ + for (String title : customTitleMap.get(excel.name())){ + this.createHeadCell(title, excel, row, column++); + } + } + else + { + this.createHeadCell(null, excel, row, column++); + } + } + if (Type.EXPORT.equals(type)) + { + fillExcelData(index, row); + addStatisticsRow(); + } + } + } + + /** + * 填充excel数据 + * + * @param index 序号 + * @param row 单元格行 + */ + @SuppressWarnings("unchecked") + public void fillExcelData(int index, Row row) + { + int startNo = index * sheetSize; + int endNo = Math.min(startNo + sheetSize, list.size()); + int rowNo = (1 + rownum) - startNo; + for (int i = startNo; i < endNo; i++) + { + rowNo = isSubList() ? (i > 1 ? rowNo + 1 : rowNo + i) : i + 1 + rownum - startNo; + row = sheet.createRow(rowNo); + // 得到导出对象. + T vo = (T) list.get(i); + Collection subList = null; + if (isSubList()) + { + if (isSubListValue(vo)) + { + subList = getListCellValue(vo); + subMergedLastRowNum = subMergedLastRowNum + subList.size(); + } + else + { + subMergedFirstRowNum++; + subMergedLastRowNum++; + } + } + int column = 0; + for (Object[] os : fields){ + Field field = (Field) os[0]; + Excel excel = (Excel) os[1]; + if (Collection.class.isAssignableFrom(field.getType()) && StringUtils.isNotNull(subList)) + { + boolean subFirst = false; + for (Object obj : subList) + { + if (subFirst) + { + rowNo++; + row = sheet.createRow(rowNo); + } + List subFields = FieldUtils.getFieldsListWithAnnotation(obj.getClass(), Excel.class); + int subIndex = 0; + for (Field subField : subFields) + { + if (subField.isAnnotationPresent(Excel.class)) + { + subField.setAccessible(true); + Excel attr = subField.getAnnotation(Excel.class); + this.addCell(attr, row, (T) obj, subField, column + subIndex); + } + subIndex++; + } + subFirst = true; + } + this.subMergedFirstRowNum = this.subMergedFirstRowNum + subList.size(); + }else if(excel.customExcelField()){ + for (String title : customTitleMap.get(excel.name())){ + this.addCell(title, excel, row, vo, field, column++); + } + } + else + { + this.addCell(excel, row, vo, field, column++); + } + } + } + } + + /** + * 创建表格样式 + * + * @param wb 工作薄对象 + * @return 样式列表 + */ + private Map createStyles(Workbook wb) + { + // 写入各条记录,每条记录对应excel表中的一行 + Map styles = new HashMap(); + CellStyle style = wb.createCellStyle(); + style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); + Font titleFont = wb.createFont(); + titleFont.setFontName("Arial"); + titleFont.setFontHeightInPoints((short) 16); + titleFont.setBold(true); + style.setFont(titleFont); + DataFormat dataFormat = wb.createDataFormat(); + style.setDataFormat(dataFormat.getFormat("@")); + styles.put("title", style); + + style = wb.createCellStyle(); + style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); + style.setBorderRight(BorderStyle.THIN); + style.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setBorderLeft(BorderStyle.THIN); + style.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setBorderTop(BorderStyle.THIN); + style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setBorderBottom(BorderStyle.THIN); + style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + Font dataFont = wb.createFont(); + dataFont.setFontName("Arial"); + dataFont.setFontHeightInPoints((short) 10); + style.setFont(dataFont); + styles.put("data", style); + + style = wb.createCellStyle(); + style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); + Font totalFont = wb.createFont(); + totalFont.setFontName("Arial"); + totalFont.setFontHeightInPoints((short) 10); + style.setFont(totalFont); + styles.put("total", style); + + styles.putAll(annotationHeaderStyles(wb, styles)); + + styles.putAll(annotationDataStyles(wb)); + + return styles; + } + + /** + * 根据Excel注解创建表格头样式 + * + * @param wb 工作薄对象 + * @return 自定义样式列表 + */ + private Map annotationHeaderStyles(Workbook wb, Map styles) + { + Map headerStyles = new HashMap(); + for (Object[] os : fields) + { + Excel excel = (Excel) os[1]; + String key = StringUtils.format("header_{}_{}", excel.headerColor(), excel.headerBackgroundColor()); + if (!headerStyles.containsKey(key)) + { + CellStyle style = wb.createCellStyle(); + style.cloneStyleFrom(styles.get("data")); + style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); + style.setFillForegroundColor(excel.headerBackgroundColor().index); + style.setFillPattern(FillPatternType.SOLID_FOREGROUND); + Font headerFont = wb.createFont(); + headerFont.setFontName("Arial"); + headerFont.setFontHeightInPoints((short) 10); + headerFont.setBold(true); + headerFont.setColor(excel.headerColor().index); + style.setFont(headerFont); + // 设置表格头单元格文本形式 + DataFormat dataFormat = wb.createDataFormat(); + style.setDataFormat(dataFormat.getFormat("@")); + headerStyles.put(key, style); + } + } + return headerStyles; + } + + /** + * 根据Excel注解创建表格列样式 + * + * @param wb 工作薄对象 + * @return 自定义样式列表 + */ + private Map annotationDataStyles(Workbook wb) + { + Map styles = new HashMap(); + for (Object[] os : fields) + { + Field field = (Field) os[0]; + Excel excel = (Excel) os[1]; + if (Collection.class.isAssignableFrom(field.getType())) + { + ParameterizedType pt = (ParameterizedType) field.getGenericType(); + Class subClass = (Class) pt.getActualTypeArguments()[0]; + List subFields = FieldUtils.getFieldsListWithAnnotation(subClass, Excel.class); + for (Field subField : subFields) + { + Excel subExcel = subField.getAnnotation(Excel.class); + annotationDataStyles(styles, subField, subExcel); + } + } + else + { + annotationDataStyles(styles, field, excel); + } + } + return styles; + } + + /** + * 根据Excel注解创建表格列样式 + * + * @param styles 自定义样式列表 + * @param field 属性列信息 + * @param excel 注解信息 + */ + public void annotationDataStyles(Map styles, Field field, Excel excel) + { + String key = StringUtils.format("data_{}_{}_{}_{}", excel.align(), excel.color(), excel.backgroundColor(), excel.cellType()); + if (!styles.containsKey(key)) + { + CellStyle style = wb.createCellStyle(); + style.setAlignment(excel.align()); + style.setVerticalAlignment(VerticalAlignment.CENTER); + style.setBorderRight(BorderStyle.THIN); + style.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setBorderLeft(BorderStyle.THIN); + style.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setBorderTop(BorderStyle.THIN); + style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setBorderBottom(BorderStyle.THIN); + style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setFillPattern(FillPatternType.SOLID_FOREGROUND); + style.setFillForegroundColor(excel.backgroundColor().getIndex()); + Font dataFont = wb.createFont(); + dataFont.setFontName("Arial"); + dataFont.setFontHeightInPoints((short) 10); + dataFont.setColor(excel.color().index); + style.setFont(dataFont); + if (ColumnType.TEXT == excel.cellType()) + { + DataFormat dataFormat = wb.createDataFormat(); + style.setDataFormat(dataFormat.getFormat("@")); + } + styles.put(key, style); + } + } + + /** + * 创建单元格 + */ + public Cell createHeadCell(String title, Excel attr, Row row, int column) + { + // 创建列 + Cell cell = row.createCell(column); + // 写入列信息 + cell.setCellValue(((attr.customExcelField() && StringUtils.isNotEmpty(title)) ? title : attr.name())); + setDataValidation(attr, row, column); + cell.setCellStyle(styles.get(StringUtils.format("header_{}_{}", attr.headerColor(), attr.headerBackgroundColor()))); + if (isSubList()) + { + // 填充默认样式,防止合并单元格样式失效 + sheet.setDefaultColumnStyle(column, styles.get(StringUtils.format("data_{}_{}_{}_{}", attr.align(), attr.color(), attr.backgroundColor(), attr.cellType()))); + if (attr.needMerge()) + { + sheet.addMergedRegion(new CellRangeAddress(rownum - 1, rownum, column, column)); + } + } + return cell; + } + + /** + * 设置单元格信息 + * + * @param value 单元格值 + * @param attr 注解相关 + * @param cell 单元格信息 + */ + public void setCellVo(Object value, Excel attr, Cell cell) + { + if (ColumnType.STRING == attr.cellType() || ColumnType.TEXT == attr.cellType()) + { + String cellValue = Convert.toStr(value); + // 对于任何以表达式触发字符 =-+@开头的单元格,直接使用tab字符作为前缀,防止CSV注入。 + if (StringUtils.startsWithAny(cellValue, FORMULA_STR)) + { + cellValue = RegExUtils.replaceFirst(cellValue, FORMULA_REGEX_STR, "\t$0"); + } + if (value instanceof Collection && StringUtils.equals("[]", cellValue)) + { + cellValue = StringUtils.EMPTY; + } + cell.setCellValue(StringUtils.isNull(cellValue) ? attr.defaultValue() : cellValue + attr.suffix()); + } + else if (ColumnType.NUMERIC == attr.cellType()) + { + if (StringUtils.isNotNull(value)) + { + cell.setCellValue(StringUtils.contains(Convert.toStr(value), ".") ? Convert.toDouble(value) : Convert.toInt(value)); + } + } + else if (ColumnType.IMAGE == attr.cellType()) + { + ClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, (short) cell.getColumnIndex(), cell.getRow().getRowNum(), (short) (cell.getColumnIndex() + 1), cell.getRow().getRowNum() + 1); + String imagePath = Convert.toStr(value); + if (StringUtils.isNotEmpty(imagePath)) + { + byte[] data = ImageUtils.getImage(imagePath); + getDrawingPatriarch(cell.getSheet()).createPicture(anchor, + cell.getSheet().getWorkbook().addPicture(data, getImageType(data))); + } + } + } + + /** + * 获取画布 + */ + public static Drawing getDrawingPatriarch(Sheet sheet) + { + if (sheet.getDrawingPatriarch() == null) + { + sheet.createDrawingPatriarch(); + } + return sheet.getDrawingPatriarch(); + } + + /** + * 获取图片类型,设置图片插入类型 + */ + public int getImageType(byte[] value) + { + String type = FileTypeUtils.getFileExtendName(value); + if ("JPG".equalsIgnoreCase(type)) + { + return Workbook.PICTURE_TYPE_JPEG; + } + else if ("PNG".equalsIgnoreCase(type)) + { + return Workbook.PICTURE_TYPE_PNG; + } + return Workbook.PICTURE_TYPE_JPEG; + } + + /** + * 创建表格样式 + */ + public void setDataValidation(Excel attr, Row row, int column) + { + if (attr.name().indexOf("注:") >= 0) + { + sheet.setColumnWidth(column, 6000); + } + else + { + // 设置列宽 + sheet.setColumnWidth(column, (int) ((attr.width() + 0.72) * 256)); + } + if (StringUtils.isNotEmpty(attr.prompt()) || attr.combo().length > 0 || attr.comboReadDict()) + { + String[] comboArray = attr.combo(); + if (attr.comboReadDict()) + { + if (!sysDictMap.containsKey("combo_" + attr.dictType())) + { + String labels = DictUtils.getDictLabels(attr.dictType()); + sysDictMap.put("combo_" + attr.dictType(), labels); + } + String val = sysDictMap.get("combo_" + attr.dictType()); + comboArray = StringUtils.split(val, DictUtils.SEPARATOR); + } + if (comboArray.length > 15 || StringUtils.join(comboArray).length() > 255) + { + // 如果下拉数大于15或字符串长度大于255,则使用一个新sheet存储,避免生成的模板下拉值获取不到 + setXSSFValidationWithHidden(sheet, comboArray, attr.prompt(), 1, 100, column, column); + } + else + { + // 提示信息或只能选择不能输入的列内容. + setPromptOrValidation(sheet, comboArray, attr.prompt(), 1, 100, column, column); + } + } + } + + /** + * 添加单元格 + */ + public Cell addCell(String title, Excel attr, Row row, T vo, Field field, int column) + { + Cell cell = null; + try + { + // 设置行高 + row.setHeight(maxHeight); + // 根据Excel中设置情况决定是否导出,有些情况需要保持为空,希望用户填写这一列. + if (attr.isExport()) + { + // 创建cell + cell = row.createCell(column); + if (isSubListValue(vo) && getListCellValue(vo).size() > 1 && attr.needMerge()) + { + CellRangeAddress cellAddress = new CellRangeAddress(subMergedFirstRowNum, subMergedLastRowNum, column, column); + sheet.addMergedRegion(cellAddress); + } + cell.setCellStyle(styles.get(StringUtils.format("data_{}_{}_{}_{}", attr.align(), attr.color(), attr.backgroundColor(), attr.cellType()))); + + // 用于读取对象中的属性 + Object value = getTargetValue(title, vo, field, attr); + String dateFormat = attr.dateFormat(); + String readConverterExp = attr.readConverterExp(); + String separator = attr.separator(); + String dictType = attr.dictType(); + if (StringUtils.isNotEmpty(dateFormat) && StringUtils.isNotNull(value)) + { + cell.setCellValue(parseDateToStr(dateFormat, value)); + } + else if (StringUtils.isNotEmpty(readConverterExp) && StringUtils.isNotNull(value)) + { + cell.setCellValue(convertByExp(Convert.toStr(value), readConverterExp, separator)); + } + else if (StringUtils.isNotEmpty(dictType) && StringUtils.isNotNull(value)) + { + if (!sysDictMap.containsKey(dictType + value)) + { + String lable = convertDictByExp(Convert.toStr(value), dictType, separator); + sysDictMap.put(dictType + value, lable); + } + cell.setCellValue(sysDictMap.get(dictType + value)); + } + else if (value instanceof BigDecimal && -1 != attr.scale()) + { + cell.setCellValue((((BigDecimal) value).setScale(attr.scale(), attr.roundingMode())).doubleValue()); + } + else if (!attr.handler().equals(ExcelHandlerAdapter.class)) + { + cell.setCellValue(dataFormatHandlerAdapter(value, attr, cell)); + } + else + { + // 设置列类型 + setCellVo(value, attr, cell); + } + addStatisticsData(column, Convert.toStr(value), attr); + } + } + catch (Exception e) + { + log.error("导出Excel失败{}", e); + } + return cell; + } + + + /** + * 添加单元格 + */ + public Cell addCell(Excel attr, Row row, T vo, Field field, int column) + { + Cell cell = null; + try + { + // 设置行高 + row.setHeight(maxHeight); + // 根据Excel中设置情况决定是否导出,有些情况需要保持为空,希望用户填写这一列. + if (attr.isExport()) + { + // 创建cell + cell = row.createCell(column); + if (isSubListValue(vo) && getListCellValue(vo).size() > 1 && attr.needMerge()) + { + CellRangeAddress cellAddress = new CellRangeAddress(subMergedFirstRowNum, subMergedLastRowNum, column, column); + sheet.addMergedRegion(cellAddress); + } + cell.setCellStyle(styles.get(StringUtils.format("data_{}_{}_{}_{}", attr.align(), attr.color(), attr.backgroundColor(), attr.cellType()))); + + // 用于读取对象中的属性 + Object value = getTargetValue(null, vo, field, attr); + String dateFormat = attr.dateFormat(); + String readConverterExp = attr.readConverterExp(); + String separator = attr.separator(); + String dictType = attr.dictType(); + if (StringUtils.isNotEmpty(dateFormat) && StringUtils.isNotNull(value)) + { + cell.setCellValue(parseDateToStr(dateFormat, value)); + } + else if (StringUtils.isNotEmpty(readConverterExp) && StringUtils.isNotNull(value)) + { + cell.setCellValue(convertByExp(Convert.toStr(value), readConverterExp, separator)); + } + else if (StringUtils.isNotEmpty(dictType) && StringUtils.isNotNull(value)) + { + if (!sysDictMap.containsKey(dictType + value)) + { + String lable = convertDictByExp(Convert.toStr(value), dictType, separator); + sysDictMap.put(dictType + value, lable); + } + cell.setCellValue(sysDictMap.get(dictType + value)); + } + else if (value instanceof BigDecimal && -1 != attr.scale()) + { + cell.setCellValue((((BigDecimal) value).setScale(attr.scale(), attr.roundingMode())).doubleValue()); + } + else if (!attr.handler().equals(ExcelHandlerAdapter.class)) + { + cell.setCellValue(dataFormatHandlerAdapter(value, attr, cell)); + } + else + { + // 设置列类型 + setCellVo(value, attr, cell); + } + addStatisticsData(column, Convert.toStr(value), attr); + } + } + catch (Exception e) + { + log.error("导出Excel失败{}", e); + } + return cell; + } + + /** + * 设置 POI XSSFSheet 单元格提示或选择框 + * + * @param sheet 表单 + * @param textlist 下拉框显示的内容 + * @param promptContent 提示内容 + * @param firstRow 开始行 + * @param endRow 结束行 + * @param firstCol 开始列 + * @param endCol 结束列 + */ + public void setPromptOrValidation(Sheet sheet, String[] textlist, String promptContent, int firstRow, int endRow, + int firstCol, int endCol) + { + DataValidationHelper helper = sheet.getDataValidationHelper(); + DataValidationConstraint constraint = textlist.length > 0 ? helper.createExplicitListConstraint(textlist) : helper.createCustomConstraint("DD1"); + CellRangeAddressList regions = new CellRangeAddressList(firstRow, endRow, firstCol, endCol); + DataValidation dataValidation = helper.createValidation(constraint, regions); + if (StringUtils.isNotEmpty(promptContent)) + { + // 如果设置了提示信息则鼠标放上去提示 + dataValidation.createPromptBox("", promptContent); + dataValidation.setShowPromptBox(true); + } + // 处理Excel兼容性问题 + if (dataValidation instanceof XSSFDataValidation) + { + dataValidation.setSuppressDropDownArrow(true); + dataValidation.setShowErrorBox(true); + } + else + { + dataValidation.setSuppressDropDownArrow(false); + } + sheet.addValidationData(dataValidation); + } + + /** + * 设置某些列的值只能输入预制的数据,显示下拉框(兼容超出一定数量的下拉框). + * + * @param sheet 要设置的sheet. + * @param textlist 下拉框显示的内容 + * @param promptContent 提示内容 + * @param firstRow 开始行 + * @param endRow 结束行 + * @param firstCol 开始列 + * @param endCol 结束列 + */ + public void setXSSFValidationWithHidden(Sheet sheet, String[] textlist, String promptContent, int firstRow, int endRow, int firstCol, int endCol) + { + String hideSheetName = "combo_" + firstCol + "_" + endCol; + Sheet hideSheet = wb.createSheet(hideSheetName); // 用于存储 下拉菜单数据 + for (int i = 0; i < textlist.length; i++) + { + hideSheet.createRow(i).createCell(0).setCellValue(textlist[i]); + } + // 创建名称,可被其他单元格引用 + Name name = wb.createName(); + name.setNameName(hideSheetName + "_data"); + name.setRefersToFormula(hideSheetName + "!$A$1:$A$" + textlist.length); + DataValidationHelper helper = sheet.getDataValidationHelper(); + // 加载下拉列表内容 + DataValidationConstraint constraint = helper.createFormulaListConstraint(hideSheetName + "_data"); + // 设置数据有效性加载在哪个单元格上,四个参数分别是:起始行、终止行、起始列、终止列 + CellRangeAddressList regions = new CellRangeAddressList(firstRow, endRow, firstCol, endCol); + // 数据有效性对象 + DataValidation dataValidation = helper.createValidation(constraint, regions); + if (StringUtils.isNotEmpty(promptContent)) + { + // 如果设置了提示信息则鼠标放上去提示 + dataValidation.createPromptBox("", promptContent); + dataValidation.setShowPromptBox(true); + } + // 处理Excel兼容性问题 + if (dataValidation instanceof XSSFDataValidation) + { + dataValidation.setSuppressDropDownArrow(true); + dataValidation.setShowErrorBox(true); + } + else + { + dataValidation.setSuppressDropDownArrow(false); + } + + sheet.addValidationData(dataValidation); + // 设置hiddenSheet隐藏 + wb.setSheetHidden(wb.getSheetIndex(hideSheet), true); + } + + /** + * 解析导出值 0=男,1=女,2=未知 + * + * @param propertyValue 参数值 + * @param converterExp 翻译注解 + * @param separator 分隔符 + * @return 解析后值 + */ + public static String convertByExp(String propertyValue, String converterExp, String separator) + { + StringBuilder propertyString = new StringBuilder(); + String[] convertSource = converterExp.split(","); + for (String item : convertSource) + { + String[] itemArray = item.split("="); + if (StringUtils.containsAny(propertyValue, separator)) + { + for (String value : propertyValue.split(separator)) + { + if (itemArray[0].equals(value)) + { + propertyString.append(itemArray[1] + separator); + break; + } + } + } + else + { + if (itemArray[0].equals(propertyValue)) + { + return itemArray[1]; + } + } + } + return StringUtils.stripEnd(propertyString.toString(), separator); + } + + /** + * 反向解析值 男=0,女=1,未知=2 + * + * @param propertyValue 参数值 + * @param converterExp 翻译注解 + * @param separator 分隔符 + * @return 解析后值 + */ + public static String reverseByExp(String propertyValue, String converterExp, String separator) + { + StringBuilder propertyString = new StringBuilder(); + String[] convertSource = converterExp.split(","); + for (String item : convertSource) + { + String[] itemArray = item.split("="); + if (StringUtils.containsAny(propertyValue, separator)) + { + for (String value : propertyValue.split(separator)) + { + if (itemArray[1].equals(value)) + { + propertyString.append(itemArray[0] + separator); + break; + } + } + } + else + { + if (itemArray[1].equals(propertyValue)) + { + return itemArray[0]; + } + } + } + return StringUtils.stripEnd(propertyString.toString(), separator); + } + + /** + * 解析字典值 + * + * @param dictValue 字典值 + * @param dictType 字典类型 + * @param separator 分隔符 + * @return 字典标签 + */ + public static String convertDictByExp(String dictValue, String dictType, String separator) + { + return DictUtils.getDictLabel(dictType, dictValue, separator); + } + + /** + * 反向解析值字典值 + * + * @param dictLabel 字典标签 + * @param dictType 字典类型 + * @param separator 分隔符 + * @return 字典值 + */ + public static String reverseDictByExp(String dictLabel, String dictType, String separator) + { + return DictUtils.getDictValue(dictType, dictLabel, separator); + } + + /** + * 数据处理器 + * + * @param value 数据值 + * @param excel 数据注解 + * @return + */ + public String dataFormatHandlerAdapter(Object value, Excel excel, Cell cell) + { + try + { + Object instance = excel.handler().newInstance(); + Method formatMethod = excel.handler().getMethod("format", new Class[] { Object.class, String[].class, Cell.class, Workbook.class }); + value = formatMethod.invoke(instance, value, excel.args(), cell, this.wb); + } + catch (Exception e) + { + log.error("不能格式化数据 " + excel.handler(), e.getMessage()); + } + return Convert.toStr(value); + } + + /** + * 合计统计信息 + */ + private void addStatisticsData(Integer index, String text, Excel entity) + { + if (entity != null && entity.isStatistics()) + { + Double temp = 0D; + if (!statistics.containsKey(index)) + { + statistics.put(index, temp); + } + try + { + temp = Double.valueOf(text); + } + catch (NumberFormatException e) + { + } + statistics.put(index, statistics.get(index) + temp); + } + } + + /** + * 创建统计行 + */ + public void addStatisticsRow() + { + if (statistics.size() > 0) + { + Row row = sheet.createRow(sheet.getLastRowNum() + 1); + Set keys = statistics.keySet(); + Cell cell = row.createCell(0); + cell.setCellStyle(styles.get("total")); + cell.setCellValue("合计"); + + for (Integer key : keys) + { + cell = row.createCell(key); + cell.setCellStyle(styles.get("total")); + cell.setCellValue(DOUBLE_FORMAT.format(statistics.get(key))); + } + statistics.clear(); + } + } + + /** + * 编码文件名 + */ + public String encodingFilename(String filename) + { + filename = UUID.randomUUID() + "_" + filename + ".xlsx"; + return filename; + } + + /** + * 获取下载路径 + * + * @param filename 文件名称 + */ + public String getAbsoluteFile(String filename) + { + String downloadPath = EvoConfig.getDownloadPath() + filename; + File desc = new File(downloadPath); + if (!desc.getParentFile().exists()) + { + desc.getParentFile().mkdirs(); + } + return downloadPath; + } + + /** + * 获取bean中的属性值 + * + * @param vo 实体对象 + * @param field 字段 + * @param excel 注解 + * @return 最终的属性值 + * @throws Exception + */ + private Object getTargetValue(String title, T vo, Field field, Excel excel) throws Exception + { + Object o = field.get(vo); + if (StringUtils.isNotEmpty(excel.targetAttr())){ + String target = excel.targetAttr(); + if (target.contains(".")) + { + String[] targets = target.split("[.]"); + for (String name : targets) + { + o = getValue(o, name); + } + } + else + { + o = getValue(o, target); + } + } + if(excel.customExcelField() && StringUtils.isNotEmpty(title)){ + o = ((Map)o).get(title); + } + return o; + } + + /** + * 以类的属性的get方法方法形式获取值 + * + * @param o + * @param name + * @return value + * @throws Exception + */ + private Object getValue(Object o, String name) throws Exception + { + if (StringUtils.isNotNull(o) && StringUtils.isNotEmpty(name)) + { + Class clazz = o.getClass(); + Field field = clazz.getDeclaredField(name); + field.setAccessible(true); + o = field.get(o); + } + return o; + } + + /** + * 得到所有定义字段 + */ + private void createExcelField() + { + this.fields = getFields(); + this.fields = this.fields.stream().sorted(Comparator.comparing(objects -> ((Excel) objects[1]).sort())).collect(Collectors.toList()); + this.maxHeight = getRowHeight(); + } + + /** + * 获取字段注解信息 + */ + public List getFields() + { + List fields = new ArrayList(); + List tempFields = new ArrayList<>(); + tempFields.addAll(Arrays.asList(clazz.getSuperclass().getDeclaredFields())); + tempFields.addAll(Arrays.asList(clazz.getDeclaredFields())); + for (Field field : tempFields) + { + if (!ArrayUtils.contains(this.excludeFields, field.getName())) + { + // 单注解 + if (field.isAnnotationPresent(Excel.class)) + { + Excel attr = field.getAnnotation(Excel.class); + if (attr != null && (attr.type() == Type.ALL || attr.type() == type)) + { + field.setAccessible(true); + fields.add(new Object[] { field, attr }); + } + if (Collection.class.isAssignableFrom(field.getType())) + { + subMethod = getSubMethod(field.getName(), clazz); + ParameterizedType pt = (ParameterizedType) field.getGenericType(); + Class subClass = (Class) pt.getActualTypeArguments()[0]; + this.subFields = FieldUtils.getFieldsListWithAnnotation(subClass, Excel.class); + } + } + + // 多注解 + if (field.isAnnotationPresent(Excels.class)) + { + Excels attrs = field.getAnnotation(Excels.class); + Excel[] excels = attrs.value(); + for (Excel attr : excels) + { + if (!ArrayUtils.contains(this.excludeFields, field.getName() + "." + attr.targetAttr()) + && (attr != null && (attr.type() == Type.ALL || attr.type() == type))) + { + field.setAccessible(true); + fields.add(new Object[] { field, attr }); + } + } + } + } + } + return fields; + } + + /** + * 根据注解获取最大行高 + */ + public short getRowHeight() + { + double maxHeight = 0; + for (Object[] os : this.fields) + { + Excel excel = (Excel) os[1]; + maxHeight = Math.max(maxHeight, excel.height()); + } + return (short) (maxHeight * 20); + } + + /** + * 创建一个工作簿 + */ + public void createWorkbook() + { + this.wb = new SXSSFWorkbook(500); + this.sheet = wb.createSheet(); + wb.setSheetName(0, sheetName); + this.styles = createStyles(wb); + } + + /** + * 创建工作表 + * + * @param sheetNo sheet数量 + * @param index 序号 + */ + public void createSheet(int sheetNo, int index) + { + // 设置工作表的名称. + if (sheetNo > 1 && index > 0) + { + this.sheet = wb.createSheet(); + this.createTitle(); + wb.setSheetName(index, sheetName + index); + } + } + + /** + * 获取单元格值 + * + * @param row 获取的行 + * @param column 获取单元格列号 + * @return 单元格值 + */ + public Object getCellValue(Row row, int column) + { + if (row == null) + { + return row; + } + Object val = ""; + try + { + Cell cell = row.getCell(column); + if (StringUtils.isNotNull(cell)) + { + if (cell.getCellType() == CellType.NUMERIC || cell.getCellType() == CellType.FORMULA) + { + val = cell.getNumericCellValue(); + if (DateUtil.isCellDateFormatted(cell)) + { + val = DateUtil.getJavaDate((Double) val); // POI Excel 日期格式转换 + } + else + { + if ((Double) val % 1 != 0) + { + val = new BigDecimal(val.toString()); + } + else + { + val = new DecimalFormat("0").format(val); + } + } + } + else if (cell.getCellType() == CellType.STRING) + { + val = cell.getStringCellValue(); + } + else if (cell.getCellType() == CellType.BOOLEAN) + { + val = cell.getBooleanCellValue(); + } + else if (cell.getCellType() == CellType.ERROR) + { + val = cell.getErrorCellValue(); + } + + } + } + catch (Exception e) + { + return val; + } + return val; + } + + /** + * 判断是否是空行 + * + * @param row 判断的行 + * @return + */ + private boolean isRowEmpty(Row row) + { + if (row == null) + { + return true; + } + for (int i = row.getFirstCellNum(); i < row.getLastCellNum(); i++) + { + Cell cell = row.getCell(i); + if (cell != null && cell.getCellType() != CellType.BLANK) + { + return false; + } + } + return true; + } + + /** + * 获取Excel2003图片 + * + * @param sheet 当前sheet对象 + * @param workbook 工作簿对象 + * @return Map key:图片单元格索引(1_1)String,value:图片流PictureData + */ + public static Map getSheetPictures03(HSSFSheet sheet, HSSFWorkbook workbook) + { + Map sheetIndexPicMap = new HashMap(); + List pictures = workbook.getAllPictures(); + if (!pictures.isEmpty()) + { + for (HSSFShape shape : sheet.getDrawingPatriarch().getChildren()) + { + HSSFClientAnchor anchor = (HSSFClientAnchor) shape.getAnchor(); + if (shape instanceof HSSFPicture) + { + HSSFPicture pic = (HSSFPicture) shape; + int pictureIndex = pic.getPictureIndex() - 1; + HSSFPictureData picData = pictures.get(pictureIndex); + String picIndex = anchor.getRow1() + "_" + anchor.getCol1(); + sheetIndexPicMap.put(picIndex, picData); + } + } + return sheetIndexPicMap; + } + else + { + return sheetIndexPicMap; + } + } + + /** + * 获取Excel2007图片 + * + * @param sheet 当前sheet对象 + * @param workbook 工作簿对象 + * @return Map key:图片单元格索引(1_1)String,value:图片流PictureData + */ + public static Map getSheetPictures07(XSSFSheet sheet, XSSFWorkbook workbook) + { + Map sheetIndexPicMap = new HashMap(); + for (POIXMLDocumentPart dr : sheet.getRelations()) + { + if (dr instanceof XSSFDrawing) + { + XSSFDrawing drawing = (XSSFDrawing) dr; + List shapes = drawing.getShapes(); + for (XSSFShape shape : shapes) + { + if (shape instanceof XSSFPicture) + { + XSSFPicture pic = (XSSFPicture) shape; + XSSFClientAnchor anchor = pic.getPreferredSize(); + CTMarker ctMarker = anchor.getFrom(); + String picIndex = ctMarker.getRow() + "_" + ctMarker.getCol(); + sheetIndexPicMap.put(picIndex, pic.getPictureData()); + } + } + } + } + return sheetIndexPicMap; + } + + /** + * 格式化不同类型的日期对象 + * + * @param dateFormat 日期格式 + * @param val 被格式化的日期对象 + * @return 格式化后的日期字符 + */ + public String parseDateToStr(String dateFormat, Object val) + { + if (val == null) + { + return ""; + } + String str; + if (val instanceof Date) + { + str = DateUtils.parseDateToStr(dateFormat, (Date) val); + } + else if (val instanceof LocalDateTime) + { + str = DateUtils.parseDateToStr(dateFormat, DateUtils.toDate((LocalDateTime) val)); + } + else if (val instanceof LocalDate) + { + str = DateUtils.parseDateToStr(dateFormat, DateUtils.toDate((LocalDate) val)); + } + else + { + str = val.toString(); + } + return str; + } + + /** + * 是否有对象的子列表 + */ + public boolean isSubList() + { + return StringUtils.isNotNull(subFields) && subFields.size() > 0; + } + + /** + * 是否有对象的子列表,集合不为空 + */ + public boolean isSubListValue(T vo) + { + return StringUtils.isNotNull(subFields) && subFields.size() > 0 && StringUtils.isNotNull(getListCellValue(vo)) && getListCellValue(vo).size() > 0; + } + + /** + * 获取集合的值 + */ + public Collection getListCellValue(Object obj) + { + Object value; + try + { + value = subMethod.invoke(obj, new Object[] {}); + } + catch (Exception e) + { + return new ArrayList(); + } + return (Collection) value; + } + + /** + * 获取对象的子列表方法 + * + * @param name 名称 + * @param pojoClass 类对象 + * @return 子列表方法 + */ + public Method getSubMethod(String name, Class pojoClass) + { + StringBuffer getMethodName = new StringBuffer("get"); + getMethodName.append(name.substring(0, 1).toUpperCase()); + getMethodName.append(name.substring(1)); + Method method = null; + try + { + method = pojoClass.getMethod(getMethodName.toString(), new Class[] {}); + } + catch (Exception e) + { + log.error("获取对象异常{}", e.getMessage()); + } + return method; + } +} diff --git a/evo-admin/src/main/java/com/evo/common/utils/poi/handler/ExcelFieldHandlerAdapter.java b/evo-admin/src/main/java/com/evo/common/utils/poi/handler/ExcelFieldHandlerAdapter.java new file mode 100644 index 0000000..5b4e2b7 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/utils/poi/handler/ExcelFieldHandlerAdapter.java @@ -0,0 +1,20 @@ +package com.evo.common.utils.poi.handler; + +import com.evo.common.annotation.Excel; + +import java.lang.reflect.Field; +import java.util.List; + +/** + * 特殊出具处理接口 + * + * @ClassName:ExcelFieldHandlerAdapter + * @date: 2025年07月12日 10:40 + * @author: andy.shi + * @contact: 17330188597 + * @remark: 开发人员联系方式 1042025947@qq.com/微信同步 + */ +public interface ExcelFieldHandlerAdapter { + + List buildExcel(); +} diff --git a/evo-admin/src/main/java/com/evo/common/utils/poi/ExcelHandlerAdapter.java b/evo-admin/src/main/java/com/evo/common/utils/poi/handler/ExcelHandlerAdapter.java similarity index 92% rename from evo-admin/src/main/java/com/evo/common/utils/poi/ExcelHandlerAdapter.java rename to evo-admin/src/main/java/com/evo/common/utils/poi/handler/ExcelHandlerAdapter.java index c911b71..e90efde 100644 --- a/evo-admin/src/main/java/com/evo/common/utils/poi/ExcelHandlerAdapter.java +++ b/evo-admin/src/main/java/com/evo/common/utils/poi/handler/ExcelHandlerAdapter.java @@ -1,4 +1,4 @@ -package com.evo.common.utils.poi; +package com.evo.common.utils.poi.handler; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Workbook; diff --git a/evo-admin/src/main/java/com/evo/common/utils/poi/handler/impl/SysStaffExcelFieldHandlerAdapter.java b/evo-admin/src/main/java/com/evo/common/utils/poi/handler/impl/SysStaffExcelFieldHandlerAdapter.java new file mode 100644 index 0000000..b89caef --- /dev/null +++ b/evo-admin/src/main/java/com/evo/common/utils/poi/handler/impl/SysStaffExcelFieldHandlerAdapter.java @@ -0,0 +1,30 @@ +package com.evo.common.utils.poi.handler.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.evo.common.constant.Constants; +import com.evo.common.utils.Collections; +import com.evo.common.utils.poi.handler.ExcelFieldHandlerAdapter; +import com.evo.common.utils.spring.SpringUtils; +import com.evo.personnelMatters.domain.RzSubsidyInfo; +import com.evo.personnelMatters.mapper.RzSubsidyInfoMapper; + +import java.lang.reflect.Field; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 类 + * + * @ClassName:SysStaffExcelFieldHandlerAdapter + * @date: 2025年07月12日 10:42 + * @author: andy.shi + * @contact: 17330188597 + * @remark: 开发人员联系方式 1042025947@qq.com/微信同步 + */ + +public class SysStaffExcelFieldHandlerAdapter implements ExcelFieldHandlerAdapter { + @Override + public List buildExcel() { + return SpringUtils.getBean(RzSubsidyInfoMapper.class).selectList(new LambdaQueryWrapper().eq(RzSubsidyInfo::getDelFlag, Constants.DELETE_FLAG_0)).stream().map(RzSubsidyInfo::getName).collect(Collectors.toList()); + } +} diff --git a/evo-admin/src/main/java/com/evo/kingdeeUtils/KingdeeRequestUtils.java b/evo-admin/src/main/java/com/evo/kingdeeUtils/KingdeeRequestUtils.java new file mode 100644 index 0000000..b5201bb --- /dev/null +++ b/evo-admin/src/main/java/com/evo/kingdeeUtils/KingdeeRequestUtils.java @@ -0,0 +1,109 @@ +package com.evo.kingdeeUtils; + +import com.alibaba.fastjson2.JSON; +import com.evo.common.utils.DateUtils; +import com.evo.common.utils.spring.SpringUtils; +import com.evo.kingdeeUtils.exception.KingdeeException; +import com.evo.kingdeeUtils.kenum.BaseEnum; +import com.evo.kingdeeUtils.kenum.KingdeeParamsEnum; +import com.evo.kingdeeUtils.mapper.LogKingDeeMapper; +import com.evo.kingdeeUtils.vo.LogKingDee; +import com.kingdee.bos.webapi.sdk.K3CloudApi; +import lombok.extern.slf4j.Slf4j; + +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * 类 + * + * @ClassName:KingdeeRequestUtils + * @date: 2025年07月11日 9:33 + * @author: andy.shi + * @contact: 17330188597 + * @remark: 开发人员联系方式 1042025947@qq.com/微信同步 + */ + +@Slf4j +public class KingdeeRequestUtils { + + /*** + * 员工保存接口 + * @param params + * 参数说明对照关系: key-value + * FName-员工姓名 + * FStaffNumber-员工编号 + * FNumber-岗位编号 + * FPostDept_FNumber_岗位所属部门编号 + */ + public static void employeeSave(Map params){ +// request(params, KingdeeParamsEnum.Employee.SAVE); + } + + /*** + * 员工禁用接口 + * @param params + * 参数说明对照关系: key-value + * Numbers-员工编码 (多个使用,分割, 即: 001,002,003) + */ + public static void employeeDisabled(Map params){ +// request(params, KingdeeParamsEnum.Employee.DISABLED); + } + + /*** + * 岗位调整 + * @param params + * 参数说明对照关系: key-value + * NeedUpDateFields-更新字段 (多个使用,分割, 如:FDept_FNumber,FPosition_FNumber ) + * FNumber-员工编号 + * FDept_FNumber-部门编号 + * FPosition_FNumber-岗位编号 + */ + public static void updateJobInfo(Map params){ +// request(params, KingdeeParamsEnum.JobInfo.UPDATE); + } + + private static void request(Map params, BaseEnum paramEnum){ + log.error("{}====> 接口调用, 参数为:{} ", paramEnum.getDes(), JSON.toJSONString(params)); + List keyList = params.entrySet().stream().map(Map.Entry::getKey).collect(Collectors.toList()); + Map requiredParams = paramEnum.getRequiredParams(); + for (String key : requiredParams.keySet()){ + if(!keyList.contains(key)){ + throw new KingdeeException(requiredParams.get(key)); + } + } + String requestParam = paramEnum.getParamJson(); + for (String key : params.keySet()){ + requestParam = requestParam.replaceAll(key+ KingdeeParamsEnum.REQUEST_PARAM_SUFFIX, params.get(key)); + } + //更新时间 + requestParam = requestParam.replaceAll("date"+KingdeeParamsEnum.REQUEST_PARAM_SUFFIX, DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss", new Date())); + String resultJson = ""; + try { + K3CloudApi client = new K3CloudApi(); + resultJson = client.save(paramEnum.getFromId(), requestParam); + log.info("{}====>接口返回结果: {}", paramEnum.getDes(), resultJson); + + } catch (Exception e) { + resultJson = e.getMessage(); + log.error("{}====>请求错误: {}", paramEnum.getDes(), e.getMessage()); + }finally { + //记录日志 + instLog(paramEnum, params, requestParam, resultJson); + } + } + + + private static void instLog(BaseEnum paramEnum, Map params, String requestInfo, String response){ + LogKingDee logKingDee = new LogKingDee(); + logKingDee.setRequestTime(new Date()); + logKingDee.setType(paramEnum.getDes()); + logKingDee.setRequestParams(JSON.toJSONString(params)); + logKingDee.setRequestInfo(requestInfo); + logKingDee.setResponse(response); + SpringUtils.getBean(LogKingDeeMapper.class).insert(logKingDee); + } + +} diff --git a/evo-admin/src/main/java/com/evo/kingdeeUtils/exception/KingdeeException.java b/evo-admin/src/main/java/com/evo/kingdeeUtils/exception/KingdeeException.java new file mode 100644 index 0000000..c7fdab4 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/kingdeeUtils/exception/KingdeeException.java @@ -0,0 +1,29 @@ +package com.evo.kingdeeUtils.exception; + +import lombok.extern.slf4j.Slf4j; + +/** + * 类 + * + * @ClassName:KingdeeException + * @date: 2025年07月11日 10:02 + * @author: andy.shi + * @contact: 17330188597 + * @remark: 开发人员联系方式 1042025947@qq.com/微信同步 + */ +@Slf4j +public class KingdeeException extends RuntimeException{ + + public KingdeeException(String message){ + super(message); + log.error("推送金蝶出现错误---->>>>>>>{}", message); + } + + + public KingdeeException(String message, Throwable e) + { + super(message, e); + log.error("推送金蝶出现错误---->>>>>>>错误信息{}, 异常信息:{}", message, e.getMessage()); + } + +} diff --git a/evo-admin/src/main/java/com/evo/kingdeeUtils/kenum/BaseEnum.java b/evo-admin/src/main/java/com/evo/kingdeeUtils/kenum/BaseEnum.java new file mode 100644 index 0000000..ff2dd55 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/kingdeeUtils/kenum/BaseEnum.java @@ -0,0 +1,24 @@ +package com.evo.kingdeeUtils.kenum; + +import java.util.Map; + +/** + * 枚举 + * @ClassName:BaseEnum + * @date: 2025年07月11日 10:26 + * @author: andy.shi + * @contact: 17330188597 + * @remark: 开发人员联系方式 1042025947@qq.com/微信同步 + */ +public interface BaseEnum { + + + + abstract Map getRequiredParams(); + + abstract String getParamJson(); + + abstract String getFromId(); + + abstract String getDes(); +} diff --git a/evo-admin/src/main/java/com/evo/kingdeeUtils/kenum/KingdeeParamsEnum.java b/evo-admin/src/main/java/com/evo/kingdeeUtils/kenum/KingdeeParamsEnum.java new file mode 100644 index 0000000..1335b0d --- /dev/null +++ b/evo-admin/src/main/java/com/evo/kingdeeUtils/kenum/KingdeeParamsEnum.java @@ -0,0 +1,97 @@ +package com.evo.kingdeeUtils.kenum; + +import com.evo.common.utils.Collections; + +import java.util.Map; + +/** + * 金蝶请求的参数类枚举 + * + * @ClassName:KingdeeRequest + * @date: 2025年07月11日 8:59 + * @author: andy.shi + * @contact: 17330188597 + * @remark: 开发人员联系方式 1042025947@qq.com/微信同步 + */ +public enum KingdeeParamsEnum { + + ; + + Enum paramEnum; + + + KingdeeParamsEnum() { + } + + KingdeeParamsEnum(Enum paramEnum) { + this.paramEnum = paramEnum; + } + + public static final String REQUEST_PARAM_SUFFIX="_param"; + + public enum JobInfo implements BaseEnum{ + UPDATE("岗位信息修改", "BD_NEWSTAFF", Collections.asMap("FNumber","员工编号不能为空","FDept_FNumber","部门编号不能为空","FPosition_FNumber","岗位编号不能为空"),"{\"NeedUpDateFields\":[NeedUpDateFields"+REQUEST_PARAM_SUFFIX+"],\"NeedReturnFields\":[],\"IsDeleteEntry\":\"true\",\"SubSystemId\":\"\",\"IsVerifyBaseDataField\":\"false\",\"IsEntryBatchFill\":\"true\",\"ValidateFlag\":\"true\",\"NumberSearch\":\"true\",\"IsAutoAdjustField\":\"true\",\"InterationFlags\":\"\",\"IgnoreInterationFlag\":\"\",\"IsControlPrecision\":\"false\",\"ValidateRepeatJson\":\"false\",\"Model\":{\"FSTAFFID\":0,\"FNumber\":\"FNumber"+REQUEST_PARAM_SUFFIX+"\",\"FPerson\":{\"FNumber\":\"FNumber"+REQUEST_PARAM_SUFFIX+"\"},\"FDept\":{\"FNumber\":\"FDept_FNumber"+REQUEST_PARAM_SUFFIX+"\"},\"FPosition\":{\"FNumber\":\"FPosition_FNumber"+REQUEST_PARAM_SUFFIX+"\"},\"FStartDate\":\"date"+REQUEST_PARAM_SUFFIX+"\",\"FEmpInfoId\":{\"FNumber\":\"FNumber"+REQUEST_PARAM_SUFFIX+"\"},\"FPOSTBILLEntity\":{\"FIsFirstPost\":false},\"FOtherEntity\":{},\"FSHRMapEntity\":{}}}"), + ; + String des; + String fromId; + Map requiredParams; + String paramJson; + JobInfo(String des, String fromId, Map requiredParams, String paramJson) { + this.des = des; + this.fromId = fromId; + this.requiredParams = requiredParams; + this.paramJson = paramJson; + } + @Override + public Map getRequiredParams() { + return this.requiredParams; + } + @Override + public String getParamJson() { + return this.paramJson; + } + @Override + public String getFromId() { + return this.fromId; + } + @Override + public String getDes() { + return this.des; + } + } + /*** + * 金蝶请求参数, 员工 + */ + public enum Employee implements BaseEnum { + SAVE("员工保存", "BD_Empinfo", Collections.asMap("FName","员工姓名不能为空","FStaffNumber","员工编号不能为空","FNumber","岗位编号不能为空"),"{\"NeedUpDateFields\":[],\"NeedReturnFields\":[],\"IsDeleteEntry\":\"true\",\"SubSystemId\":\"\",\"IsVerifyBaseDataField\":\"false\",\"IsEntryBatchFill\":\"true\",\"ValidateFlag\":\"true\",\"NumberSearch\":\"true\",\"IsAutoAdjustField\":\"true\",\"InterationFlags\":\"\",\"IgnoreInterationFlag\":\"\",\"IsControlPrecision\":\"false\",\"ValidateRepeatJson\":\"false\",\"Model\":{\"FID\":0,\"FName\":\"FName"+REQUEST_PARAM_SUFFIX+"\",\"FStaffNumber\":\"FStaffNumber"+REQUEST_PARAM_SUFFIX+"\",\"FCreateSaler\":false,\"FCreateUser\":false,\"FCreateCashier\":false,\"FJoinDate\":\"date"+REQUEST_PARAM_SUFFIX+"\",\"FSHRMapEntity\":{},\"FPostEntity\":[{\"FPostDept\":{\"FNumber\":\"FPostDept_FNumber"+REQUEST_PARAM_SUFFIX+"\"},\"FPost\":{\"FNumber\":\"FNumber"+REQUEST_PARAM_SUFFIX+"\"},\"FStaffStartDate\":\"date"+REQUEST_PARAM_SUFFIX+"\",\"FIsFirstPost\":true,\"FStaffDetails\":0}]}}"), + DISABLED("员工禁用","BD_Empinfo", Collections.asMap("Numbers","员工编码不能为空"),"{\"Numbers\":[Numbers"+REQUEST_PARAM_SUFFIX+"],\"Ids\":\"\",\"PkEntryIds\":[],\"UseOrgId\":0,\"NetworkCtrl\":\"\",\"IgnoreInterationFlag\":\"\"}") + ; + String des; + String fromId; + Map requiredParams; + String paramJson; + Employee(String des, String fromId, Map requiredParams, String paramJson) { + this.des = des; + this.fromId = fromId; + this.requiredParams = requiredParams; + this.paramJson = paramJson; + } + @Override + public Map getRequiredParams() { + return this.requiredParams; + } + @Override + public String getParamJson() { + return this.paramJson; + } + @Override + public String getFromId() { + return this.fromId; + } + @Override + public String getDes() { + return this.des; + } + } + +} diff --git a/evo-admin/src/main/java/com/evo/kingdeeUtils/mapper/LogKingDeeMapper.java b/evo-admin/src/main/java/com/evo/kingdeeUtils/mapper/LogKingDeeMapper.java new file mode 100644 index 0000000..d8a406f --- /dev/null +++ b/evo-admin/src/main/java/com/evo/kingdeeUtils/mapper/LogKingDeeMapper.java @@ -0,0 +1,16 @@ +package com.evo.kingdeeUtils.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.evo.kingdeeUtils.vo.LogKingDee; + +/** + * 金蝶日志请求接口 + * + * @ClassName:LogKingDeeMapper + * @date: 2025年07月11日 11:18 + * @author: andy.shi + * @contact: 17330188597 + * @remark: 开发人员联系方式 1042025947@qq.com/微信同步 + */ +public interface LogKingDeeMapper extends BaseMapper { +} diff --git a/evo-admin/src/main/java/com/evo/kingdeeUtils/vo/LogKingDee.java b/evo-admin/src/main/java/com/evo/kingdeeUtils/vo/LogKingDee.java new file mode 100644 index 0000000..b7042de --- /dev/null +++ b/evo-admin/src/main/java/com/evo/kingdeeUtils/vo/LogKingDee.java @@ -0,0 +1,38 @@ +package com.evo.kingdeeUtils.vo; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +/** + * 请求日志类 + * + * @ClassName:LogKingDee + * @date: 2025年07月11日 11:15 + * @author: andy.shi + * @contact: 17330188597 + * @remark: 开发人员联系方式 1042025947@qq.com/微信同步 + */ +@Data +@TableName("sys_log_king_dee") +public class LogKingDee implements Serializable { + + /** 主键 */ + @TableId(type= IdType.AUTO) + private Long id; + + private String type; + + private String requestParams; + + private String requestInfo; + + private String response; + + private Date requestTime; + +} diff --git a/evo-admin/src/main/java/com/evo/personnelMatters/controller/RzSubsidyInfoController.java b/evo-admin/src/main/java/com/evo/personnelMatters/controller/RzSubsidyInfoController.java index b786cd3..378c9aa 100644 --- a/evo-admin/src/main/java/com/evo/personnelMatters/controller/RzSubsidyInfoController.java +++ b/evo-admin/src/main/java/com/evo/personnelMatters/controller/RzSubsidyInfoController.java @@ -6,10 +6,8 @@ import com.evo.common.core.domain.AjaxResult; import com.evo.common.core.page.TableDataInfo; import com.evo.common.enums.BusinessType; import com.evo.common.utils.poi.ExcelUtil; -import com.evo.personnelMatters.domain.RzSubsidy; import com.evo.personnelMatters.domain.RzSubsidyInfo; import com.evo.personnelMatters.service.IRzSubsidyInfoService; -import com.evo.personnelMatters.service.IRzSubsidyService; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; diff --git a/evo-admin/src/main/java/com/evo/personnelMatters/domain/RzSubsidyInfo.java b/evo-admin/src/main/java/com/evo/personnelMatters/domain/RzSubsidyInfo.java index 55b31cb..5eee152 100644 --- a/evo-admin/src/main/java/com/evo/personnelMatters/domain/RzSubsidyInfo.java +++ b/evo-admin/src/main/java/com/evo/personnelMatters/domain/RzSubsidyInfo.java @@ -1,5 +1,7 @@ package com.evo.personnelMatters.domain; +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; import com.evo.common.annotation.Excel; import com.evo.common.core.domain.BaseEntity; import lombok.Data; @@ -39,6 +41,7 @@ public class RzSubsidyInfo extends BaseEntity private String remarks; /** 删除标识 */ + @TableField(fill = FieldFill.INSERT) private String delFlag; @Override diff --git a/evo-admin/src/main/java/com/evo/system/controller/SysStaffController.java b/evo-admin/src/main/java/com/evo/system/controller/SysStaffController.java index aa70fa0..b853f2b 100644 --- a/evo-admin/src/main/java/com/evo/system/controller/SysStaffController.java +++ b/evo-admin/src/main/java/com/evo/system/controller/SysStaffController.java @@ -52,9 +52,9 @@ public class SysStaffController extends BaseController @PostMapping("/export") public void export(HttpServletResponse response, SysStaff sysStaff) { - List list = sysStaffService.selectSysStaffList(sysStaff); - ExcelUtil util = new ExcelUtil(SysStaff.class); - util.exportExcel(response, list, "员工管理数据"); + sysStaffService.exportInfo(response, sysStaff); +// ExcelUtil util = new ExcelUtil(SysStaff.class); +// util.exportExcel(response, list, "员工管理数据"); } /** * 导出员工详情 @@ -63,9 +63,11 @@ public class SysStaffController extends BaseController @PostMapping("/exportDetail") public void exportDetail(HttpServletResponse response, SysStaff sysStaff) { - List list = sysStaffService.selectSysStaffDetailList(sysStaff); - ExcelUtil util = new ExcelUtil(SysStaffVo.class); - util.exportExcel(response, list, "员工详情数据"); + + sysStaffService.exportInfo(response, sysStaff); +// List list = sysStaffService.selectSysStaffDetailList(sysStaff); +// ExcelUtil util = new ExcelUtil(SysStaffVo.class); +// util.exportExcel(response, list, "员工详情数据"); } /** * 获取员工管理详细信息 diff --git a/evo-admin/src/main/java/com/evo/system/domain/SysStaff.java b/evo-admin/src/main/java/com/evo/system/domain/SysStaff.java index 7970078..82371b2 100644 --- a/evo-admin/src/main/java/com/evo/system/domain/SysStaff.java +++ b/evo-admin/src/main/java/com/evo/system/domain/SysStaff.java @@ -47,6 +47,8 @@ public class SysStaff extends BaseEntity @TableField(exist = false) private String deptName; + private String jobCode; + /** 身份证号 */ @Excel(name = "身份证号") private String idCard; diff --git a/evo-admin/src/main/java/com/evo/system/domain/vo/SysStaffVo.java b/evo-admin/src/main/java/com/evo/system/domain/vo/SysStaffVo.java index af3ae11..7e64fa9 100644 --- a/evo-admin/src/main/java/com/evo/system/domain/vo/SysStaffVo.java +++ b/evo-admin/src/main/java/com/evo/system/domain/vo/SysStaffVo.java @@ -1,769 +1,125 @@ package com.evo.system.domain.vo; import com.evo.common.annotation.Excel; +import com.evo.common.utils.poi.handler.impl.SysStaffExcelFieldHandlerAdapter; import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; + import java.math.BigDecimal; import java.util.Date; +import java.util.Map; +@Data public class SysStaffVo { - /** 姓名 */ @Excel(name = "* 姓名") private String name; + @Excel(name = "* 公司", dictType = "sys_company") + private String companyName; @Excel(name = "* 部门") private String deptName; - /** 编号 */ @Excel(name = "编号") private String code; - /** 身份证号 */ @Excel(name = "* 身份证号") private String idCard; - /** 性别 */ - @Excel(name = "性别") + @Excel(name = "性别", dictType = "sys_user_sex") private String sex; - /** 年龄 */ @Excel(name = "年龄") private Long age; - /** 电话 */ @Excel(name = "电话") private String phone; - /** 住址 */ @Excel(name = "住址") private String address; - /** 学历 */ - @Excel(name = "* 学历") + @Excel(name = "* 学历", dictType = "sys_level") private String level; - /** 专业 */ - @Excel(name = "专业") - private String major; - /** 毕业学校 */ @Excel(name = "毕业学校") private String school; - /** 银行卡号 */ - @Excel(name = "银行卡号") - private String bankNumber; - /** 开户行 */ + @Excel(name = "专业") + private String major; @Excel(name = "开户行") private String bank; - /** 入职时间 */ + @Excel(name = "银行卡号") + private String bankNumber; + + @Excel(name = "在职状态", dictType = "sys_worker_status") + private String status; @JsonFormat(pattern = "yyyy-MM-dd") @Excel(name = " * 入职时间", width = 30, dateFormat = "yyyy-MM-dd") private Date employmentDate; - /** 全额工资时间 */ - @JsonFormat(pattern = "yyyy-MM-dd") - @Excel(name = "全额工资时间", width = 30, dateFormat = "yyyy-MM-dd") - private Date wagesRatioDate; - /** 履历 */ - @Excel(name = "履历") - private String experience; - /** 试用期限 */ @Excel(name = "试用期限") private Long workerTerm; - /** 转正日期 */ @JsonFormat(pattern = "yyyy-MM-dd") @Excel(name = "转正日期", width = 30, dateFormat = "yyyy-MM-dd") private Date regularDate; - /** 离职时间 */ @JsonFormat(pattern = "yyyy-MM-dd") @Excel(name = "离职时间", width = 30, dateFormat = "yyyy-MM-dd") private Date quitDate; - /** 合同-起 */ @JsonFormat(pattern = "yyyy-MM-dd") @Excel(name = "合同-起", width = 30, dateFormat = "yyyy-MM-dd") private Date contractStart; - /** 合同-止 */ @JsonFormat(pattern = "yyyy-MM-dd") @Excel(name = "合同-止", width = 30, dateFormat = "yyyy-MM-dd") private Date contractEnd; - /** 合同类型 */ - @Excel(name = "* 合同期限") - private String contractType; @Excel(name = "* 是否新农合") private String socialSubsidy; - /** 社保 */ @Excel(name = "* 社保") private String socialType; - /** 工龄 */ @Excel(name = "工龄") private Long seniority; - - /** 是否有加班费 */ - @Excel(name = "* 加班费") - private String isOvertimePay; - /** 住宿标识 */ - @Excel(name = "* 住宿") + @Excel(name = "* 是否住宿") private String zsFlag; - /** 保密合同 */ - @Excel(name = "保密合同") - private String secrecy; - /** 工伤 */ - @Excel(name = "工伤") + @Excel(name = "工伤险") private String injury; - /** 雇主险 */ @Excel(name = "雇主险") private String insurance; - /** 介绍人 */ - @Excel(name = "介绍人") - private String introducer; - /** 是否打卡 */ - @Excel(name = "* 打卡") + @Excel(name = "* 是否打卡") private String clockIn; - /** 在职状态 */ - @Excel(name = "在职状态") - private String status; - @Excel(name = "* 公司") - private String companyName; + + @Excel(name = "基本工资") private BigDecimal basicSalary; - /** 岗位工资 */ @Excel(name = "岗位工资") private BigDecimal jobsSalary; - /** 日薪 */ @Excel(name = "日薪") private BigDecimal dailyWage; - /** 时薪 */ - @Excel(name = "时薪") - private BigDecimal hoursSalary; - /** 全勤奖 */ - @Excel(name = "全勤奖") - private BigDecimal fullFrequentlySubsidies; - /** 学历补助 */ - @Excel(name = "学历补助") - private BigDecimal levelOfEducationSubsidies; - /** 合同补助 */ - @Excel(name = "合同补助") - private BigDecimal contractSubsidies; - /** 工龄补助 */ - @Excel(name = "工龄补助") - private BigDecimal senioritySubsidies; - /** 社保补助 */ - @Excel(name = "社保补助") - private BigDecimal socialSecuritySubsidies; - - @Excel(name = "中班补助") - private BigDecimal middleSubsidies; - /** 夜班补助 */ - @Excel(name = "夜班补助") - private BigDecimal nightShiftSubsidies; - /** 夜餐补助 */ - @Excel(name = "夜餐补助") - private BigDecimal dinnerSubsidies; - /** 固定补助 */ + @Excel(name = "享有补助", customExcelField = true, excelFieldHandler= SysStaffExcelFieldHandlerAdapter.class, defaultValue = "0") + private Map subsidyMap; @Excel(name = "固定补助") private BigDecimal fixedAllowance; - /** 其他补助 */ - @Excel(name = "其他补助") - private BigDecimal otherSubsidies; - /** 早餐消费 */ - @Excel(name = "早餐消费") - private BigDecimal breakfastExpend; - /** 午餐消费 */ - @Excel(name = "午餐消费") - private BigDecimal lunchExpend; - /** 晚餐消费 */ - @Excel(name = "晚餐消费") - private BigDecimal supperExpend; - /** 离职扣款 */ - @Excel(name = "离职扣款") - private BigDecimal subsidyDeductMoney; - /** 其他扣款 */ - @Excel(name = "其他扣款") - private BigDecimal deductions; - /** 养老保险 */ + @Excel(name = "养老保险") private BigDecimal endowmentInsurance; - /** 医疗保险 */ @Excel(name = "医疗保险") private BigDecimal medicalInsurance; - /** 工伤保险 */ @Excel(name = "工伤保险") private BigDecimal employmentInjuryInsurance; - /** 生育保险 */ @Excel(name = "生育保险") private BigDecimal maternityInsurance; - /** 失业保险 */ @Excel(name = "失业保险") private BigDecimal unemploymentInsurance; - /** 公积金 */ @Excel(name = "公积金") private BigDecimal accumulationFund; - /** 子女教育 */ + @Excel(name = "子女教育") private BigDecimal childrenEducation; - /** 赡养老人 */ @Excel(name = "赡养老人") private BigDecimal supportTheOld; - /** 住房贷款 */ @Excel(name = "住房贷款") private BigDecimal housingLoans; - /** 住房租金 */ @Excel(name = "住房租金") private BigDecimal housingRents; - /** 继续教育 */ @Excel(name = "继续教育") private BigDecimal adultEducation; - /** 大病医疗 */ @Excel(name = "大病医疗") private BigDecimal treatmentForSeriousDisease; - /** 本年累计专项附加扣除 */ + @Excel(name = "本年累计专项附加扣除") private BigDecimal specialDeduction; - /** 本年累计已发工资 */ @Excel(name = "本年累计已发工资") private BigDecimal totalWages; - /** 本年累计已缴个税 */ @Excel(name = "本年累计已缴个税") private BigDecimal aggregatePersonalIncomeTax; - /** 备注 */ + @Excel(name = "备注") private String remarks; - public String getSocialSubsidy() { - return socialSubsidy; - } - - public void setSocialSubsidy(String socialSubsidy) { - this.socialSubsidy = socialSubsidy; - } - - public BigDecimal getMiddleSubsidies() { - return middleSubsidies; - } - - public void setMiddleSubsidies(BigDecimal middleSubsidies) { - this.middleSubsidies = middleSubsidies; - } - - public String getCompanyName() { - return companyName; - } - - public void setCompanyName(String companyName) { - this.companyName = companyName; - } - - public String getDeptName() { - return deptName; - } - - public void setDeptName(String deptName) { - this.deptName = deptName; - } - - public String getCode() { - return code; - } - - public void setCode(String code) { - this.code = code; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getIdCard() { - return idCard; - } - - public void setIdCard(String idCard) { - this.idCard = idCard; - } - - public String getSex() { - return sex; - } - - public void setSex(String sex) { - this.sex = sex; - } - - public Long getAge() { - return age; - } - - public void setAge(Long age) { - this.age = age; - } - - public String getPhone() { - return phone; - } - - public void setPhone(String phone) { - this.phone = phone; - } - - public String getAddress() { - return address; - } - - public void setAddress(String address) { - this.address = address; - } - - public String getLevel() { - return level; - } - - public void setLevel(String level) { - this.level = level; - } - - public String getMajor() { - return major; - } - - public void setMajor(String major) { - this.major = major; - } - - public String getSchool() { - return school; - } - - public void setSchool(String school) { - this.school = school; - } - - public String getBankNumber() { - return bankNumber; - } - - public void setBankNumber(String bankNumber) { - this.bankNumber = bankNumber; - } - - public String getBank() { - return bank; - } - - public void setBank(String bank) { - this.bank = bank; - } - - public Date getEmploymentDate() { - return employmentDate; - } - - public void setEmploymentDate(Date employmentDate) { - this.employmentDate = employmentDate; - } - - public Date getWagesRatioDate() { - return wagesRatioDate; - } - - public void setWagesRatioDate(Date wagesRatioDate) { - this.wagesRatioDate = wagesRatioDate; - } - - public String getExperience() { - return experience; - } - - public void setExperience(String experience) { - this.experience = experience; - } - - public Long getWorkerTerm() { - return workerTerm; - } - - public void setWorkerTerm(Long workerTerm) { - this.workerTerm = workerTerm; - } - - public Date getRegularDate() { - return regularDate; - } - - public void setRegularDate(Date regularDate) { - this.regularDate = regularDate; - } - - public Date getQuitDate() { - return quitDate; - } - - public void setQuitDate(Date quitDate) { - this.quitDate = quitDate; - } - - public Date getContractStart() { - return contractStart; - } - - public void setContractStart(Date contractStart) { - this.contractStart = contractStart; - } - - public Date getContractEnd() { - return contractEnd; - } - - public void setContractEnd(Date contractEnd) { - this.contractEnd = contractEnd; - } - - public String getContractType() { - return contractType; - } - - public void setContractType(String contractType) { - this.contractType = contractType; - } - - public String getSocialType() { - return socialType; - } - - public void setSocialType(String socialType) { - this.socialType = socialType; - } - - public Long getSeniority() { - return seniority; - } - - public void setSeniority(Long seniority) { - this.seniority = seniority; - } - - public String getIsOvertimePay() { - return isOvertimePay; - } - - public void setIsOvertimePay(String isOvertimePay) { - this.isOvertimePay = isOvertimePay; - } - - public String getZsFlag() { - return zsFlag; - } - - public void setZsFlag(String zsFlag) { - this.zsFlag = zsFlag; - } - - public String getSecrecy() { - return secrecy; - } - - public void setSecrecy(String secrecy) { - this.secrecy = secrecy; - } - - public String getInjury() { - return injury; - } - - public void setInjury(String injury) { - this.injury = injury; - } - - public String getInsurance() { - return insurance; - } - - public void setInsurance(String insurance) { - this.insurance = insurance; - } - - public String getIntroducer() { - return introducer; - } - - public void setIntroducer(String introducer) { - this.introducer = introducer; - } - - public String getClockIn() { - return clockIn; - } - - public void setClockIn(String clockIn) { - this.clockIn = clockIn; - } - - public String getStatus() { - return status; - } - - public void setStatus(String status) { - this.status = status; - } - - public BigDecimal getBasicSalary() { - return basicSalary; - } - - public void setBasicSalary(BigDecimal basicSalary) { - this.basicSalary = basicSalary; - } - - public BigDecimal getJobsSalary() { - return jobsSalary; - } - - public void setJobsSalary(BigDecimal jobsSalary) { - this.jobsSalary = jobsSalary; - } - - public BigDecimal getDailyWage() { - return dailyWage; - } - - public void setDailyWage(BigDecimal dailyWage) { - this.dailyWage = dailyWage; - } - - public BigDecimal getHoursSalary() { - return hoursSalary; - } - - public void setHoursSalary(BigDecimal hoursSalary) { - this.hoursSalary = hoursSalary; - } - - public BigDecimal getFullFrequentlySubsidies() { - return fullFrequentlySubsidies; - } - - public void setFullFrequentlySubsidies(BigDecimal fullFrequentlySubsidies) { - this.fullFrequentlySubsidies = fullFrequentlySubsidies; - } - - public BigDecimal getLevelOfEducationSubsidies() { - return levelOfEducationSubsidies; - } - - public void setLevelOfEducationSubsidies(BigDecimal levelOfEducationSubsidies) { - this.levelOfEducationSubsidies = levelOfEducationSubsidies; - } - - public BigDecimal getContractSubsidies() { - return contractSubsidies; - } - - public void setContractSubsidies(BigDecimal contractSubsidies) { - this.contractSubsidies = contractSubsidies; - } - - public BigDecimal getSenioritySubsidies() { - return senioritySubsidies; - } - - public void setSenioritySubsidies(BigDecimal senioritySubsidies) { - this.senioritySubsidies = senioritySubsidies; - } - - public BigDecimal getSocialSecuritySubsidies() { - return socialSecuritySubsidies; - } - - public void setSocialSecuritySubsidies(BigDecimal socialSecuritySubsidies) { - this.socialSecuritySubsidies = socialSecuritySubsidies; - } - - public BigDecimal getNightShiftSubsidies() { - return nightShiftSubsidies; - } - - public void setNightShiftSubsidies(BigDecimal nightShiftSubsidies) { - this.nightShiftSubsidies = nightShiftSubsidies; - } - - public BigDecimal getDinnerSubsidies() { - return dinnerSubsidies; - } - - public void setDinnerSubsidies(BigDecimal dinnerSubsidies) { - this.dinnerSubsidies = dinnerSubsidies; - } - - public BigDecimal getFixedAllowance() { - return fixedAllowance; - } - - public void setFixedAllowance(BigDecimal fixedAllowance) { - this.fixedAllowance = fixedAllowance; - } - - public BigDecimal getOtherSubsidies() { - return otherSubsidies; - } - - public void setOtherSubsidies(BigDecimal otherSubsidies) { - this.otherSubsidies = otherSubsidies; - } - - public BigDecimal getBreakfastExpend() { - return breakfastExpend; - } - - public void setBreakfastExpend(BigDecimal breakfastExpend) { - this.breakfastExpend = breakfastExpend; - } - - public BigDecimal getLunchExpend() { - return lunchExpend; - } - - public void setLunchExpend(BigDecimal lunchExpend) { - this.lunchExpend = lunchExpend; - } - - public BigDecimal getSupperExpend() { - return supperExpend; - } - - public void setSupperExpend(BigDecimal supperExpend) { - this.supperExpend = supperExpend; - } - - public BigDecimal getSubsidyDeductMoney() { - return subsidyDeductMoney; - } - - public void setSubsidyDeductMoney(BigDecimal subsidyDeductMoney) { - this.subsidyDeductMoney = subsidyDeductMoney; - } - - public BigDecimal getDeductions() { - return deductions; - } - - public void setDeductions(BigDecimal deductions) { - this.deductions = deductions; - } - - public BigDecimal getEndowmentInsurance() { - return endowmentInsurance; - } - - public void setEndowmentInsurance(BigDecimal endowmentInsurance) { - this.endowmentInsurance = endowmentInsurance; - } - - public BigDecimal getMedicalInsurance() { - return medicalInsurance; - } - - public void setMedicalInsurance(BigDecimal medicalInsurance) { - this.medicalInsurance = medicalInsurance; - } - - public BigDecimal getEmploymentInjuryInsurance() { - return employmentInjuryInsurance; - } - - public void setEmploymentInjuryInsurance(BigDecimal employmentInjuryInsurance) { - this.employmentInjuryInsurance = employmentInjuryInsurance; - } - - public BigDecimal getMaternityInsurance() { - return maternityInsurance; - } - - public void setMaternityInsurance(BigDecimal maternityInsurance) { - this.maternityInsurance = maternityInsurance; - } - - public BigDecimal getUnemploymentInsurance() { - return unemploymentInsurance; - } - - public void setUnemploymentInsurance(BigDecimal unemploymentInsurance) { - this.unemploymentInsurance = unemploymentInsurance; - } - - public BigDecimal getAccumulationFund() { - return accumulationFund; - } - - public void setAccumulationFund(BigDecimal accumulationFund) { - this.accumulationFund = accumulationFund; - } - - public BigDecimal getChildrenEducation() { - return childrenEducation; - } - - public void setChildrenEducation(BigDecimal childrenEducation) { - this.childrenEducation = childrenEducation; - } - - public BigDecimal getSupportTheOld() { - return supportTheOld; - } - - public void setSupportTheOld(BigDecimal supportTheOld) { - this.supportTheOld = supportTheOld; - } - - public BigDecimal getHousingLoans() { - return housingLoans; - } - - public void setHousingLoans(BigDecimal housingLoans) { - this.housingLoans = housingLoans; - } - - public BigDecimal getHousingRents() { - return housingRents; - } - - public void setHousingRents(BigDecimal housingRents) { - this.housingRents = housingRents; - } - - public BigDecimal getAdultEducation() { - return adultEducation; - } - - public void setAdultEducation(BigDecimal adultEducation) { - this.adultEducation = adultEducation; - } - - public BigDecimal getTreatmentForSeriousDisease() { - return treatmentForSeriousDisease; - } - - public void setTreatmentForSeriousDisease(BigDecimal treatmentForSeriousDisease) { - this.treatmentForSeriousDisease = treatmentForSeriousDisease; - } - - public BigDecimal getSpecialDeduction() { - return specialDeduction; - } - - public void setSpecialDeduction(BigDecimal specialDeduction) { - this.specialDeduction = specialDeduction; - } - - public BigDecimal getTotalWages() { - return totalWages; - } - - public void setTotalWages(BigDecimal totalWages) { - this.totalWages = totalWages; - } - public BigDecimal getAggregatePersonalIncomeTax() { - return aggregatePersonalIncomeTax; - } - - public void setAggregatePersonalIncomeTax(BigDecimal aggregatePersonalIncomeTax) { - this.aggregatePersonalIncomeTax = aggregatePersonalIncomeTax; - } - public String getRemarks() { - return remarks; - } - - public void setRemarks(String remarks) { - this.remarks = remarks; - } } diff --git a/evo-admin/src/main/java/com/evo/system/service/ISysStaffService.java b/evo-admin/src/main/java/com/evo/system/service/ISysStaffService.java index b0d8361..f4213d2 100644 --- a/evo-admin/src/main/java/com/evo/system/service/ISysStaffService.java +++ b/evo-admin/src/main/java/com/evo/system/service/ISysStaffService.java @@ -7,6 +7,7 @@ import com.evo.system.domain.SysStaff; import com.evo.system.domain.vo.SysStaffVo; import org.springframework.web.multipart.MultipartFile; +import javax.servlet.http.HttpServletResponse; import java.util.List; /** @@ -100,4 +101,11 @@ public interface ISysStaffService extends IService SysStaff selectByDepId(Long deptId); AjaxResult importSalesCommissions(List attendanceList); + + /*** + * 数据导出 + * @param response + * @param sysStaff + */ + void exportInfo(HttpServletResponse response, SysStaff sysStaff); } diff --git a/evo-admin/src/main/java/com/evo/system/service/impl/SysStaffServiceImpl.java b/evo-admin/src/main/java/com/evo/system/service/impl/SysStaffServiceImpl.java index 210c619..b3f35a9 100644 --- a/evo-admin/src/main/java/com/evo/system/service/impl/SysStaffServiceImpl.java +++ b/evo-admin/src/main/java/com/evo/system/service/impl/SysStaffServiceImpl.java @@ -11,8 +11,14 @@ import com.evo.common.core.domain.entity.RzUpload; import com.evo.common.core.domain.entity.SysDept; import com.evo.common.core.domain.entity.SysDictData; import com.evo.common.utils.*; +import com.evo.common.utils.Collections; import com.evo.common.utils.bean.BeanUtils; +import com.evo.common.utils.poi.ExcelUtil; +import com.evo.common.utils.poi.ExcelUtil1; import com.evo.equipment.service.IEqSnDetailService; +import com.evo.kingdeeUtils.KingdeeRequestUtils; +import com.evo.personnelMatters.domain.RzSubsidyInfo; +import com.evo.personnelMatters.mapper.RzSubsidyInfoMapper; import com.evo.restaurant.service.IRzRestaurantStatisticsService; import com.evo.system.domain.SysStaff; import com.evo.system.domain.SysStaffDetail; @@ -23,6 +29,7 @@ import com.evo.system.mapper.SysStaffDetailMapper; import com.evo.system.mapper.SysStaffMapper; import com.evo.system.service.ISysStaffService; import com.evo.system.service.RzUploadService; +import com.evo.system.utils.SubsidyCalculationUtils; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.ObjectUtils; @@ -35,14 +42,11 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; -import java.io.IOException; -import java.io.InputStream; +import javax.servlet.http.HttpServletResponse; +import java.io.*; import java.math.BigDecimal; import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Date; -import java.util.List; +import java.util.*; import java.util.stream.Collectors; /** @@ -69,6 +73,8 @@ public class SysStaffServiceImpl extends ServiceImpl i private RzUploadService rzUploadService;//文件上传 @Resource private IEqSnDetailService eqSnDetailService;//设备信息 + @Resource + private RzSubsidyInfoMapper rzSubsidyInfoMapper; /** * 查询员工管理 * @@ -152,6 +158,9 @@ public class SysStaffServiceImpl extends ServiceImpl i rzRestaurantStatisticsService.createRestaurantStatistics(sysStaff, DateUtils.getNowDate()); //处理考勤机相关信息 initCheckDevice(sysStaff); + //新增员工信息到金蝶 + KingdeeRequestUtils.employeeSave(Collections.asMap("FName", sysStaff.getName(), "FStaffNumber", sysStaff.getCode(), "FNumber", sysStaff.getJobCode().split("_")[0])); + return AjaxResult.success(); } @@ -223,6 +232,8 @@ public class SysStaffServiceImpl extends ServiceImpl i if(i < 1){ return AjaxResult.error(); } + //如果是离职, 推送金蝶禁用 + KingdeeRequestUtils.employeeDisabled(Collections.asMap("Numbers",sysStaff.getJobCode().split("_")[0])); return AjaxResult.success(); } } @@ -237,6 +248,10 @@ public class SysStaffServiceImpl extends ServiceImpl i } //根据员工ID查询原来的数据信息 SysStaff old_staff = getBaseMapper().selectSysStaffByUserId(sysStaff.getUserId()); + //检查是否修改岗位 + if(!old_staff.getJobCode().equals(sysStaff.getJobCode())) { + KingdeeRequestUtils.updateJobInfo(Collections.asMap("NeedUpDateFields","\"FDept\",\"FPosition\"", "FNumber", sysStaff.getCode(), "FDept_FNumber", sysStaff.getJobCode().split("_")[1], "FPosition_FNumber", sysStaff.getJobCode().split("_")[0])); + } //判断员工更换公司 if(!old_staff.getCompanyName().equals(sysStaff.getCompanyName())) { SysStaffDetail sysStaffDetail = sysStaffDetailMapper.selectSysStaffDetailByStaffId(sysStaff.getUserId()); @@ -480,8 +495,8 @@ public class SysStaffServiceImpl extends ServiceImpl i for (SysStaffVo Staffvo : staffList){ //判断必填项是否为空,为空执行下一条数据: 身份证号,姓名,部门,是否有加班费,入职日期,学历,打卡,合同,社保 if(StringUtils.isEmpty(Staffvo.getIdCard()) || StringUtils.isEmpty(Staffvo.getName()) || StringUtils.isEmpty(Staffvo.getDeptName()) - || StringUtils.isEmpty(Staffvo.getIsOvertimePay()) || Staffvo.getEmploymentDate() == null || StringUtils.isEmpty(Staffvo.getLevel()) - || StringUtils.isEmpty(Staffvo.getClockIn()) || StringUtils.isEmpty(Staffvo.getContractType()) || StringUtils.isEmpty(Staffvo.getSocialType()) + || Staffvo.getEmploymentDate() == null || StringUtils.isEmpty(Staffvo.getLevel()) + || StringUtils.isEmpty(Staffvo.getClockIn()) || StringUtils.isEmpty(Staffvo.getSocialType()) || StringUtils.isEmpty(Staffvo.getSocialSubsidy())){ continue; } @@ -526,12 +541,12 @@ public class SysStaffServiceImpl extends ServiceImpl i } } //合同年限 - for (SysDictData sysDictData : ht_list) { - if(sysDictData.getDictLabel().equals(Staffvo.getContractType())){ - sysStaff.setContractType(sysDictData.getDictValue()); - break; - } - } +// for (SysDictData sysDictData : ht_list) { +// if(sysDictData.getDictLabel().equals(Staffvo.getContractType())){ +// sysStaff.setContractType(sysDictData.getDictValue()); +// break; +// } +// } //计算性别和年龄 if(StringUtils.isNotEmpty(sysStaff.getIdCard())){ //根据身份证解析性别和年龄 @@ -707,5 +722,45 @@ public class SysStaffServiceImpl extends ServiceImpl i return AjaxResult.success(); } + @Override + public void exportInfo(HttpServletResponse response, SysStaff sysStaff) { + List res_list = new ArrayList(); + //查询员工信息 + List yg_list = getBaseMapper().selectSysStaffList(sysStaff); + List userIds = yg_list.stream().map(SysStaff::getUserId).collect(Collectors.toList()); + Map detailMap = sysStaffDetailMapper.selectList(new LambdaQueryWrapper().eq(SysStaffDetail::getDelFlag, Constants.DELETE_FLAG_0).in(SysStaffDetail::getStaffId,userIds)).stream().collect(Collectors.toMap(SysStaffDetail::getStaffId, v->v)); + List subsidyList = rzSubsidyInfoMapper.selectList(new LambdaQueryWrapper()); + Map subsidyMap = rzSubsidyInfoMapper.selectList(new LambdaQueryWrapper()).stream().collect(Collectors.toMap(RzSubsidyInfo::getId, RzSubsidyInfo::getName)); + + for (SysStaff staff : yg_list) { + SysStaffVo sysStaffVo = new SysStaffVo(); + BeanUtils.copyProperties(staff,sysStaffVo); + //根据员工信息查询详情信息 + SysStaffDetail sysStaffDetail = SubsidyCalculationUtils.subsidyCalculation(staff,detailMap.get(staff.getUserId()), subsidyList); + BeanUtils.copyProperties(sysStaffDetail,sysStaffVo); +// StringBuilder subsidyInfo = new StringBuilder(""); +// for (String key : sysStaffDetail.getExtendeds().keySet()){ +// subsidyInfo.append(key).append("-").append(sysStaffDetail.getExtendeds().get(key)).append("元,"); +// } +// sysStaffVo.setSubsidyInfo(subsidyInfo.toString()); + sysStaffVo.setSubsidyMap(sysStaffDetail.getExtendeds()); + res_list.add(sysStaffVo); + } + ExcelUtil1 util = new ExcelUtil1(SysStaffVo.class); + util.exportExcel(response, res_list, "员工信息"); + } + + + public static void main(String[] args) throws Exception { + + BufferedReader reader = new BufferedReader(new FileReader(new File("D:\\andy\\文档\\考勤\\岗位任职部门信息.txt"))); + String line = reader.readLine(); + while (line != null) { + String[] configData = line.split("_"); + System.out.println("update sys_dict_data set dict_value='"+line+"' where dict_value='"+configData[0]+"';\n"); + line = reader.readLine(); + } + } + } diff --git a/evo-admin/src/main/resources/lib/k3cloud-webapi-sdk-java11-v8.2.0.jar b/evo-admin/src/main/resources/lib/k3cloud-webapi-sdk-java11-v8.2.0.jar new file mode 100644 index 0000000..bad846c Binary files /dev/null and b/evo-admin/src/main/resources/lib/k3cloud-webapi-sdk-java11-v8.2.0.jar differ diff --git a/evo-admin/src/main/resources/mapper/system/SysStaffMapper.xml b/evo-admin/src/main/resources/mapper/system/SysStaffMapper.xml index 587a5c2..7521f1f 100644 --- a/evo-admin/src/main/resources/mapper/system/SysStaffMapper.xml +++ b/evo-admin/src/main/resources/mapper/system/SysStaffMapper.xml @@ -52,7 +52,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - select user_id,company_name, dept_id, code, name, id_card,is_leader, sex, age, phone, address, level, major, school, bank_number,social_subsidy, bank, employment_date, experience, worker_term, regular_date, quit_date, contract_start, contract_end, contract_type, social_type, seniority, is_overtime_pay, zs_flag, secrecy, injury, insurance, introducer, clock_in, status, wages_ratio_date, remarks, del_flag, create_by, create_time, update_by, update_time, image_url,time_clock,subsidys from sys_staff + select user_id,company_name, dept_id, code, name, id_card,is_leader, sex, age, phone, address, level, major, school, bank_number,social_subsidy, bank, employment_date, experience, worker_term, regular_date, quit_date, contract_start, contract_end, contract_type, social_type, seniority, is_overtime_pay, zs_flag, secrecy, injury, insurance, introducer, clock_in, status, wages_ratio_date, remarks, del_flag, create_by, create_time, update_by, update_time, image_url,time_clock,subsidys, job_code from sys_staff