refactor(system): 优化日志实例导出功能
- 使用 EasyExcel 替代 ExcelUtils 写入 Excel 文件 - 添加单元格合并功能 - 优化表格样式,包括列宽自适应、居中对齐等 -增加部门编号筛选条件 - 调整日志数据查询逻辑,提高效率
This commit is contained in:
parent
d83dca6b87
commit
cdb4d79822
@ -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<LogExportExcelVO> list = logInstanceService.getLogInstanceExport(reqVO);
|
||||
// 导出 Excel
|
||||
ExcelUtils.write(response, "日志实例的拓展.xls", "数据", LogExportExcelVO.class,
|
||||
list);
|
||||
|
||||
|
||||
// 输出excel
|
||||
ExcelWriterBuilder writer = EasyExcel.write(response.getOutputStream(), LogExportExcelVO.class);
|
||||
|
||||
List<OnceAbsoluteMergeStrategy> 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<OnceAbsoluteMergeStrategy> getMergeStrategy(List<LogExportExcelVO> dataList) {
|
||||
List<OnceAbsoluteMergeStrategy> strategies = new ArrayList<>();
|
||||
List<Integer> 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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
@ -7,6 +7,9 @@ import lombok.Data;
|
||||
@Data
|
||||
public class LogExportVO {
|
||||
|
||||
@Schema(description = "部门编号")
|
||||
private Long companyDeptId;
|
||||
|
||||
@Schema(description = "日志模版编号")
|
||||
private Long formId;
|
||||
|
||||
|
@ -142,7 +142,8 @@ public class LogInstanceServiceImpl implements LogInstanceService {
|
||||
List<LogReadUserRespDTO> respDTOS = logInstanceMapper.selectRaedUser(userId, adminUserDO.getDeptId());
|
||||
|
||||
//特殊情况, 日志发起人为研发部时 手动添加查看者
|
||||
if (adminUserDO.getDeptId() == 128L && adminUserDO.getId() != 126L) {
|
||||
List<Long> 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<LogExportExcelVO> getLogInstanceExport(LogExportVO reqVO) {
|
||||
List<LogInstanceDO> list = logInstanceMapper.selectList(new LambdaQueryWrapperX<LogInstanceDO>()
|
||||
.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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user