From cdb4d79822868d7a3527419005795b53fcada12e Mon Sep 17 00:00:00 2001 From: furongxin <419481438@qq.com> Date: Sun, 9 Mar 2025 10:27:12 +0800 Subject: [PATCH] =?UTF-8?q?refactor(system):=20=E4=BC=98=E5=8C=96=E6=97=A5?= =?UTF-8?q?=E5=BF=97=E5=AE=9E=E4=BE=8B=E5=AF=BC=E5=87=BA=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 使用 EasyExcel 替代 ExcelUtils 写入 Excel 文件 - 添加单元格合并功能 - 优化表格样式,包括列宽自适应、居中对齐等 -增加部门编号筛选条件 - 调整日志数据查询逻辑,提高效率 --- .../admin/worklog/LogInstanceController.java | 82 +++++++++++++++++-- .../vo/loginstance/LogExportExcelVO.java | 2 - .../worklog/vo/loginstance/LogExportVO.java | 3 + .../worklog/LogInstanceServiceImpl.java | 26 +++--- 4 files changed, 91 insertions(+), 22 deletions(-) diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/worklog/LogInstanceController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/worklog/LogInstanceController.java index 087946e3..846537a0 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/worklog/LogInstanceController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/worklog/LogInstanceController.java @@ -2,10 +2,8 @@ package cn.iocoder.yudao.module.system.controller.admin.worklog; import cn.hutool.core.collection.CollectionUtil; import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission; -import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptRespVO; import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserRespVO; @@ -21,10 +19,20 @@ import cn.iocoder.yudao.module.system.service.user.AdminUserService; import cn.iocoder.yudao.module.system.service.worklog.LogInstanceService; import cn.iocoder.yudao.module.system.service.worklog.LogReadService; import cn.iocoder.yudao.module.system.service.worklog.LogUseService; +import com.alibaba.excel.EasyExcel; +import com.alibaba.excel.converters.longconverter.LongStringConverter; +import com.alibaba.excel.support.ExcelTypeEnum; +import com.alibaba.excel.write.builder.ExcelWriterBuilder; +import com.alibaba.excel.write.merge.OnceAbsoluteMergeStrategy; +import com.alibaba.excel.write.metadata.style.WriteCellStyle; +import com.alibaba.excel.write.style.HorizontalCellStyleStrategy; +import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy; import com.baomidou.mybatisplus.core.metadata.IPage; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; +import org.apache.poi.ss.usermodel.HorizontalAlignment; +import org.apache.poi.ss.usermodel.VerticalAlignment; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -33,10 +41,9 @@ import javax.annotation.Resource; import javax.servlet.http.HttpServletResponse; import javax.validation.Valid; import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.*; import java.util.stream.Collectors; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; @@ -310,8 +317,65 @@ public class LogInstanceController { HttpServletResponse response) throws IOException { List list = logInstanceService.getLogInstanceExport(reqVO); - // 导出 Excel - ExcelUtils.write(response, "日志实例的拓展.xls", "数据", LogExportExcelVO.class, - list); + + + // 输出excel + ExcelWriterBuilder writer = EasyExcel.write(response.getOutputStream(), LogExportExcelVO.class); + + List strategies = getMergeStrategy(list); + strategies.forEach(writer::registerWriteHandler); + + writer.autoCloseStream(false); // 不要自动关闭,交给 Servlet 自己处理 + writer.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()); // 基于 column 长度,自动适配。最大 255 宽度 + writer.registerWriteHandler(new HorizontalCellStyleStrategy(getHeadStyle(), getContentStyle())); + writer.registerConverter(new LongStringConverter()); // 避免 Long 类型丢失精度 + writer.excelType(ExcelTypeEnum.XLS); + writer.sheet("数据").doWrite(list); + + // 设置 header 和 contentType。写在最后的原因是,避免报错时,响应 contentType 已经被修改了 + response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("日志实例的拓展.xls", StandardCharsets.UTF_8.name())); + response.setContentType("application/vnd.ms-excel;charset=UTF-8"); + + +// // 导出 Excel +// ExcelUtils.write(response, "日志实例的拓展.xls", "数据", LogExportExcelVO.class, +// list); + } + + public static List getMergeStrategy(List dataList) { + List strategies = new ArrayList<>(); + List mergeCols = Arrays.asList(0, 1); // 需要合并的列索引 + + // 遍历数据,生成合并区间 + for (int i = 0; i < dataList.size(); i++) { + if (i > 0 && dataList.get(i).getNickname().equals(dataList.get(i - 1).getNickname()) && dataList.get(i).getTime().equals(dataList.get(i - 1).getTime())) { + continue; + } + int startRow = i + 1; + while (i < dataList.size() - 1 && dataList.get(i).getNickname().equals(dataList.get(i + 1).getNickname()) && dataList.get(i).getTime().equals(dataList.get(i + 1).getTime())) { + i++; + } + for (int col : mergeCols) { + strategies.add(new OnceAbsoluteMergeStrategy(startRow, i + 1, col, col)); + } + } + return strategies; + } + + // 表头样式(居中) + public static WriteCellStyle getHeadStyle() { + WriteCellStyle headStyle = new WriteCellStyle(); + headStyle.setHorizontalAlignment(HorizontalAlignment.CENTER); + headStyle.setVerticalAlignment(VerticalAlignment.CENTER); + return headStyle; + } + + // 内容样式(居中) + public static WriteCellStyle getContentStyle() { + WriteCellStyle contentStyle = new WriteCellStyle(); + contentStyle.setWrapped(true); // 启用自动换行 + contentStyle.setHorizontalAlignment(HorizontalAlignment.CENTER); + contentStyle.setVerticalAlignment(VerticalAlignment.CENTER); + return contentStyle; } } \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/worklog/vo/loginstance/LogExportExcelVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/worklog/vo/loginstance/LogExportExcelVO.java index 87a0d907..63b8d07b 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/worklog/vo/loginstance/LogExportExcelVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/worklog/vo/loginstance/LogExportExcelVO.java @@ -1,7 +1,5 @@ package cn.iocoder.yudao.module.system.controller.admin.worklog.vo.loginstance; -import cn.iocoder.yudao.framework.common.validation.IdCard; -import cn.iocoder.yudao.framework.common.validation.Mobile; import com.alibaba.excel.annotation.ExcelProperty; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/worklog/vo/loginstance/LogExportVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/worklog/vo/loginstance/LogExportVO.java index 606aaa50..36e393e4 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/worklog/vo/loginstance/LogExportVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/worklog/vo/loginstance/LogExportVO.java @@ -7,6 +7,9 @@ import lombok.Data; @Data public class LogExportVO { + @Schema(description = "部门编号") + private Long companyDeptId; + @Schema(description = "日志模版编号") private Long formId; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/worklog/LogInstanceServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/worklog/LogInstanceServiceImpl.java index ca16217d..f944ff26 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/worklog/LogInstanceServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/worklog/LogInstanceServiceImpl.java @@ -142,7 +142,8 @@ public class LogInstanceServiceImpl implements LogInstanceService { List respDTOS = logInstanceMapper.selectRaedUser(userId, adminUserDO.getDeptId()); //特殊情况, 日志发起人为研发部时 手动添加查看者 - if (adminUserDO.getDeptId() == 128L && adminUserDO.getId() != 126L) { + List deptIds = convertList(deptService.getChildDept(128L), DeptDO::getId); + if (deptIds.contains(adminUserDO.getDeptId()) && adminUserDO.getId() != 126L) { LogReadUserRespDTO dto = new LogReadUserRespDTO(); dto.setUserId(126L); @@ -450,6 +451,7 @@ public class LogInstanceServiceImpl implements LogInstanceService { @Override public List getLogInstanceExport(LogExportVO reqVO) { List list = logInstanceMapper.selectList(new LambdaQueryWrapperX() + .eqIfPresent(LogInstanceDO::getDeptId, reqVO.getCompanyDeptId()) .eqIfPresent(LogInstanceDO::getFormId, reqVO.getFormId()) .betweenIfPresent(LogInstanceDO::getTime, reqVO.getTime())); @@ -469,16 +471,6 @@ public class LogInstanceServiceImpl implements LogInstanceService { //遍历 for (LogInstanceDO item : list) { - LogExportExcelVO logExportExcelVO = new LogExportExcelVO(); - - // 设置时间 - logExportExcelVO.setTime(item.getTime()); - - //设置发起人用户名称和头像 - AdminUserDO userDO = userMap.get(item.getStartUserId()); - if (userDO != null) { - logExportExcelVO.setNickname(userDO.getNickname()); - } //设置日志内部分an LogFormDO logFormDO = formMap.get(item.getFormId()); @@ -496,6 +488,18 @@ public class LogInstanceServiceImpl implements LogInstanceService { continue; } String field = workLogContentJson.getStr(fieldStr); + + LogExportExcelVO logExportExcelVO = new LogExportExcelVO(); + + // 设置时间 + logExportExcelVO.setTime(item.getTime()); + + //设置发起人用户名称和头像 + AdminUserDO userDO = userMap.get(item.getStartUserId()); + if (userDO != null) { + logExportExcelVO.setNickname(userDO.getNickname()); + } + logExportExcelVO.setTitle(title); logExportExcelVO.setContent(field);