diff --git a/ruoyi-bussiness/src/main/java/com/ruoyi/cms/controller/cms/CmsJobController.java b/ruoyi-bussiness/src/main/java/com/ruoyi/cms/controller/cms/CmsJobController.java index 055198a..b95700e 100644 --- a/ruoyi-bussiness/src/main/java/com/ruoyi/cms/controller/cms/CmsJobController.java +++ b/ruoyi-bussiness/src/main/java/com/ruoyi/cms/controller/cms/CmsJobController.java @@ -20,7 +20,6 @@ import com.ruoyi.common.core.domain.entity.Company; import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.enums.BusinessType; import com.ruoyi.common.utils.DateUtils; -import com.ruoyi.common.utils.EncryptDecryptUtil; import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.bean.BeanUtils; @@ -68,8 +67,6 @@ public class CmsJobController extends BaseController private IJobApplyService iJobApplyService; @Autowired private IAppReviewJobService iAppReviewJobService; - @Autowired - private EncryptDecryptUtil encryptDecryptUtil; /** * 查询岗位列表 */ diff --git a/ruoyi-bussiness/src/main/java/com/ruoyi/cms/controller/cms/StaticsController.java b/ruoyi-bussiness/src/main/java/com/ruoyi/cms/controller/cms/StaticsController.java index 027b83d..a3f44a9 100644 --- a/ruoyi-bussiness/src/main/java/com/ruoyi/cms/controller/cms/StaticsController.java +++ b/ruoyi-bussiness/src/main/java/com/ruoyi/cms/controller/cms/StaticsController.java @@ -1,14 +1,19 @@ package com.ruoyi.cms.controller.cms; +import com.ruoyi.cms.domain.StaticsJob; import com.ruoyi.cms.domain.query.Staticsquery; import com.ruoyi.cms.service.StaticsqueryService; +import com.ruoyi.cms.util.excel.StaticsExcelUtil; import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.utils.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import javax.servlet.http.HttpServletResponse; +import java.util.List; import java.util.Map; @RestController @@ -112,4 +117,27 @@ public class StaticsController extends BaseController { Map result = service.qygwtjCount(staticsquery); return success(result); } + + @GetMapping("/qygwtjDownload") + public void qygwtjDownload(Staticsquery staticsquery, HttpServletResponse response) throws Exception { + if(staticsquery==null){ + throw new Exception("参数为空!"); + } + String timeRange=""; + if(StringUtils.isBlank(staticsquery.getStartTime())){ + timeRange= "全部"; + }else{ + timeRange= staticsquery.getStartTime()+"至"+staticsquery.getEndTime(); + } + String[] statLabels = {"注册企业数", "求职者实名数", "归集岗位合计", "简历投递数", "零工岗位数", "零工招聘人数"}; + Map result = service.qygwtjCount(staticsquery); + List regionList = (List) result.get("group"); + StaticsJob staticsJob=(StaticsJob)result.get("hz"); + Integer[] statValues = {Integer.valueOf(staticsJob.getZcqys()),Integer.valueOf(staticsJob.getQzzsms()), + Integer.valueOf(staticsJob.getGjgwhj()), Integer.valueOf(staticsJob.getJlsl()), + Integer.valueOf(staticsJob.getLggws()), Integer.valueOf(staticsJob.getLgzprs())}; + StaticsExcelUtil excelUtil = new StaticsExcelUtil<>(StaticsJob.class); + excelUtil.exportEmploymentExcel(response, timeRange, statLabels, statValues, regionList, + "岗位归集统计", 12); + } } diff --git a/ruoyi-bussiness/src/main/java/com/ruoyi/cms/domain/StaticsJob.java b/ruoyi-bussiness/src/main/java/com/ruoyi/cms/domain/StaticsJob.java index 6528f6e..b0cddf9 100644 --- a/ruoyi-bussiness/src/main/java/com/ruoyi/cms/domain/StaticsJob.java +++ b/ruoyi-bussiness/src/main/java/com/ruoyi/cms/domain/StaticsJob.java @@ -1,31 +1,51 @@ package com.ruoyi.cms.domain; +import com.ruoyi.common.annotation.Excel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @Data public class StaticsJob { - @ApiModelProperty("总数") - private String zs; - @ApiModelProperty("高效毕业生岗位") - private String gxbysgw; - @ApiModelProperty("实时在招岗位数") - private String sszzgw; - @ApiModelProperty("简历数量") - private String jlsl; + + @Excel(name = "地区") @ApiModelProperty("名称") private String label; - @ApiModelProperty("归集岗位合计") - private String gjgwhj; + @Excel(name = "总数") + @ApiModelProperty("总数") + private String zs; + + @Excel(name = "企业总数") @ApiModelProperty("注册企业数") private String zcqys; - @ApiModelProperty("求职者实名数") - private String qzzsms; - @ApiModelProperty("零工岗位数") - private String lggws; - @ApiModelProperty("零工招聘人数") - private String lgzprs; + + @Excel(name = "新注册企业数") @ApiModelProperty("新注册企业数") private String xzcqys; + + @Excel(name = "其中适合高校毕业生岗位数") + @ApiModelProperty("高效毕业生岗位") + private String gxbysgw; + + @Excel(name = "实时在招岗位数") + @ApiModelProperty("实时在招岗位数") + private String sszzgw; + + @Excel(name = "简历数量") + @ApiModelProperty("简历数量") + private String jlsl; + + @ApiModelProperty("归集岗位合计") + private String gjgwhj; + + @ApiModelProperty("求职者实名数") + private String qzzsms; + + @Excel(name = "零工岗位数") + @ApiModelProperty("零工岗位数") + private String lggws; + + @Excel(name = "零工招聘人数") + @ApiModelProperty("零工招聘人数") + private String lgzprs; } diff --git a/ruoyi-bussiness/src/main/java/com/ruoyi/cms/util/excel/StaticsExcelUtil.java b/ruoyi-bussiness/src/main/java/com/ruoyi/cms/util/excel/StaticsExcelUtil.java new file mode 100644 index 0000000..b079fd7 --- /dev/null +++ b/ruoyi-bussiness/src/main/java/com/ruoyi/cms/util/excel/StaticsExcelUtil.java @@ -0,0 +1,164 @@ +package com.ruoyi.cms.util.excel; + +import com.ruoyi.common.annotation.Excel; +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; + +import javax.servlet.http.HttpServletResponse; +import java.io.OutputStream; +import java.lang.reflect.Field; +import java.net.URLEncoder; +import java.util.List; + +/** + * 就业统计Excel导出工具(支持动态传递列数) + */ +public class StaticsExcelUtil { + private final Class clazz; + + public StaticsExcelUtil(Class clazz) { + this.clazz = clazz; + } + + public void exportEmploymentExcel(HttpServletResponse response, + String timeRange, + String[] statLabels, + Integer[] statValues, + List dataList, + String sheetName, + int maxColumnNum) throws Exception { + // 参数校验 + if (statLabels == null || statValues == null || statLabels.length != statValues.length) { + throw new IllegalArgumentException("统计标签数组和数值数组长度必须一致!"); + } + if (maxColumnNum < 1) { + throw new IllegalArgumentException("最大列数不能小于1!"); + } + int maxColumnIndex = maxColumnNum - 1; // 列索引从0开始,比如9列对应索引0-8 + + // 1. 创建工作簿和工作表 + Workbook workbook = new XSSFWorkbook(); + Sheet sheet = workbook.createSheet(sheetName); + + // 2. 第1行:统计时间(动态合并列) + Row row1 = sheet.createRow(0); + Cell cell1 = row1.createCell(0); + cell1.setCellValue("统计时间:" + timeRange); + // 合并第1行的0 ~ maxColumnIndex列(动态列数) + sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, maxColumnIndex)); + setCellStyle(cell1, true, workbook); + + // 3. 第2行:统计指标(适配动态列数) + Row row2 = sheet.createRow(1); + int cellIndex = 0; + for (int i = 0; i < statLabels.length; i++) { + if (cellIndex > maxColumnIndex) { + break; // 超出动态列数则停止 + } + // 指标名称单元格 + Cell labelCell = row2.createCell(cellIndex); + labelCell.setCellValue(statLabels[i]); + setCellStyle(labelCell, true, workbook); + + // 指标数值单元格(判断剩余列是否足够) + int valueCellIndex = cellIndex + 1; + if (valueCellIndex > maxColumnIndex) { + // 剩余列不足,合并单元格存放“名称+数值” + sheet.addMergedRegion(new CellRangeAddress(1, 1, cellIndex, maxColumnIndex)); + labelCell.setCellValue(statLabels[i] + ":" + statValues[i]); + break; + } else { + // 正常填充数值 + Cell valueCell = row2.createCell(valueCellIndex); + valueCell.setCellValue(statValues[i]); + setCellStyle(valueCell, false, workbook); + cellIndex = valueCellIndex + 1; + } + } + + // 4. 第3行:明细数据表头(反射获取@Excel注解) + Row headerRow = sheet.createRow(2); + Field[] fields = clazz.getDeclaredFields(); + int headerCellIndex = 0; + for (Field field : fields) { + Excel excel = field.getAnnotation(Excel.class); + if (excel != null && headerCellIndex < maxColumnNum) { // 不超过动态列数 + Cell headerCell = headerRow.createCell(headerCellIndex++); + headerCell.setCellValue(excel.name()); + setCellStyle(headerCell, true, workbook); + } + } + + // 5. 第4行开始:填充明细数据 + int dataRowNum = 3; + for (T data : dataList) { + Row dataRow = sheet.createRow(dataRowNum++); + int dataCellIndex = 0; + for (Field field : fields) { + Excel excel = field.getAnnotation(Excel.class); + if (excel != null && dataCellIndex < maxColumnNum) { // 不超过动态列数 + field.setAccessible(true); + Cell dataCell = dataRow.createCell(dataCellIndex++); + Object value = field.get(data); + if (value instanceof String) { + dataCell.setCellValue((String) value); + } else if (value instanceof Integer) { + dataCell.setCellValue((Integer) value); + } + setCellStyle(dataCell, false, workbook); + } + } + } + + // 6. 自动调整列宽(动态列数) + autoSizeColumns(sheet, maxColumnNum); + + // 7. 写入响应流 + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + response.setCharacterEncoding("utf-8"); + String fileName = URLEncoder.encode(sheetName, "UTF-8").replaceAll("\\+", "%20"); + response.setHeader("Content-disposition", "attachment;filename*=UTF-8''" + fileName + ".xlsx"); + try (OutputStream os = response.getOutputStream()) { + workbook.write(os); + os.flush(); + } + workbook.close(); + } + + /** + * 自定义单元格样式 + */ + private void setCellStyle(Cell cell, boolean isHeader, Workbook workbook) { + CellStyle style = workbook.createCellStyle(); + Font font = workbook.createFont(); + font.setFontName("微软雅黑"); + font.setFontHeightInPoints((short) 11); + + if (isHeader) { + font.setBold(true); + style.setFillForegroundColor((short) 22); // 浅灰色索引 + style.setFillPattern(FillPatternType.SOLID_FOREGROUND); + } + + style.setFont(font); + style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); + style.setBorderTop(BorderStyle.THIN); + style.setBorderBottom(BorderStyle.THIN); + style.setBorderLeft(BorderStyle.THIN); + style.setBorderRight(BorderStyle.THIN); + + cell.setCellStyle(style); + } + + /** + * 自动调整列宽(动态列数) + */ + private void autoSizeColumns(Sheet sheet, int columnCount) { + for (int i = 0; i < columnCount; i++) { + sheet.autoSizeColumn(i); + sheet.setColumnWidth(i, sheet.getColumnWidth(i) + 2000); + } + } +} \ No newline at end of file diff --git a/ruoyi-bussiness/src/main/resources/mapper/app/StaticsMapper.xml b/ruoyi-bussiness/src/main/resources/mapper/app/StaticsMapper.xml index 61c5110..bcdf96c 100644 --- a/ruoyi-bussiness/src/main/resources/mapper/app/StaticsMapper.xml +++ b/ruoyi-bussiness/src/main/resources/mapper/app/StaticsMapper.xml @@ -12,7 +12,7 @@ job_stats AS ( SELECT COUNT(*) AS 归集岗位合计,sum(case when type='4' then 1 else 0 end) 零工岗位数量, sum(case when type='4' then COALESCE(vacancies,0) else 0 end) 零工招聘人数 FROM job, time_params tp - WHERE (tp.start_time IS NULL OR posting_date >= tp.start_time) + WHERE del_flag='0' and (tp.start_time IS NULL OR posting_date >= tp.start_time) AND (tp.end_time IS NULL OR posting_date < tp.end_time) ), company_stats AS (