excel 导出功能
This commit is contained in:
parent
97a0b3bf26
commit
e02950a1dc
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -60,5 +60,9 @@
|
|||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-all</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>easyexcel</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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) {
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
8
pom.xml
8
pom.xml
|
@ -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>
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user