导出评估申请表格

This commit is contained in:
2026-05-15 13:43:20 +08:00
parent 76858d26a9
commit 0d9d77ea9e
3 changed files with 226 additions and 27 deletions

View File

@@ -6,6 +6,7 @@ import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
@@ -107,4 +108,18 @@ public class LbAssessmentApplyController {
return ResponseEntity.internalServerError().body(result);
}
@GetMapping("/export")
@Operation(summary = "导出申请评估Excel", description = "按租户ID与申请日期时间范围导出申请评估列表")
public void export(
@Parameter(description = "租户ID", required = true) @RequestParam String tenantId,
@Parameter(description = "申请开始时间格式yyyy-MM-dd HH:mm:ss", required = true)
@RequestParam String applicationDatetimeStart,
@Parameter(description = "申请结束时间格式yyyy-MM-dd HH:mm:ss", required = true)
@RequestParam String applicationDatetimeEnd,
HttpServletResponse response) {
lbAssessmentApplyService.exportExcel(
tenantId, applicationDatetimeStart, applicationDatetimeEnd, response
);
}
}

View File

@@ -2,6 +2,7 @@ package com.rj.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.rj.entity.LbAssessmentApply;
import jakarta.servlet.http.HttpServletResponse;
import java.util.Map;
@@ -29,4 +30,9 @@ public interface ILbAssessmentApplyService extends IService<LbAssessmentApply> {
*/
Map<String, Object> parseFromAssessmentTextByLlm(String assessmentText, String tenantId);
void exportExcel(String tenantId,
String applicationDatetimeStart,
String applicationDatetimeEnd,
HttpServletResponse response);
}

View File

@@ -14,14 +14,26 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.rj.entity.LbAssessmentApply;
import com.rj.mapper.LbAssessmentApplyMapper;
import com.rj.service.ILbAssessmentApplyService;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFColor;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Service;
import java.awt.Color;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
@@ -250,33 +262,10 @@ public class LbAssessmentApplyServiceImpl
size = 10;
}
LambdaQueryWrapper<LbAssessmentApply> queryWrapper = new LambdaQueryWrapper<>();
if (tenantId != null && !tenantId.trim().isEmpty()) {
queryWrapper.eq(LbAssessmentApply::getTenantId, tenantId.trim());
}
if (applicantName != null && !applicantName.trim().isEmpty()) {
queryWrapper.like(LbAssessmentApply::getApplicantName, applicantName.trim());
}
if (applicantPhone != null && !applicantPhone.trim().isEmpty()) {
queryWrapper.like(LbAssessmentApply::getApplicantPhone, applicantPhone.trim());
}
if (colleagueName != null && !colleagueName.trim().isEmpty()) {
queryWrapper.like(LbAssessmentApply::getColleagueName, colleagueName.trim());
}
if (teamLeaderName != null && !teamLeaderName.trim().isEmpty()) {
queryWrapper.like(LbAssessmentApply::getTeamLeaderName, teamLeaderName.trim());
}
if (assessmentTeacherName != null && !assessmentTeacherName.trim().isEmpty()) {
queryWrapper.like(LbAssessmentApply::getAssessmentTeacherName, assessmentTeacherName.trim());
}
if (moderatorName != null && !moderatorName.trim().isEmpty()) {
queryWrapper.like(LbAssessmentApply::getModeratorName, moderatorName.trim());
}
if (meetingNumber != null && !meetingNumber.trim().isEmpty()) {
queryWrapper.like(LbAssessmentApply::getMeetingNumber, meetingNumber.trim());
}
queryWrapper.orderByDesc(LbAssessmentApply::getUpdatedAt)
.orderByDesc(LbAssessmentApply::getCreatedAt);
LambdaQueryWrapper<LbAssessmentApply> queryWrapper = buildQueryWrapper(
tenantId, applicantName, applicantPhone, colleagueName, teamLeaderName,
assessmentTeacherName, moderatorName, meetingNumber
);
Page<LbAssessmentApply> page = this.page(new Page<>(current, size), queryWrapper);
result.put("success", true);
@@ -294,4 +283,193 @@ public class LbAssessmentApplyServiceImpl
return result;
}
}
@Override
public void exportExcel(String tenantId,
String applicationDatetimeStart,
String applicationDatetimeEnd,
HttpServletResponse response) {
try {
if (tenantId == null || tenantId.trim().isEmpty()) {
response.sendError(HttpServletResponse.SC_BAD_REQUEST, "tenantId不能为空");
return;
}
if (applicationDatetimeStart == null || applicationDatetimeStart.trim().isEmpty()) {
response.sendError(HttpServletResponse.SC_BAD_REQUEST, "applicationDatetimeStart不能为空");
return;
}
if (applicationDatetimeEnd == null || applicationDatetimeEnd.trim().isEmpty()) {
response.sendError(HttpServletResponse.SC_BAD_REQUEST, "applicationDatetimeEnd不能为空");
return;
}
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime start;
LocalDateTime end;
try {
start = LocalDateTime.parse(applicationDatetimeStart.trim(), formatter);
} catch (Exception e) {
response.sendError(HttpServletResponse.SC_BAD_REQUEST, "申请开始时间格式错误,请使用 yyyy-MM-dd HH:mm:ss");
return;
}
try {
end = LocalDateTime.parse(applicationDatetimeEnd.trim(), formatter);
} catch (Exception e) {
response.sendError(HttpServletResponse.SC_BAD_REQUEST, "申请结束时间格式错误,请使用 yyyy-MM-dd HH:mm:ss");
return;
}
if (start.isAfter(end)) {
response.sendError(HttpServletResponse.SC_BAD_REQUEST, "申请开始时间不能晚于结束时间");
return;
}
LambdaQueryWrapper<LbAssessmentApply> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(LbAssessmentApply::getTenantId, tenantId.trim())
.ge(LbAssessmentApply::getApplicationDatetime, start)
.le(LbAssessmentApply::getApplicationDatetime, end)
.orderByDesc(LbAssessmentApply::getApplicationDatetime);
List<LbAssessmentApply> rows = this.list(queryWrapper);
try (Workbook workbook = new XSSFWorkbook()) {
Sheet sheet = workbook.createSheet("申请评估");
CellStyle headerStyle = workbook.createCellStyle();
Font headerFont = workbook.createFont();
headerFont.setBold(true);
headerStyle.setFont(headerFont);
headerStyle.setAlignment(HorizontalAlignment.CENTER);
headerStyle.setVerticalAlignment(VerticalAlignment.CENTER);
headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
((XSSFCellStyle) headerStyle).setFillForegroundColor(new XSSFColor(new Color(255, 217, 102), null));
headerStyle.setBorderTop(BorderStyle.THIN);
headerStyle.setBorderBottom(BorderStyle.THIN);
headerStyle.setBorderLeft(BorderStyle.THIN);
headerStyle.setBorderRight(BorderStyle.THIN);
CellStyle dataStyle = workbook.createCellStyle();
dataStyle.setAlignment(HorizontalAlignment.CENTER);
dataStyle.setVerticalAlignment(VerticalAlignment.CENTER);
dataStyle.setBorderTop(BorderStyle.THIN);
dataStyle.setBorderBottom(BorderStyle.THIN);
dataStyle.setBorderLeft(BorderStyle.THIN);
dataStyle.setBorderRight(BorderStyle.THIN);
String[] headers = {
"序号", "申请人", "电话", "同事", "电话", "团队长", "全收益团队长",
"整理确定时间", "安排评估老师", "安排主持人", "会议号"
};
Row headerRow = sheet.createRow(0);
headerRow.setHeightInPoints(22);
for (int i = 0; i < headers.length; i++) {
createCell(headerRow, i, headers[i], headerStyle);
}
int rowIndex = 1;
for (LbAssessmentApply item : rows) {
Row row = sheet.createRow(rowIndex);
row.setHeightInPoints(20);
createCell(row, 0, String.valueOf(rowIndex), dataStyle);
createCell(row, 1, nullToEmpty(item.getApplicantName()), dataStyle);
createCell(row, 2, nullToEmpty(item.getApplicantPhone()), dataStyle);
createCell(row, 3, nullToEmpty(item.getColleagueName()), dataStyle);
createCell(row, 4, nullToEmpty(item.getColleaguePhone()), dataStyle);
createCell(row, 5, nullToEmpty(item.getTeamLeaderName()), dataStyle);
createCell(row, 6, "", dataStyle);
createCell(row, 7, formatApplicationDatetime(item.getApplicationDatetime()), dataStyle);
createCell(row, 8, nullToEmpty(item.getAssessmentTeacherName()), dataStyle);
createCell(row, 9, nullToEmpty(item.getModeratorName()), dataStyle);
createCell(row, 10, nullToEmpty(item.getMeetingNumber()), dataStyle);
rowIndex++;
}
for (int i = 0; i < headers.length; i++) {
sheet.autoSizeColumn(i);
int width = sheet.getColumnWidth(i);
sheet.setColumnWidth(i, Math.min(255 * 256, (int) (width * 1.2)));
}
String filename = "申请评估_" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")) + ".xlsx";
String encoded = URLEncoder.encode(filename, StandardCharsets.UTF_8).replaceAll("\\+", "%20");
response.setCharacterEncoding(StandardCharsets.UTF_8.name());
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename*=UTF-8''" + encoded);
try (ServletOutputStream os = response.getOutputStream()) {
workbook.write(os);
os.flush();
}
}
} catch (Exception e) {
log.error("申请评估导出异常", e);
try {
response.reset();
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
response.setCharacterEncoding(StandardCharsets.UTF_8.name());
response.setContentType("text/plain;charset=UTF-8");
response.getWriter().write("导出异常:" + e.getMessage());
} catch (Exception ignored) {
// ignore
}
}
}
private LambdaQueryWrapper<LbAssessmentApply> buildQueryWrapper(String tenantId,
String applicantName,
String applicantPhone,
String colleagueName,
String teamLeaderName,
String assessmentTeacherName,
String moderatorName,
String meetingNumber) {
LambdaQueryWrapper<LbAssessmentApply> queryWrapper = new LambdaQueryWrapper<>();
if (tenantId != null && !tenantId.trim().isEmpty()) {
queryWrapper.eq(LbAssessmentApply::getTenantId, tenantId.trim());
}
if (applicantName != null && !applicantName.trim().isEmpty()) {
queryWrapper.like(LbAssessmentApply::getApplicantName, applicantName.trim());
}
if (applicantPhone != null && !applicantPhone.trim().isEmpty()) {
queryWrapper.like(LbAssessmentApply::getApplicantPhone, applicantPhone.trim());
}
if (colleagueName != null && !colleagueName.trim().isEmpty()) {
queryWrapper.like(LbAssessmentApply::getColleagueName, colleagueName.trim());
}
if (teamLeaderName != null && !teamLeaderName.trim().isEmpty()) {
queryWrapper.like(LbAssessmentApply::getTeamLeaderName, teamLeaderName.trim());
}
if (assessmentTeacherName != null && !assessmentTeacherName.trim().isEmpty()) {
queryWrapper.like(LbAssessmentApply::getAssessmentTeacherName, assessmentTeacherName.trim());
}
if (moderatorName != null && !moderatorName.trim().isEmpty()) {
queryWrapper.like(LbAssessmentApply::getModeratorName, moderatorName.trim());
}
if (meetingNumber != null && !meetingNumber.trim().isEmpty()) {
queryWrapper.like(LbAssessmentApply::getMeetingNumber, meetingNumber.trim());
}
queryWrapper.orderByDesc(LbAssessmentApply::getUpdatedAt)
.orderByDesc(LbAssessmentApply::getCreatedAt);
return queryWrapper;
}
private static String nullToEmpty(String value) {
return value == null ? "" : value;
}
private static String formatApplicationDatetime(LocalDateTime datetime) {
if (datetime == null) {
return "";
}
if (datetime.getMinute() == 0 && datetime.getSecond() == 0) {
return datetime.getMonthValue() + "." + datetime.getDayOfMonth() + "" + datetime.getHour() + "";
}
return datetime.format(DateTimeFormatter.ofPattern("M月d日 H:mm"));
}
private static void createCell(Row row, int col, String text, CellStyle style) {
Cell cell = row.createCell(col);
cell.setCellValue(text);
cell.setCellStyle(style);
}
}