diff --git a/src/com/engine/jucailinkq/attendance/component/ImportAndExport/service/ExcelExportImportService.java b/src/com/engine/jucailinkq/attendance/component/ImportAndExport/service/ExcelExportImportService.java index fb90e11..211f1a4 100644 --- a/src/com/engine/jucailinkq/attendance/component/ImportAndExport/service/ExcelExportImportService.java +++ b/src/com/engine/jucailinkq/attendance/component/ImportAndExport/service/ExcelExportImportService.java @@ -1,6 +1,7 @@ package com.engine.jucailinkq.attendance.component.ImportAndExport.service; import com.engine.jucailinkq.attendance.component.ImportAndExport.service.param.ImportParam; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import java.util.Map; @@ -19,6 +20,8 @@ public interface ExcelExportImportService { */ XSSFWorkbook exportSchedule(Map paramMap); + HSSFWorkbook exportScheduleNew(Map paramMap); + /** * 日历排班页面中的排班列表导入 * @param param diff --git a/src/com/engine/jucailinkq/attendance/component/ImportAndExport/service/impl/ExcelExportImportServiceImpl.java b/src/com/engine/jucailinkq/attendance/component/ImportAndExport/service/impl/ExcelExportImportServiceImpl.java index 6fcf2b4..71d1f91 100644 --- a/src/com/engine/jucailinkq/attendance/component/ImportAndExport/service/impl/ExcelExportImportServiceImpl.java +++ b/src/com/engine/jucailinkq/attendance/component/ImportAndExport/service/impl/ExcelExportImportServiceImpl.java @@ -21,6 +21,7 @@ import com.engine.core.impl.Service; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.util.IOUtils; import org.apache.poi.xssf.usermodel.XSSFWorkbook; @@ -32,6 +33,7 @@ import java.io.InputStream; import java.util.*; import java.util.stream.Collectors; +import static com.engine.jucailinkq.common.util.excel.ExcelSupport.EXCEL_TYPE_XLS; import static com.engine.jucailinkq.common.util.excel.ExcelSupport.EXCEL_TYPE_XLSX; /** @@ -80,6 +82,53 @@ public class ExcelExportImportServiceImpl extends Service implements ExcelExport return ExcelUtil.genWorkbookV2(excelSheetData, sheetName, dateTime, columns.size()); } + @Override + public HSSFWorkbook exportScheduleNew(Map paramMap) { + String total = Util.null2String(paramMap.get("total")); + if ("".equals(total) || "0".equals(total)) { + paramMap.put("pageSize", "9999"); + } else { + paramMap.put("pageSize", total); + } + paramMap.put("pageindex", "1"); + log.debug("查询条件:{}",paramMap); + Map scheduleResult = getWorkRulesService(user).getDepartSchedule(paramMap); + List columns = buildScheduleColumns((List>) scheduleResult.get("columns")); + List> records = buildScheduleRecords((List>) scheduleResult.get("datas")); + + List> excelSheetData = new ArrayList<>(); + //工作簿名称 + String sheetName = "日历排班"; + excelSheetData.add(Arrays.asList(columns.stream().map(WeaTableColumn::getText).toArray())); + + //工作簿数据 + List> rows = new LinkedList<>(); + for (Map recordData : records) { + List row = new LinkedList<>(); + for (WeaTableColumn column : columns) { + row.add(recordData.get(column.getColumn())); + } + rows.add(row); + } + + excelSheetData.addAll(rows); + String dateTime = Util.null2String(paramMap.get("dateTime")); + //获取下拉列表中的值 + String sql = "select mc from uf_jcl_kq_bcxx;"; + List> bcData = DbTools.getSqlToList(sql); + List bcMcList = new ArrayList<>(); + if (bcData.size() > 0) { + bcMcList = bcData.stream().map(e -> e.get("mc").toString()).collect(Collectors.toList()); + } + //配置下拉列表的区域信息,依次为开始行、结束行、开始列、结束列 + List dropdownRange = new ArrayList<>(); + dropdownRange.add(2); + dropdownRange.add(records.size() + 1); + dropdownRange.add(4); + dropdownRange.add(columns.size() + 3); + return ExcelUtil.genWorkbookV2WithDropdownList1(excelSheetData, sheetName, dateTime, columns.size(), bcMcList.toArray(new String[0]), dropdownRange); + } + private List> buildScheduleRecords(List> dataInfo) { List> result = new ArrayList<>(); if (dataInfo != null && dataInfo.size() > 0) { @@ -139,15 +188,17 @@ public class ExcelExportImportServiceImpl extends Service implements ExcelExport if (fileInputStream == null) { throw new AttendanceRunTimeException("excel文件解析失败!"); } - Sheet sheet = ExcelSupport.parseFile(fileInputStream, 0, EXCEL_TYPE_XLSX); +// Sheet sheet = ExcelSupport.parseFile(fileInputStream, 0, EXCEL_TYPE_XLSX); + Sheet sheet = ExcelSupport.parseFile(fileInputStream, 0, EXCEL_TYPE_XLS); //标题 List titles = ExcelSupport.getSheetHeader(sheet, 0); - String title = titles.get(0); - log.debug("处理前年月信息:{}",title); + log.info("title长度:{}",titles.get(0).length()); + String title = titles.get(0).replace(" ", ""); + log.info("处理前年月信息:{}",title); //年月格式的转换处理 if (StrUtil.isNotBlank(title) && title.length() > 7) { title = title.substring(0, 7); - log.debug("处理后年月信息:{}",title); + log.info("处理后年月信息:{}",title); } if (StrUtil.isNotBlank(title) && !DateUtil.checkYearMonth(title.replace("/", "-"))) { throw new AttendanceRunTimeException("excel首行'年月'时间格式错误,正确格式为yyyy-mm或者yyyy-mm-dd或者yyyy/mm或者yyyy/mm/dd"); @@ -155,14 +206,14 @@ public class ExcelExportImportServiceImpl extends Service implements ExcelExport int monthDays = DateUtil.getDays(title, Calendar.DAY_OF_MONTH); // 表头 List headers = ExcelSupport.getSheetHeader(sheet, 1); - log.debug("headers数据:{}", headers); + log.info("headers数据:{}", headers); // 错误sheet数据 List> errorData = new LinkedList<>(); // 错误提示 List> excelComments = new LinkedList<>(); // 处理数值 List> data = ExcelParseHelper.parse2Map(sheet, 2, 1); - log.debug("excel导入数据:[{}]", data); + log.info("excel导入数据数量:[{}]", data.size()); //单行记录 Map map; for (int i = 0; i < data.size(); i++) { @@ -175,9 +226,9 @@ public class ExcelExportImportServiceImpl extends Service implements ExcelExport if (key == null) { continue; } - singleCheck.put(key, Optional.ofNullable(map.get(key)).orElse("").toString()); + singleCheck.put(key.replace(" ", ""), Optional.ofNullable(map.get(key)).orElse("").toString().replace(" ", "")); } - log.debug(i + 3 + "-singleCheck:{}", singleCheck); +// log.info(i + 3 + "-singleCheck:{}", singleCheck); isError = singleScheduleLineCheck(singleCheck, title, monthDays, toImportScheduleInfos, employeeInfoList, shiftMapWithMc, excelComments, i + 3, formModeId, empIds); if (isError) { errorCount += 1; @@ -225,6 +276,7 @@ public class ExcelExportImportServiceImpl extends Service implements ExcelExport String subCompany = Util.null2String(singleCheck.get("分部")); String department = Util.null2String(singleCheck.get("部门")); String rowIndex = "第" + index + "行"; + log.info("workcode : {}, lastname : {}, subCompany : {}, department : {}", workCode, lastName, subCompany, department); //校验该行数据中员工信息是否唯一存在 List> targetEmpInfo = matchImportEmp(employeeByIds, lastName, subCompany, department, workCode); if (CollectionUtils.isEmpty(targetEmpInfo)) { @@ -250,6 +302,13 @@ public class ExcelExportImportServiceImpl extends Service implements ExcelExport } //获取目标人员目标月日期类型对日期的映射 List> rqlxInfo = CommonUtil.getYearCalendarList(employeeId, yearMonth.substring(0, 4)); + if (rqlxInfo == null || rqlxInfo.size() == 0) { + Map errorMessageMap = new HashMap<>(); + errorMessageMap.put("message", rowIndex + "该员工不存在可用日历!"); + excelComments.add(errorMessageMap); + isError = true; + return isError; + } Map rqlxInfoWithRq = rqlxInfo.stream().filter(f -> f.get("rq").toString().contains(yearMonth)).collect(Collectors.toMap(e->e.get("rq").toString(), e->e.get("rqlx").toString())); //暂存本次调用中的导入数据 List> singleToImportScheduleInfos = new ArrayList<>(); @@ -346,7 +405,8 @@ public class ExcelExportImportServiceImpl extends Service implements ExcelExport InputStream fileInputStream = null; try { fileInputStream = ImageFileManager.getInputStreamById(Integer.parseInt(param.getImageId())); - Sheet sheet = ExcelSupport.parseFile(fileInputStream, 0, EXCEL_TYPE_XLSX); +// Sheet sheet = ExcelSupport.parseFile(fileInputStream, 0, EXCEL_TYPE_XLSX); + Sheet sheet = ExcelSupport.parseFile(fileInputStream, 0, EXCEL_TYPE_XLS); map.put("headers", ExcelSupport.getSheetHeader(sheet, 1)); map.put("list", ExcelParseHelper.parse2List(sheet, 2, 1)); return map; diff --git a/src/com/engine/jucailinkq/attendance/component/ImportAndExport/web/ExcelController.java b/src/com/engine/jucailinkq/attendance/component/ImportAndExport/web/ExcelController.java index dc05811..898be15 100644 --- a/src/com/engine/jucailinkq/attendance/component/ImportAndExport/web/ExcelController.java +++ b/src/com/engine/jucailinkq/attendance/component/ImportAndExport/web/ExcelController.java @@ -7,6 +7,7 @@ import com.engine.common.util.ParamUtil; import com.engine.jucailinkq.common.util.ResponseResult; import com.engine.common.util.ServiceUtil; import io.swagger.v3.oas.annotations.parameters.RequestBody; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import weaver.hrm.HrmUserVarify; import weaver.hrm.User; @@ -40,11 +41,13 @@ public class ExcelController { public Response scheduleExport(@Context HttpServletRequest request, @Context HttpServletResponse response) { User user = HrmUserVarify.getUser(request, response); Map paramMap = ParamUtil.request2Map(request); - XSSFWorkbook workbook = getExcelService(user).exportSchedule(paramMap); +// XSSFWorkbook workbook = getExcelService(user).exportSchedule(paramMap); + HSSFWorkbook workbook = getExcelService(user).exportScheduleNew(paramMap); String time = LocalDate.now().toString(); String fileName = "日历排班列表" + time; try { - fileName = URLEncoder.encode(fileName + ".xlsx", "UTF-8"); +// fileName = URLEncoder.encode(fileName + ".xlsx", "UTF-8"); + fileName = URLEncoder.encode(fileName + ".xls", "UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } diff --git a/src/com/engine/jucailinkq/attendance/workflow/cmd/GetCqSummarySearchConditionCmd.java b/src/com/engine/jucailinkq/attendance/workflow/cmd/GetCqSummarySearchConditionCmd.java index c28e9d4..925bab5 100644 --- a/src/com/engine/jucailinkq/attendance/workflow/cmd/GetCqSummarySearchConditionCmd.java +++ b/src/com/engine/jucailinkq/attendance/workflow/cmd/GetCqSummarySearchConditionCmd.java @@ -100,7 +100,10 @@ public class GetCqSummarySearchConditionCmd extends AbstractCommonCommand 4) { + wrg.getOptions().subList(4, wrg.getOptions().size()).clear(); + } lsCondition.add(wrg); WeaRadioGroup wrg1 = new WeaRadioGroup(); diff --git a/src/com/engine/jucailinkq/common/util/excel/ExcelUtil.java b/src/com/engine/jucailinkq/common/util/excel/ExcelUtil.java index a432a79..343adc8 100644 --- a/src/com/engine/jucailinkq/common/util/excel/ExcelUtil.java +++ b/src/com/engine/jucailinkq/common/util/excel/ExcelUtil.java @@ -1,12 +1,15 @@ package com.engine.jucailinkq.common.util.excel; import com.engine.jucailinkq.common.util.DateUtil; +import org.apache.poi.hssf.usermodel.*; import org.apache.poi.ss.usermodel.*; import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.ss.util.CellRangeAddressList; import org.apache.poi.xssf.usermodel.*; -import java.util.Date; -import java.util.List; +import java.util.*; + +import static org.apache.poi.hssf.usermodel.DVConstraint.createExplicitListConstraint; /** * @Author: sy @@ -187,6 +190,145 @@ public class ExcelUtil { return workbook; } + public static HSSFWorkbook genWorkbookV2WithDropdownList1(List> rowList, String sheetName, String title, int titleCellNum, String[] dropdownData, List deopdownRange) { + HSSFWorkbook hssfWorkbook = new HSSFWorkbook(); + // 设置title样式 + HSSFCellStyle titleCellStyle = hssfWorkbook.createCellStyle(); + HSSFFont titleFont = hssfWorkbook.createFont(); + titleFont.setBold(true); + titleFont.setFontName("仿宋"); + titleFont.setFontHeightInPoints((short) 15); + titleCellStyle.setFont(titleFont); + titleCellStyle.setAlignment(HorizontalAlignment.CENTER); + titleCellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());//背景色 + titleCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); + titleCellStyle.setVerticalAlignment(VerticalAlignment.CENTER); + titleCellStyle.setBorderLeft(BorderStyle.THIN); + titleCellStyle.setBorderRight(BorderStyle.THIN); + titleCellStyle.setBorderTop(BorderStyle.THIN); + titleCellStyle.setBorderBottom(BorderStyle.THIN); + // 设置主体样式 + HSSFCellStyle cellStyle = hssfWorkbook.createCellStyle(); + HSSFFont font = hssfWorkbook.createFont(); + font.setFontName("宋体"); + font.setFontHeightInPoints((short) 10);// 设置字体大小 + cellStyle.setFont(font);// 选择需要用到的字体格式 + cellStyle.setWrapText(true); + cellStyle.setBorderLeft(BorderStyle.THIN); + cellStyle.setBorderRight(BorderStyle.THIN); + cellStyle.setBorderTop(BorderStyle.THIN); + cellStyle.setBorderBottom(BorderStyle.THIN); + + HSSFSheet sheet = hssfWorkbook.createSheet(sheetName); + //自适应宽度 + sheet.autoSizeColumn(0, true); + //默认列宽 + sheet.setDefaultColumnWidth(20); + //默认行高 + sheet.setDefaultRowHeightInPoints(18); + //设置下拉列表 + Map boxMap = new HashMap<>(); + boxMap.put("班次名称", String.join(",", dropdownData)); + //指定将下拉框添加至1-10行,0-0列。即第一列的第2到11行 + HSSFDataValidation dataValidation = createBox("班次名称", boxMap , deopdownRange.get(0), deopdownRange.get(1), deopdownRange.get(2), deopdownRange.get(3)); + if(dataValidation != null) { + sheet.addValidationData(dataValidation); + } + sheet.addValidationData(dataValidation); + // 合并第一行的前titleCellNum个单元格 + CellRangeAddress cellRangeAddress = new CellRangeAddress(0, 0, 0, titleCellNum - 1); + sheet.addMergedRegion(cellRangeAddress); + //遍历设置列宽 + List header = rowList.get(0); + for (int i = 0; i < header.size(); i++) { + sheet.setColumnWidth(i, Math.max(12, header.get(i).toString().length() * 4) * 256); + } + + for (int rowIndex = 0; rowIndex <= rowList.size(); rowIndex++) { + HSSFRow row = sheet.createRow(rowIndex); + float height = 18; + float finalHeight = 18; + + if (rowIndex == 0) { + HSSFCell cell = row.createCell(0); + cell.setCellStyle(titleCellStyle); + cell.setCellType(CellType.STRING); + cell.setCellValue(title); + } else { + List infoList = rowList.get(rowIndex - 1); + for (int cellIndex = 0; cellIndex < infoList.size(); cellIndex++) { + HSSFCell cell = row.createCell(cellIndex); + if (rowIndex == 1) { + cell.setCellStyle(titleCellStyle); + } else { + cell.setCellStyle(cellStyle); + } + Object o = infoList.get(cellIndex); + if (o instanceof String) { + cell.setCellType(CellType.STRING); + cell.setCellValue(String.valueOf(o)); + } else if (o instanceof Boolean) { + cell.setCellType(CellType.BOOLEAN); + cell.setCellValue(String.valueOf(o)); + } else if (o instanceof Date) { + cell.setCellType(CellType.STRING); + cell.setCellValue(DateUtil.getFormatLocalDate((Date) o)); + } else { + cell.setCellType(CellType.STRING); + cell.setCellValue(o == null ? "" : o.toString()); + } + + //判断是否要调整高度 + int width = sheet.getColumnWidth(cellIndex) / 256; + finalHeight = getFinalHeight(o, width, finalHeight, height); + } + } + row.setHeightInPoints(finalHeight); + } + return hssfWorkbook; + } + +/** + * excel导出,有码值的数据使用下拉框展示。 + * @param col 列名 + * @param boxMap 码值集合 + * @param firstRow 插入下拉框开始行号 + * @param lastRow 插入下拉框结束行号 + * @param firstCol 插入下拉框开始列号 + * @param lastCol 插入下拉框结束行号 + * @return + */ +public static HSSFDataValidation createBox(String col, Map boxMap, int firstRow, int lastRow, int firstCol, int lastCol) { + HSSFDataValidation dataValidation = null; + //查询码值表,如果长度超过255,则截取 + String cols = ""; + String completeCols = ""; + if(null != boxMap.get(col)) { + cols = boxMap.get(col); + } + completeCols = cols; + if (cols.length() > 255) { + cols = cols.substring(0, 255); + } + //设置下拉框 + if(cols.length() > 0) { + String[] str = cols.split(","); + if (completeCols.length() > 255) { + String[] completeStr = completeCols.split(","); + if (!completeStr[str.length - 1].equals(str[str.length - 1])) { + str = Arrays.copyOf(completeStr, str.length - 1); + } + } + //指定firstRow-lastRow行,firstCol-lastCol列为下拉框 + CellRangeAddressList cas = new CellRangeAddressList(firstRow , lastRow , firstCol , lastCol); + //创建下拉数据列 + DVConstraint dvConstraint = DVConstraint.createExplicitListConstraint(str); + //将下拉数据放入下拉框 + dataValidation = new HSSFDataValidation(cas, dvConstraint); + } + return dataValidation; +} + public static float getFinalHeight(Object o, int width, float finalHeight, float height) { if (o != null && getStrlength(o.toString()) > width) { float remainder = getStrlength(o.toString()) % width;