From e02950a1dc88bdeb0747fd8778dcb9b3b2383854 Mon Sep 17 00:00:00 2001 From: eden Date: Thu, 3 Nov 2022 16:38:26 +0800 Subject: [PATCH] =?UTF-8?q?excel=20=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 --- .../controller/SysLogLoginController.java | 12 +- .../system/service/SysLogLoginService.java | 17 +++ .../service/impl/SysLogLoginServiceImpl.java | 29 +++++ .../net/maku/system/vo/SysLogLoginVO.java | 50 +++++++- maku-framework/pom.xml | 4 + .../framework/common/excel/DateConverter.java | 39 ++++++ .../common/excel/ExcelDataListener.java | 61 ++++++++++ .../common/excel/ExcelFinishCallBack.java | 29 +++++ .../framework/common/utils/ExcelUtils.java | 112 ++++++++++++++++++ .../src/main/resources/application-dev.yml | 10 +- .../src/test/java/net/maku/EasyExcelTest.java | 82 +++++++++++++ pom.xml | 8 +- 12 files changed, 445 insertions(+), 8 deletions(-) create mode 100644 maku-framework/src/main/java/net/maku/framework/common/excel/DateConverter.java create mode 100644 maku-framework/src/main/java/net/maku/framework/common/excel/ExcelDataListener.java create mode 100644 maku-framework/src/main/java/net/maku/framework/common/excel/ExcelFinishCallBack.java create mode 100644 maku-framework/src/main/java/net/maku/framework/common/utils/ExcelUtils.java create mode 100644 maku-server/src/test/java/net/maku/EasyExcelTest.java diff --git a/maku-boot-system/src/main/java/net/maku/system/controller/SysLogLoginController.java b/maku-boot-system/src/main/java/net/maku/system/controller/SysLogLoginController.java index 5a848c9..25dc96a 100644 --- a/maku-boot-system/src/main/java/net/maku/system/controller/SysLogLoginController.java +++ b/maku-boot-system/src/main/java/net/maku/system/controller/SysLogLoginController.java @@ -14,6 +14,8 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.validation.Valid; +import java.io.IOException; +import java.util.Map; /** * 登录日志 @@ -35,5 +37,13 @@ public class SysLogLoginController { return Result.ok(page); } - + + @GetMapping("export") + @Operation(summary = "导出excel") + public Result> export() throws IOException { + Map map = sysLogLoginService.export(); + + return Result.ok(map); + } + } \ No newline at end of file diff --git a/maku-boot-system/src/main/java/net/maku/system/service/SysLogLoginService.java b/maku-boot-system/src/main/java/net/maku/system/service/SysLogLoginService.java index ffb8233..8723d4d 100644 --- a/maku-boot-system/src/main/java/net/maku/system/service/SysLogLoginService.java +++ b/maku-boot-system/src/main/java/net/maku/system/service/SysLogLoginService.java @@ -6,6 +6,9 @@ import net.maku.system.entity.SysLogLoginEntity; import net.maku.system.query.SysLogLoginQuery; import net.maku.system.vo.SysLogLoginVO; +import java.io.IOException; +import java.util.Map; + /** * 登录日志 * @@ -13,6 +16,12 @@ import net.maku.system.vo.SysLogLoginVO; */ public interface SysLogLoginService extends BaseService { + /** + * Page page result. + * + * @param query the query + * @return the page result + */ PageResult page(SysLogLoginQuery query); /** @@ -23,4 +32,12 @@ public interface SysLogLoginService extends BaseService { * @param operation 操作信息 */ void save(String username, Integer status, Integer operation); + + /** + * 导出登录日志 + * + * @return the map + * @throws IOException the io exception + */ + Map export() throws IOException; } \ No newline at end of file diff --git a/maku-boot-system/src/main/java/net/maku/system/service/impl/SysLogLoginServiceImpl.java b/maku-boot-system/src/main/java/net/maku/system/service/impl/SysLogLoginServiceImpl.java index d035182..af1adfc 100644 --- a/maku-boot-system/src/main/java/net/maku/system/service/impl/SysLogLoginServiceImpl.java +++ b/maku-boot-system/src/main/java/net/maku/system/service/impl/SysLogLoginServiceImpl.java @@ -1,5 +1,6 @@ package net.maku.system.service.impl; +import cn.hutool.core.io.IoUtil; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; @@ -8,8 +9,10 @@ import lombok.AllArgsConstructor; import net.maku.framework.common.page.PageResult; import net.maku.framework.common.service.impl.BaseServiceImpl; import net.maku.framework.common.utils.AddressUtils; +import net.maku.framework.common.utils.ExcelUtils; import net.maku.framework.common.utils.HttpContextUtils; import net.maku.framework.common.utils.IpUtils; +import net.maku.storage.service.StorageService; import net.maku.system.convert.SysLogLoginConvert; import net.maku.system.dao.SysLogLoginDao; import net.maku.system.entity.SysLogLoginEntity; @@ -20,6 +23,12 @@ import org.springframework.http.HttpHeaders; import org.springframework.stereotype.Service; import javax.servlet.http.HttpServletRequest; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.util.HashMap; +import java.util.List; +import java.util.Map; /** * 登录日志 @@ -30,6 +39,8 @@ import javax.servlet.http.HttpServletRequest; @AllArgsConstructor public class SysLogLoginServiceImpl extends BaseServiceImpl implements SysLogLoginService { + private final StorageService storageService; + @Override public PageResult page(SysLogLoginQuery query) { IPage page = baseMapper.selectPage(getPage(query), getWrapper(query)); @@ -66,4 +77,22 @@ public class SysLogLoginServiceImpl extends BaseServiceImpl export() throws IOException { + List list = list(); + List sysLogLoginVOS = SysLogLoginConvert.INSTANCE.convertList(list); + File file = File.createTempFile("log_excel", ".xlsx"); + // 写入到文件 + ExcelUtils.excelExport(SysLogLoginVO.class, file, sysLogLoginVOS); + + byte[] data = IoUtil.readBytes(Files.newInputStream(file.toPath())); + + String path = storageService.getPath(file.getName()); + String url = storageService.upload(data, path); + Map map = new HashMap<>(); + map.put("path", url); + map.put("filename", file.getName()); + return map; + } + } \ No newline at end of file diff --git a/maku-boot-system/src/main/java/net/maku/system/vo/SysLogLoginVO.java b/maku-boot-system/src/main/java/net/maku/system/vo/SysLogLoginVO.java index 85fd594..e0e23ed 100644 --- a/maku-boot-system/src/main/java/net/maku/system/vo/SysLogLoginVO.java +++ b/maku-boot-system/src/main/java/net/maku/system/vo/SysLogLoginVO.java @@ -1,8 +1,15 @@ package net.maku.system.vo; +import com.alibaba.excel.annotation.ExcelIgnore; +import com.alibaba.excel.annotation.ExcelProperty; +import com.alibaba.excel.converters.Converter; +import com.alibaba.excel.metadata.GlobalConfiguration; +import com.alibaba.excel.metadata.data.WriteCellData; +import com.alibaba.excel.metadata.property.ExcelContentProperty; import com.fasterxml.jackson.annotation.JsonFormat; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; +import net.maku.framework.common.excel.DateConverter; import net.maku.framework.common.utils.DateUtils; import java.io.Serializable; @@ -18,29 +25,70 @@ import java.util.Date; public class SysLogLoginVO implements Serializable { private static final long serialVersionUID = 1L; + @ExcelIgnore @Schema(description = "id") private Long id; + @ExcelProperty("用户名") @Schema(description = "用户名") private String username; + @ExcelProperty("登录IP") @Schema(description = "登录IP") private String ip; + @ExcelProperty("登录地点") @Schema(description = "登录地点") private String address; + @ExcelProperty("User Agent") @Schema(description = "User Agent") private String userAgent; + @ExcelProperty(value = "登录状态", converter = StatusConverter.class) @Schema(description = "登录状态 0:失败 1:成功") private Integer status; + @ExcelProperty(value = "操作信息", converter = OperationConverter.class) @Schema(description = "操作信息 0:登录成功 1:退出成功 2:验证码错误 3:账号密码错误") private Integer operation; + @ExcelProperty(value = "创建时间", converter = DateConverter.class) @Schema(description = "创建时间") @JsonFormat(pattern = DateUtils.DATE_TIME_PATTERN) private Date createTime; - + + + public static class StatusConverter implements Converter { + + @Override + public WriteCellData convertToExcelData(Integer value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { + String dateValue = ""; + if (value == 0) { + dateValue = "失败"; + } else if (value == 1) { + dateValue = "成功"; + } + return new WriteCellData<>(dateValue); + } + } + + public static class OperationConverter implements Converter { + + @Override + public WriteCellData convertToExcelData(Integer value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { + String dateValue = ""; + if (value == 0) { + dateValue = "登录成功"; + } else if (value == 1) { + dateValue = "退出成功"; + } else if (value == 2) { + dateValue = "验证码错误"; + } else if (value == 3) { + dateValue = "账号密码错误"; + } + return new WriteCellData<>(dateValue); + } + } + } \ No newline at end of file diff --git a/maku-framework/pom.xml b/maku-framework/pom.xml index 867c44c..8cefa44 100644 --- a/maku-framework/pom.xml +++ b/maku-framework/pom.xml @@ -60,5 +60,9 @@ cn.hutool hutool-all + + com.alibaba + easyexcel + \ No newline at end of file diff --git a/maku-framework/src/main/java/net/maku/framework/common/excel/DateConverter.java b/maku-framework/src/main/java/net/maku/framework/common/excel/DateConverter.java new file mode 100644 index 0000000..40ab16b --- /dev/null +++ b/maku-framework/src/main/java/net/maku/framework/common/excel/DateConverter.java @@ -0,0 +1,39 @@ +package net.maku.framework.common.excel; + +import com.alibaba.excel.converters.Converter; +import com.alibaba.excel.enums.CellDataTypeEnum; +import com.alibaba.excel.metadata.GlobalConfiguration; +import com.alibaba.excel.metadata.data.ReadCellData; +import com.alibaba.excel.metadata.data.WriteCellData; +import com.alibaba.excel.metadata.property.ExcelContentProperty; +import net.maku.framework.common.utils.DateUtils; + +import java.util.Date; + +/** + * @author eden + */ +public class DateConverter implements Converter { + + @Override + public Class supportJavaTypeKey() { + return Date.class; + } + + @Override + public CellDataTypeEnum supportExcelTypeKey() { + return CellDataTypeEnum.STRING; + } + + @Override + public Date convertToJavaData(ReadCellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { + String dateString = cellData.getStringValue(); + return dateString == null ? null : DateUtils.parse(dateString, DateUtils.DATE_TIME_PATTERN); + } + + @Override + public WriteCellData convertToExcelData(Date value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { + String dateValue = DateUtils.format(value, DateUtils.DATE_TIME_PATTERN); + return new WriteCellData<>(dateValue); + } +} \ No newline at end of file diff --git a/maku-framework/src/main/java/net/maku/framework/common/excel/ExcelDataListener.java b/maku-framework/src/main/java/net/maku/framework/common/excel/ExcelDataListener.java new file mode 100644 index 0000000..851f6b3 --- /dev/null +++ b/maku-framework/src/main/java/net/maku/framework/common/excel/ExcelDataListener.java @@ -0,0 +1,61 @@ +package net.maku.framework.common.excel; + +import com.alibaba.excel.context.AnalysisContext; +import com.alibaba.excel.event.AnalysisEventListener; + +import java.util.LinkedList; +import java.util.List; + +/** + * excel读取监听器 + * + * @author eden + */ +public class ExcelDataListener extends AnalysisEventListener { + /** + * 定义一个保存Excel所有记录的集合 + */ + private final List list = new LinkedList<>(); + /** + * 回调接口 + */ + private final ExcelFinishCallBack callBack; + + /** + * 构造 ExcelFinishCallBack + * + * @param callBack ExcelFinishCallBack + */ + public ExcelDataListener(ExcelFinishCallBack callBack) { + this.callBack = callBack; + } + + + /** + * 这个每一条数据解析都会来调用 + * 在这里可以做一些其他的操作(过滤,分批入库...) 就考自己去拓展了 + * + * @param data one row value. is same as {@link AnalysisContext#readRowHolder()} + * @param context context + */ + @Override + public void invoke(T data, AnalysisContext context) { + list.add(data); + if (list.size() == 1) { + System.out.println("自己逻辑"); + + } + } + + /** + * 所有数据解析完成了 都会来调用 + * 解析完成之后将所有数据存入回调接口中 + * + * @param context context + */ + @Override + public void doAfterAllAnalysed(AnalysisContext context) { + this.callBack.doAfterAllAnalysed(this.list); + } +} + diff --git a/maku-framework/src/main/java/net/maku/framework/common/excel/ExcelFinishCallBack.java b/maku-framework/src/main/java/net/maku/framework/common/excel/ExcelFinishCallBack.java new file mode 100644 index 0000000..be12c72 --- /dev/null +++ b/maku-framework/src/main/java/net/maku/framework/common/excel/ExcelFinishCallBack.java @@ -0,0 +1,29 @@ +package net.maku.framework.common.excel; + +import java.util.List; + +/** + * excel读取数据完成 + * + * @param the type parameter + * @author eden + */ +public interface ExcelFinishCallBack { + + /** + * 导出后置处理数据 + * Do after all analysed. + * + * @param result the result + */ + void doAfterAllAnalysed(List result); + + /** + * Do save batch. + * + * @param result the result + */ + default void doSaveBatch(List result) { + } +} + diff --git a/maku-framework/src/main/java/net/maku/framework/common/utils/ExcelUtils.java b/maku-framework/src/main/java/net/maku/framework/common/utils/ExcelUtils.java new file mode 100644 index 0000000..17293f5 --- /dev/null +++ b/maku-framework/src/main/java/net/maku/framework/common/utils/ExcelUtils.java @@ -0,0 +1,112 @@ +package net.maku.framework.common.utils; + +import com.alibaba.excel.EasyExcel; +import com.alibaba.excel.support.ExcelTypeEnum; +import net.maku.framework.common.excel.ExcelDataListener; +import net.maku.framework.common.excel.ExcelFinishCallBack; +import org.springframework.web.multipart.MultipartFile; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.List; + +/** + * The type Excel utils. + * + * @author eden + */ +public class ExcelUtils { + + /** + * 读取excel文件 + * + * @param 数据类型 + * @param file excel文件 + * @param head 列名 + * @param callBack 回调 导入时传入定义好的回调接口,excel数据解析完毕之后监听器将数据传入回调函数 + * 这样调用工具类时可以通过回调函数获取导入的数据,如果数据量过大可根据实际情况进行分配入库 + */ + public static void readAnalysis(MultipartFile file, Class head, ExcelFinishCallBack callBack) { + try { + EasyExcel.read(file.getInputStream(), head, new ExcelDataListener<>(callBack)).sheet().doRead(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * 读取excel文件 + * + * @param 数据类型 + * @param file excel文件 + * @param head 列名 + * @param callBack 回调 导入时传入定义好的回调接口,excel数据解析完毕之后监听器将数据传入回调函数 + * 这样调用工具类时可以通过回调函数获取导入的数据,如果数据量过大可根据实际情况进行分配入库 + */ + public static void readAnalysis(File file, Class head, ExcelFinishCallBack callBack) { + try { + EasyExcel.read(new FileInputStream(file), head, new ExcelDataListener<>(callBack)).sheet().doRead(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * 读取excel文件 同步 + * + * @param 数据类型 + * @param file 文件 + * @param clazz 模板类 + * @return java.util.List list + */ + public static List readSync(File file, Class clazz) { + return readSync(file, clazz, 1, 0, ExcelTypeEnum.XLSX); + } + + /** + * 读取excel文件 同步 + * + * @param 数据类型 + * @param file 文件 + * @param clazz 模板类 + * @param rowNum 数据开始行 1 + * @param sheetNo 第几张表 + * @param excelType 数据表格式类型 + * @return java.util.List list + */ + public static List readSync(File file, Class clazz, Integer rowNum, Integer sheetNo, ExcelTypeEnum excelType) { + return EasyExcel.read(file).headRowNumber(rowNum).excelType(excelType).head(clazz).sheet(sheetNo).doReadSync(); + } + + + /** + * 导出数据到文件 + * + * @param 数据类型 + * @param head 类名 + * @param file 导入到文件 + * @param data 数据 + */ + public static void excelExport(Class head, File file, List data) { + excelExport(head, file, "sheet1", data); + } + + /** + * 导出数据到文件 + * + * @param 写入格式 + * @param head 类名 + * @param file 写入到文件 + * @param sheetName sheet名称 + * @param data 数据列表 + */ + public static void excelExport(Class head, File file, String sheetName, List data) { + try { + EasyExcel.write(file, head).sheet(sheetName).doWrite(data); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + +} diff --git a/maku-server/src/main/resources/application-dev.yml b/maku-server/src/main/resources/application-dev.yml index 36432cc..2280142 100644 --- a/maku-server/src/main/resources/application-dev.yml +++ b/maku-server/src/main/resources/application-dev.yml @@ -1,15 +1,15 @@ spring: redis: - database: 1 + database: 10 host: localhost - port: 6379 - #password: + port: 16379 + password: 123456 #timeout: 6000ms # 连接超时时长(毫秒) datasource: # MySQL8 driver-class-name: com.mysql.cj.jdbc.Driver - url: jdbc:mysql://localhost:3306/maku_boot?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true - username: maku + url: jdbc:mysql://localhost:13306/maku_boot?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true + username: root password: 123456 # 达梦 # driver-class-name: dm.jdbc.driver.DmDriver diff --git a/maku-server/src/test/java/net/maku/EasyExcelTest.java b/maku-server/src/test/java/net/maku/EasyExcelTest.java new file mode 100644 index 0000000..4a632b9 --- /dev/null +++ b/maku-server/src/test/java/net/maku/EasyExcelTest.java @@ -0,0 +1,82 @@ +package net.maku; + +import com.alibaba.excel.annotation.ExcelProperty; +import lombok.Data; +import net.maku.framework.common.excel.DateConverter; +import net.maku.framework.common.excel.ExcelFinishCallBack; +import net.maku.framework.common.utils.ExcelUtils; +import org.junit.jupiter.api.Test; + +import java.io.File; +import java.io.FileNotFoundException; +import java.util.Arrays; +import java.util.Date; +import java.util.List; + +/** + * EasyExcel 测试 + * + * @author eden + */ +public class EasyExcelTest { + + @Test + public void doImport() throws FileNotFoundException { + File file = new File("D://upload//test01.xlsx"); + ExcelClass excelClass = new ExcelClass(); + excelClass.setNumber(1); + excelClass.setDecimals(1.2); + excelClass.setString("test"); + excelClass.setDate(new Date()); + List data = Arrays.asList(excelClass, excelClass, excelClass); + if (!file.exists()) { + ExcelUtils.excelExport(ExcelClass.class, file, data); + } + + List list = ExcelUtils.readSync(file, ExcelClass.class); + list.forEach(System.out::println); + } + + + @Test + public void doAImport() { + File file = new File("D://upload//test01.xlsx"); + ExcelClass excelClass = new ExcelClass(); + excelClass.setNumber(1); + excelClass.setDecimals(1.2); + excelClass.setString("test"); + excelClass.setDate(new Date()); + List data = Arrays.asList(excelClass, excelClass, excelClass, excelClass, excelClass, excelClass, excelClass); + if (!file.exists()) { + ExcelUtils.excelExport(ExcelClass.class, file, data); + } + ExcelUtils.readAnalysis(file, ExcelClass.class, new ServiceA()); + } + + + @Data + public static class ExcelClass { + + @ExcelProperty("整数") + private Integer number; + + @ExcelProperty("字符串") + private String string; + + @ExcelProperty("小数") + private Double decimals; + + @ExcelProperty(value = "日期", converter = DateConverter.class) + private Date date; + } + +} + +class ServiceA implements ExcelFinishCallBack { + + @Override + public void doAfterAllAnalysed(List result) { + System.out.println(result.size()); + } +} + diff --git a/pom.xml b/pom.xml index daef713..9facb08 100644 --- a/pom.xml +++ b/pom.xml @@ -30,7 +30,7 @@ true UTF-8 UTF-8 - 1.8 + 11 3.5.2 8.1.2.79 3.0.3 @@ -45,6 +45,7 @@ 8.4.3 5.6.89 3.22.3 + 3.1.1 @@ -149,6 +150,11 @@ esdk-obs-java-bundle ${huaweicloud.obs.version} + + com.alibaba + easyexcel + ${easyexcel.version} + -- Gitee