excel 导出功能

This commit is contained in:
eden 2022-11-03 16:38:26 +08:00
parent 97a0b3bf26
commit e02950a1dc
12 changed files with 445 additions and 8 deletions

View File

@ -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<Map<String, String>> export() throws IOException {
Map<String, String> map = sysLogLoginService.export();
return Result.ok(map);
}
}

View File

@ -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<SysLogLoginEntity> {
/**
* Page page result.
*
* @param query the query
* @return the page result
*/
PageResult<SysLogLoginVO> page(SysLogLoginQuery query);
/**
@ -23,4 +32,12 @@ public interface SysLogLoginService extends BaseService<SysLogLoginEntity> {
* @param operation 操作信息
*/
void save(String username, Integer status, Integer operation);
/**
* 导出登录日志
*
* @return the map
* @throws IOException the io exception
*/
Map<String, String> export() throws IOException;
}

View File

@ -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<SysLogLoginDao, SysLogLoginEntity> implements SysLogLoginService {
private final StorageService storageService;
@Override
public PageResult<SysLogLoginVO> page(SysLogLoginQuery query) {
IPage<SysLogLoginEntity> page = baseMapper.selectPage(getPage(query), getWrapper(query));
@ -66,4 +77,22 @@ public class SysLogLoginServiceImpl extends BaseServiceImpl<SysLogLoginDao, SysL
baseMapper.insert(entity);
}
@Override
public Map<String, String> export() throws IOException {
List<SysLogLoginEntity> list = list();
List<SysLogLoginVO> 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<String, String> map = new HashMap<>();
map.put("path", url);
map.put("filename", file.getName());
return map;
}
}

View File

@ -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<Integer> {
@Override
public WriteCellData<String> 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<Integer> {
@Override
public WriteCellData<String> 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);
}
}
}

View File

@ -60,5 +60,9 @@
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -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<Date> {
@Override
public Class<Date> 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<Date> convertToExcelData(Date value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
String dateValue = DateUtils.format(value, DateUtils.DATE_TIME_PATTERN);
return new WriteCellData<>(dateValue);
}
}

View File

@ -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<T> extends AnalysisEventListener<T> {
/**
* 定义一个保存Excel所有记录的集合
*/
private final List<T> list = new LinkedList<>();
/**
* 回调接口
*/
private final ExcelFinishCallBack<T> callBack;
/**
* 构造 ExcelFinishCallBack
*
* @param callBack ExcelFinishCallBack
*/
public ExcelDataListener(ExcelFinishCallBack<T> 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);
}
}

View File

@ -0,0 +1,29 @@
package net.maku.framework.common.excel;
import java.util.List;
/**
* excel读取数据完成
*
* @param <T> the type parameter
* @author eden
*/
public interface ExcelFinishCallBack<T> {
/**
* 导出后置处理数据
* Do after all analysed.
*
* @param result the result
*/
void doAfterAllAnalysed(List<T> result);
/**
* Do save batch.
*
* @param result the result
*/
default void doSaveBatch(List<T> result) {
}
}

View File

@ -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 <T> 数据类型
* @param file excel文件
* @param head 列名
* @param callBack 回调 导入时传入定义好的回调接口excel数据解析完毕之后监听器将数据传入回调函数
* 这样调用工具类时可以通过回调函数获取导入的数据如果数据量过大可根据实际情况进行分配入库
*/
public static <T> void readAnalysis(MultipartFile file, Class<T> head, ExcelFinishCallBack<T> callBack) {
try {
EasyExcel.read(file.getInputStream(), head, new ExcelDataListener<>(callBack)).sheet().doRead();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 读取excel文件
*
* @param <T> 数据类型
* @param file excel文件
* @param head 列名
* @param callBack 回调 导入时传入定义好的回调接口excel数据解析完毕之后监听器将数据传入回调函数
* 这样调用工具类时可以通过回调函数获取导入的数据如果数据量过大可根据实际情况进行分配入库
*/
public static <T> void readAnalysis(File file, Class<T> head, ExcelFinishCallBack<T> callBack) {
try {
EasyExcel.read(new FileInputStream(file), head, new ExcelDataListener<>(callBack)).sheet().doRead();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 读取excel文件 同步
*
* @param <T> 数据类型
* @param file 文件
* @param clazz 模板类
* @return java.util.List list
*/
public static <T> List<T> readSync(File file, Class<T> clazz) {
return readSync(file, clazz, 1, 0, ExcelTypeEnum.XLSX);
}
/**
* 读取excel文件 同步
*
* @param <T> 数据类型
* @param file 文件
* @param clazz 模板类
* @param rowNum 数据开始行 1
* @param sheetNo 第几张表
* @param excelType 数据表格式类型
* @return java.util.List list
*/
public static <T> List<T> readSync(File file, Class<T> clazz, Integer rowNum, Integer sheetNo, ExcelTypeEnum excelType) {
return EasyExcel.read(file).headRowNumber(rowNum).excelType(excelType).head(clazz).sheet(sheetNo).doReadSync();
}
/**
* 导出数据到文件
*
* @param <T> 数据类型
* @param head 类名
* @param file 导入到文件
* @param data 数据
*/
public static <T> void excelExport(Class<T> head, File file, List<T> data) {
excelExport(head, file, "sheet1", data);
}
/**
* 导出数据到文件
*
* @param <T> 写入格式
* @param head 类名
* @param file 写入到文件
* @param sheetName sheet名称
* @param data 数据列表
*/
public static <T> void excelExport(Class<T> head, File file, String sheetName, List<T> data) {
try {
EasyExcel.write(file, head).sheet(sheetName).doWrite(data);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}

View File

@ -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

View File

@ -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<ExcelClass> data = Arrays.asList(excelClass, excelClass, excelClass);
if (!file.exists()) {
ExcelUtils.excelExport(ExcelClass.class, file, data);
}
List<ExcelClass> 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<ExcelClass> 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<EasyExcelTest.ExcelClass> {
@Override
public void doAfterAllAnalysed(List<EasyExcelTest.ExcelClass> result) {
System.out.println(result.size());
}
}

View File

@ -30,7 +30,7 @@
<skipTests>true</skipTests>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<java.version>11</java.version>
<mybatisplus.version>3.5.2</mybatisplus.version>
<dameng.version>8.1.2.79</dameng.version>
<knife4j.version>3.0.3</knife4j.version>
@ -45,6 +45,7 @@
<minio.version>8.4.3</minio.version>
<qcloud.cos.version>5.6.89</qcloud.cos.version>
<huaweicloud.obs.version>3.22.3</huaweicloud.obs.version>
<easyexcel.version>3.1.1</easyexcel.version>
</properties>
<dependencies>
@ -149,6 +150,11 @@
<artifactId>esdk-obs-java-bundle</artifactId>
<version>${huaweicloud.obs.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>${easyexcel.version}</version>
</dependency>
</dependencies>
</dependencyManagement>