diff --git a/server/common/src/main/java/com/xaaef/molly/common/util/ExcelUtils.java b/server/common/src/main/java/com/xaaef/molly/common/util/ExcelUtils.java index 352f06e..fb14e77 100644 --- a/server/common/src/main/java/com/xaaef/molly/common/util/ExcelUtils.java +++ b/server/common/src/main/java/com/xaaef/molly/common/util/ExcelUtils.java @@ -1,13 +1,12 @@ package com.xaaef.molly.common.util; -import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.date.DatePattern; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.ReflectUtil; -import cn.hutool.core.util.StrUtil; import io.swagger.v3.oas.annotations.media.Schema; import lombok.extern.slf4j.Slf4j; +import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFCellStyle; import org.apache.poi.hssf.usermodel.HSSFRow; import org.apache.poi.hssf.usermodel.HSSFWorkbook; @@ -18,7 +17,6 @@ import org.springframework.http.ResponseEntity; import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.lang.reflect.Field; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.time.LocalDate; @@ -57,7 +55,7 @@ public class ExcelUtils { if (!dataList.isEmpty()) { // 获取设备的总数量 int total = dataList.size(); - int pageSize = 10000; + int pageSize = 1000; if (total > pageSize) { int pages = (total / pageSize) + 1; var startIndex = new AtomicInteger(0); @@ -88,82 +86,84 @@ public class ExcelUtils { * @date 2023/11/23 12:32 */ private static void pageExport(HSSFWorkbook workbook, String sheetName, List rangeData) { + if (rangeData.isEmpty()) { + return; + } // 反射获取对象属性,和描述名称 - var fieldNames = getFieldSchemaNames(CollectionUtil.getFirst(rangeData)); + var schemaDescriptions = getFieldSchemaDescription(CollectionUtil.getFirst(rangeData)); //创建工作表,指定工作表名称 var sheet1 = workbook.createSheet(sheetName); sheet1.setDefaultColumnWidth(20); var titleRow = sheet1.createRow(0); // 设置标题 - setTitle(titleRow, createTitleStyle(workbook), fieldNames); - - var cellNum = fieldNames.size(); + setTitleStyle(titleRow, createTitleStyle(workbook), schemaDescriptions); + var cellNum = schemaDescriptions.size(); for (int ind = 0; ind < rangeData.size(); ind++) { - var a1 = rangeData.get(ind); - var row1 = sheet1.createRow((ind + 1)); - var fieldsValue = ReflectUtil.getFieldsValue(a1); + var data = rangeData.get(ind); + var row = sheet1.createRow((ind + 1)); + var fieldsValue = ReflectUtil.getFieldsValue(data); for (int v = 0; v < cellNum; v++) { - var cell0 = row1.createCell(v); - cell0.setCellType(CellType.STRING); - var obj = fieldsValue[v]; - if (obj == null) { - cell0.setCellValue(StrUtil.EMPTY); - break; - } - if (obj instanceof Number o1) { - cell0.setCellValue(o1.toString()); - } - /* - else if (obj instanceof Integer o1) { - cell0.setCellValue(o1); - } else if (obj instanceof Short o1) { - cell0.setCellValue(o1); - } else if (obj instanceof Float o1) { - cell0.setCellValue(o1); - } else if (obj instanceof Double o1) { - cell0.setCellValue(o1); - } else if (obj instanceof Byte o1) { - cell0.setCellValue(o1); - } - */ - else if (obj instanceof String o1) { - cell0.setCellValue(o1); - } else if (obj instanceof Boolean o1) { - cell0.setCellValue(o1); - } else if (obj instanceof Date o1) { - cell0.setCellValue(DateUtil.formatDateTime(o1)); - } else if (obj instanceof LocalDate o1) { - cell0.setCellValue(o1.format(DatePattern.NORM_DATE_FORMATTER)); - } else if (obj instanceof LocalTime o1) { - cell0.setCellValue(o1.format(DatePattern.NORM_TIME_FORMATTER)); - } else if (obj instanceof LocalDateTime o1) { - cell0.setCellValue(o1.format(DatePattern.NORM_DATETIME_FORMATTER)); - } else if (obj instanceof ZonedDateTime o1) { - cell0.setCellValue(o1.format(DatePattern.NORM_DATETIME_FORMATTER)); - } else if (obj instanceof Iterable || obj.getClass().isArray()) { - cell0.setCellValue(JsonUtils.toFormatJson(obj)); - } else if (obj instanceof Map || obj instanceof Enum) { - cell0.setCellValue(JsonUtils.toFormatJson(obj)); - } else { - var fieldMaps = getFieldNameAndSchema(obj); - var valMaps = BeanUtil.beanToMap(obj); - var sb = new StringBuilder(); - valMaps.forEach((key, val) -> sb.append(StrUtil.format("{} = {} \r\n", fieldMaps.get(key), val))); - cell0.setCellValue(sb.toString()); - } + var cell = row.createCell(v); + var val = fieldsValue[v]; + setCellValue(cell, val); } } } /** - * 反射获取对象属性,和描述名称 - * - * @author WangChenChen - * @version 2.0 - * @date 2023/11/29 18:04 + * 根据 对象类型 格式化之后设置到单元格内 */ - private static List getFieldSchemaNames(Object obj) { + private static void setCellValue(HSSFCell cell, Object obj) { + if (obj == null) { + cell.setCellType(CellType.BLANK); + return; + } + if (obj instanceof Number) { + cell.setCellType(CellType.NUMERIC); + if (obj instanceof Long o2) { + cell.setCellValue(o2); + } else if (obj instanceof Integer o2) { + cell.setCellValue(o2); + } else if (obj instanceof Short o2) { + cell.setCellValue(o2); + } else if (obj instanceof Float o2) { + cell.setCellValue(o2); + } else if (obj instanceof Double o2) { + cell.setCellValue(o2); + } else if (obj instanceof Byte o2) { + cell.setCellValue(o2); + } + } else { + cell.setCellType(CellType.STRING); + if (obj instanceof String o1) { + cell.setCellValue(o1); + } else if (obj instanceof Boolean o1) { + cell.setCellType(CellType.BOOLEAN); + cell.setCellValue(o1); + } else if (obj instanceof Date o1) { + cell.setCellValue(DateUtil.formatDateTime(o1)); + } else if (obj instanceof LocalDate o1) { + cell.setCellValue(o1.format(DatePattern.NORM_DATE_FORMATTER)); + } else if (obj instanceof LocalTime o1) { + cell.setCellValue(o1.format(DatePattern.NORM_TIME_FORMATTER)); + } else if (obj instanceof LocalDateTime o1) { + cell.setCellValue(o1.format(DatePattern.NORM_DATETIME_FORMATTER)); + } else if (obj instanceof ZonedDateTime o1) { + cell.setCellValue(o1.format(DatePattern.NORM_DATETIME_FORMATTER)); + } else if (obj instanceof Iterable || obj.getClass().isArray() || obj instanceof Map || obj instanceof Enum) { + cell.setCellValue(JsonUtils.toFormatJson(obj)); + } else { + cell.setCellValue(obj.toString()); + } + } + } + + + /** + * 反射获取 对象属性 @Schema注解上的description + */ + private static List getFieldSchemaDescription(Object obj) { return Arrays.stream(ReflectUtil.getFields(obj.getClass())) .map(field -> { var ann = field.getAnnotation(Schema.class); @@ -173,25 +173,6 @@ public class ExcelUtils { } - /** - * 反射获取对象属性,和描述名称 - * - * @author WangChenChen - * @version 2.0 - * @date 2023/11/29 18:04 - */ - private static Map getFieldNameAndSchema(Object obj) { - return Arrays.stream(ReflectUtil.getFields(obj.getClass())) - .collect( - Collectors.toMap(Field::getName, field -> { - var ann = field.getAnnotation(Schema.class); - return ann == null ? field.getName() : ann.description(); - } - ) - ); - } - - /** * 获取一个 Workbook * @@ -235,7 +216,7 @@ public class ExcelUtils { /** - * 创建标题样式 + * 创建 标题 样式 * * @date 2023/11/23 11:20 */ @@ -255,11 +236,11 @@ public class ExcelUtils { /** - * 设置 标题 + * 设置 标题 样式 * * @date 2023/11/23 11:20 */ - private static void setTitle(HSSFRow titleRow, HSSFCellStyle titleStyle, List titleName) { + private static void setTitleStyle(HSSFRow titleRow, HSSFCellStyle titleStyle, List titleName) { for (int index = 0; index < titleName.size(); index++) { var cell = titleRow.createCell(index); cell.setCellStyle(titleStyle); diff --git a/server/internal-api/src/main/java/com/xaaef/molly/internal/dto/OperateUserDTO.java b/server/internal-api/src/main/java/com/xaaef/molly/internal/dto/OperateUserDTO.java index 105726e..8656913 100644 --- a/server/internal-api/src/main/java/com/xaaef/molly/internal/dto/OperateUserDTO.java +++ b/server/internal-api/src/main/java/com/xaaef/molly/internal/dto/OperateUserDTO.java @@ -28,7 +28,7 @@ public class OperateUserDTO implements java.io.Serializable { /** * 用户唯一id */ - @Schema(description = "用户唯一id") + @Schema(description = "用户Id") private Long userId; /** @@ -43,4 +43,9 @@ public class OperateUserDTO implements java.io.Serializable { @Schema(description = "昵称") private String nickname; + @Override + public String toString() { + return String.format("用户Id : %s\n头像 : %s\n昵称 : %s", this.userId, this.avatar, this.nickname); + } + } diff --git a/server/molly-service/aa.xlsx b/server/molly-service/aa.xlsx deleted file mode 100644 index 69dc5ac..0000000 Binary files a/server/molly-service/aa.xlsx and /dev/null differ diff --git a/server/molly-service/src/test/java/com/xaaef/molly/NoSpringTests.java b/server/molly-service/src/test/java/com/xaaef/molly/NoSpringTests.java index 211fcfd..99227c5 100644 --- a/server/molly-service/src/test/java/com/xaaef/molly/NoSpringTests.java +++ b/server/molly-service/src/test/java/com/xaaef/molly/NoSpringTests.java @@ -5,6 +5,7 @@ import cn.hutool.core.lang.tree.Tree; import cn.hutool.core.lang.tree.TreeNode; import cn.hutool.core.lang.tree.TreeUtil; import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.RandomUtil; import com.mysql.cj.jdbc.MysqlDataSource; import com.xaaef.molly.auth.jwt.JwtSecurityUtils; import com.xaaef.molly.common.consts.JwtConst; @@ -25,6 +26,7 @@ import java.time.Duration; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.regex.Pattern; @@ -148,6 +150,9 @@ public class NoSpringTests { @Schema(description = "爱好") protected List hobby; + @Schema(description = "长辈") + protected Map elder; + @Schema(description = "创建日期") protected LocalDate createDate; @@ -165,16 +170,33 @@ public class NoSpringTests { @Test public void test12() throws IOException { - var treeNodes = List.of( - new TestExportEntity(1001L, "角色1", List.of("A1", "B1"), LocalDate.now(), LocalTime.now(), LocalDateTime.now(), new OperateUserDTO(1L, "a", "张三")), - new TestExportEntity(1002L, "角色2", List.of("A2", "B2"), LocalDate.now(), LocalTime.now(), LocalDateTime.now(), new OperateUserDTO(2L, "b", "李四")), - new TestExportEntity(1003L, "角色3", List.of("A3", "B3"), LocalDate.now(), LocalTime.now(), LocalDateTime.now(), new OperateUserDTO(3L, "c", "王五")), - new TestExportEntity(1004L, "角色4", List.of("A4", "B4"), LocalDate.now(), LocalTime.now(), LocalDateTime.now(), new OperateUserDTO(4L, "d", "陈六")), - new TestExportEntity(1005L, "角色5", List.of("A5", "B5"), LocalDate.now(), LocalTime.now(), LocalDateTime.now(), new OperateUserDTO(5L, "e", "赵七")) - ); - var entity = ExcelUtils.deviceExport("aa.xlsx", treeNodes); - var file = Files.createFile(Path.of("aa.xlsx")).toFile(); + List source = List.of("A1", "B1", "C3", "D4", "E5", "F6", "S7"); + var dataList = new ArrayList(); + for (int i = 0; i < 10000; i++) { + dataList.add( + new TestExportEntity( + RandomUtil.randomLong(1999999999L, 9999999999L), + RandomUtil.randomString(20), + RandomUtil.randomEleList(source, 3), + Map.of(String.valueOf(new char[]{RandomUtil.randomChinese(), RandomUtil.randomChinese(), RandomUtil.randomChinese()}), RandomUtil.randomLong(40, 88)), + LocalDate.now(), + LocalTime.now(), + LocalDateTime.now(), + new OperateUserDTO( + RandomUtil.randomLong(), + "a", + String.valueOf(new char[]{RandomUtil.randomChinese(), RandomUtil.randomChinese(), RandomUtil.randomChinese()} + ) + ) + ) + ); + } + var start = System.currentTimeMillis(); + var entity = ExcelUtils.deviceExport("aa.xlsx", dataList); + var file = Files.createFile(Path.of(String.format("%s.xlsx", RandomUtil.randomString(10)))).toFile(); FileUtil.writeFromStream(entity.getBody().getInputStream(), file, true); + var ms = System.currentTimeMillis() - start; + System.out.printf("%s => 耗时: %d ms \n", file.getName(), ms); }