mitao
2 天以前 9c76b7efccd70395231b032a193a89f7638b657e
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java
@@ -29,6 +29,17 @@
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.RegionUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Propagation;
@@ -190,10 +201,12 @@
    @PostMapping("/importUser")
    public R<Object> importUser(@RequestPart("file") MultipartFile file) {
        ImportParams params = new ImportParams();
        params.setHeadRows(1); // 表头行数
        params.setHeadRows(2); // 表头行数改为2行
        InputStream inputStream = null;
        List<EmployeeImportExcel> employeeExcelList;
        Map<String, SysUser> userMap = userService.selectAllList().stream()
                .collect(Collectors.toMap(SysUser::getPhonenumber, e -> e));
        try {
            inputStream = file.getInputStream();
            employeeExcelList = ExcelImportUtil.importExcel(inputStream,
@@ -210,33 +223,31 @@
                }
            }
        }
        if (CollectionUtils.isEmpty(employeeExcelList)) {
            throw new ServiceException("员工数据为空!");
        }
        int successCount = 0;
        int failCount = 0;
        List<String> errorMessages = new ArrayList<>();
        Map<String, TDept> deptMap = tDeptService.list().stream().collect(Collectors.toMap(TDept::getDeptName, e -> e));
        Map<String, SysRole> roleMap = roleService.selectRoleAll().stream().collect(Collectors.toMap(SysRole::getRoleName, e -> e));
        for (EmployeeImportExcel employeeExcel : employeeExcelList) {
            try {
                // 数据验证
                // 数据验证
                if (StringUtils.isEmpty(employeeExcel.getNickName())) {
                    errorMessages.add("第" + (successCount + failCount + 1) + "行:姓名为空");
                    failCount++;
                    continue;
                }
                if (StringUtils.isEmpty(employeeExcel.getPhoneNumber())) {
                    errorMessages.add("第" + (successCount + failCount + 1) + "行:联系电话为空");
                    failCount++;
                    continue;
                }
                // 转换并保存用户
                SysUser sysUser = convertToSysUser(employeeExcel);
                if (StringUtils.isEmpty(employeeExcel.getDepartment())) {
@@ -245,66 +256,166 @@
                    continue;
                }
                TDept dept = tDeptService.lambdaQuery().eq(TDept::getDeptName, employeeExcel.getDepartment())
                        .last("limit 1").one();
                TDept dept = deptMap.get(employeeExcel.getDepartment().trim());
                if (dept == null){
                    errorMessages.add("第" + (successCount + failCount + 1) + "行:所在股室不存在");
                    failCount++;
                    continue;
                }
                SysRole role = roleMap.get(employeeExcel.getRoleName().trim());
                if (role == null){
                    errorMessages.add("第" + (successCount + failCount + 1) + "行:角色不存在");
                    failCount++;
                    continue;
                }
                SysUser sysUser1 = userMap.get(sysUser.getPhonenumber());
                if (sysUser1 != null){
                    errorMessages.add("第" + (successCount + failCount + 1) + "行:电话号码已存在");
                    failCount++;
                    continue;
                }
                sysUser.setRoleId(role.getRoleId());
                sysUser.setDeptId(dept.getId().toString());
                userService.insertUser(sysUser);
                successCount++;
            } catch (Exception e) {
                errorMessages.add("第" + (successCount + failCount + 1) + "行:" + e.getMessage());
                failCount++;
                e.printStackTrace();
            }
        }
        JSONObject result = new JSONObject();
        result.put("successCount", successCount);
        result.put("failCount", failCount);
        result.put("totalCount", successCount + failCount);
        if (!errorMessages.isEmpty()) {
            result.put("errorMessages", errorMessages);
            return R.fail(result.get("errorMessages"));
            return R.fail("部分数据导入失败:"+result.get("errorMessages").toString());
        }
        return R.ok("导入完成", result.toString());
    }
    /**
     * 解析日期字符串为Date对象
     * @param dateStr 日期字符串,格式如:2022.09
     * @return Date对象
     */
    private Date parseDate(String dateStr) {
        if (StringUtils.isEmpty(dateStr)) {
            return null;
        }
    @ApiOperation(value = "员工导入模板下载")
    @GetMapping("/importDownload")
    @CrossOrigin(origins = "*")
    public void importDownload(HttpServletResponse response) {
        ServletOutputStream outputStream = null;
        Workbook workbook = null;
        try {
            // 支持 YYYY.MM 格式
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
            return sdf.parse(dateStr);
        } catch (ParseException e) {
            // 确保在创建workbook之前没有输出任何内容
            response.reset();
            // 创建工作簿
            workbook = new HSSFWorkbook();
            Sheet sheet = workbook.createSheet("员工信息");
            // 创建样式
            CellStyle headStyle = workbook.createCellStyle();
            headStyle.setAlignment(HorizontalAlignment.CENTER);
            headStyle.setVerticalAlignment(VerticalAlignment.CENTER);
            headStyle.setBorderBottom(BorderStyle.THIN);
            headStyle.setBorderTop(BorderStyle.THIN);
            headStyle.setBorderLeft(BorderStyle.THIN);
            headStyle.setBorderRight(BorderStyle.THIN);
            Font font = workbook.createFont();
            font.setBold(true);
            headStyle.setFont(font);
            // 创建两行
            Row row1 = sheet.createRow(0);
            Row row2 = sheet.createRow(1);
            // 设置列宽
            for (int i = 0; i < 20; i++) {
                sheet.setColumnWidth(i, 15 * 256);
            }
            // 根据截图重新设计列结构
            // A-H列(0-7): 基础信息
            // I-N列(8-13): 学历相关
            // O-S列(14-18): 其他信息
            // 第一行表头 - 20列
            String[] firstRowHeaders = {
                    "序号", "姓名", "性别", "身份证号码", "年龄", "政治面貌",
                    "参工时间", "进入公司时间", "", "", "", "", "", "",  // 移除重复的"学历"字段
                    "所在股室", "职务", "任职时间", "电话号码", "编制","角色"
            };
            // 第二行表头 - 20列
            String[] secondRowHeaders = {
                    "", "", "", "", "", "", "", "",
                    "第一学历", "第一学历-学院", "第一学历-专业", "最高学历", "最高学历-学院", "最高学历-专业", "",
                    "", "", "", "",""
            };
            // 填充第一行
            for (int i = 0; i < firstRowHeaders.length; i++) {
                Cell cell = row1.createCell(i);
                cell.setCellValue(firstRowHeaders[i]);
                cell.setCellStyle(headStyle);
            }
            // 填充第二行
            for (int i = 0; i < secondRowHeaders.length; i++) {
                Cell cell = row2.createCell(i);
                cell.setCellValue(secondRowHeaders[i]);
                cell.setCellStyle(headStyle);
            }
            // 合并单元格操作
            // 1. 先合并"学历"大标题区域(第8列到第13列,只合并第一行)
            sheet.addMergedRegion(new CellRangeAddress(0, 0, 8, 13));
            // 2. 合并其他单列表头(跨越两行)
            // 基础信息列:A-H (0-7)
            // 其他信息列:O-S (14-18)
            int[] singleColumns = {0, 1, 2, 3, 4, 5, 6, 7, 14, 15, 16, 17, 18,19};
            for (int col : singleColumns) {
                sheet.addMergedRegion(new CellRangeAddress(0, 1, col, col));
            }
            // 设置响应头
            String fileName = URLEncoder.encode("员工信息导入模板.xls", "UTF-8");
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("UTF-8");
            response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
            response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
            response.setHeader("Pragma", "no-cache");
            response.setHeader("Expires", "0");
            // 添加CORS头
            response.setHeader("Access-Control-Allow-Origin", "*");
            response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
            response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With");
            // 写入响应
            outputStream = response.getOutputStream();
            workbook.write(outputStream);
            outputStream.flush();
        } catch (Exception e) {
            e.printStackTrace();
            System.err.println("员工导入模板下载失败: " + e.getMessage());
        } finally {
            try {
                // 支持 YYYY-MM 格式
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
                return sdf.parse(dateStr);
            } catch (ParseException ex) {
                try {
                    // 支持 YYYY-MM-DD 格式
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                    return sdf.parse(dateStr);
                } catch (ParseException exc) {
                    return null;
                if (outputStream != null) {
                    outputStream.close();
                }
                if (workbook != null) {
                    workbook.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    /**
     * 将EmployeeImportExcel转换为SysUser
     * @param employeeExcel 员工导入Excel数据
@@ -326,17 +437,17 @@
        } else {
            sysUser.setSex("0");
        }
        // 身份证
        sysUser.setIdCard(employeeExcel.getIdCard());
        // 政治面貌
        sysUser.setPoliticalOutlook(employeeExcel.getPoliticalOutlook());
        // 时间字段
        sysUser.setParticipationTime(parseDate(employeeExcel.getParticipationTime()));
        sysUser.setCompanyTime(parseDate(employeeExcel.getCompanyTime()));
        sysUser.setPositionTime(parseDate(employeeExcel.getPositionTime()));
        sysUser.setParticipationTime(employeeExcel.getParticipationTime());
        sysUser.setCompanyTime(employeeExcel.getCompanyTime());
        sysUser.setPositionTime(employeeExcel.getPositionTime());
        // 学历信息
        sysUser.setFirstDegree(employeeExcel.getFirstDegree());
        sysUser.setFirstCollege(employeeExcel.getFirstCollege());
@@ -344,52 +455,27 @@
        sysUser.setHighestDegree(employeeExcel.getHighestDegree());
        sysUser.setHighestCollege(employeeExcel.getHighestCollege());
        sysUser.setHighestMajor(employeeExcel.getHighestMajor());
        // 职务和部门
        sysUser.setPosition(employeeExcel.getPosition());
        sysUser.setOrganization(employeeExcel.getOrganization());
        // 系统字段
        sysUser.setStatus("0"); // 正常状态
        sysUser.setDelFlag("0"); // 未删除
        sysUser.setCreateBy(getUsername());
        return sysUser;
    }
    @ApiOperation(value = "员工导入模板下载")
    @GetMapping("/importDownload")
    public void importDownload() {
        List<EmployeeImportExcel> employeeImportExcels = new ArrayList<>();
        EmployeeImportExcel employeeImportExcel = new EmployeeImportExcel();
        employeeImportExcels.add(employeeImportExcel);
        ExportParams exportParams = new ExportParams();
        exportParams.setTitle("员工信息导入模板");
        exportParams.setSheetName("员工信息");
        Workbook workbook = ExcelExportUtil.exportExcel(exportParams, EmployeeImportExcel.class, employeeImportExcels);
        HttpServletResponse response = WebUtils.response();
        ServletOutputStream outputStream = null;
        try {
            String fileName = URLEncoder.encode("员工信息导入模板.xls", "utf-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
            response.setHeader("content-Type", "application/vnd.ms-excel");
            response.setHeader("Pragma", "no-cache");
            response.setHeader("Cache-Control", "no-cache");
            outputStream = response.getOutputStream();
            workbook.write(outputStream);
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("员工导入模板下载失败!");
        } finally {
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
//    @ApiOperation(value = "员工导入模板下载OPTIONS")
//    @RequestMapping(value = "/importDownload", method = RequestMethod.OPTIONS)
//    @CrossOrigin(origins = "*")
//    public void importDownloadOptions(HttpServletResponse response) {
//        response.setHeader("Access-Control-Allow-Origin", "*");
//        response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
//        response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With");
//        response.setStatus(HttpServletResponse.SC_OK);
//    }
    /**
     * 修改用户