文件导入导出
通过集成 Excel
导入导出功能,您可以显著提升数据处理的效率和灵活性,满足多样化的业务需求。
使用场景
在项目中集成 Excel
文件导入导出功能,可以显著提升数据处理效率,适用于数据报表生成、批量数据导入等场景。通过使用 Apache POI
或 EasyExcel
等工具。
您可以轻松实现以下功能:
Excel 导出:
1. 将数据库中的数据导出为 Excel 文件,支持自定义表头和格式。
2. 适用于生成报表、数据备份等场景。
Excel 导入:
1. 将 Excel 文件中的数据导入到数据库,支持批量处理和校验。
2. 适用于批量数据录入、数据迁移等场景。
高性能处理:
1. 使用 EasyExcel 可以实现高效的大数据量导入导出,避免内存溢出问题。
灵活配置:
1. 支持自定义数据映射、格式校验和错误处理,满足复杂业务需求。
AOP切面
在项目中使用 AOP
(面向切面编程)注解实现文件导入、导出功能,具有以下优势:
1. 代码解耦:将日志记录逻辑与业务逻辑分离,避免代码重复,提升代码可读性和可维护性。
2. 灵活性与扩展性:通过注解可以灵活地控制哪些方法需要记录日志,便于扩展和修改日志记录逻辑。
3. 非侵入性:无需修改现有业务代码,只需在方法上添加注解即可实现日志记录。
4. 集中管理:日志记录逻辑集中在切面中,便于统一管理和维护。
5. 提高开发效率:通过注解方式快速实现日志功能,减少重复代码编写。
定义注解
在 xiaomayi-common/xiaomayi-excel
模块中定义的登录日志的 AOP
切面 RequestExcel
和 ResponseExcel
文件。
RequestExcel
切面文件
js
package com.xiaomayi.excel.annotation;
import com.xiaomayi.excel.listener.DefaultListReadListener;
import com.xiaomayi.excel.listener.ListReadListener;
import java.lang.annotation.*;
/**
* <p>
* 自定义导入Excel注解
* </p>
*
* @author 小蚂蚁云团队
* @since 2023-10-04
*/
@Documented
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface RequestExcel {
/**
* 文件上传接口参数名定义,默认:file
*
* @return 返回结果
*/
String fileName() default "file";
/**
* 文件数据读取监听器
*
* @return 返回监听器
*/
Class<? extends ListReadListener<?>> readListener() default DefaultListReadListener.class;
/**
* 文件表头行数,不指定默认:-1
* 备注:
* 1、读取一个ExcelProperty注解,value有值时取其长度;
* 2、如果value没值,则head取值:1
*
* @return 返回表头行数
*/
int headRowNumber() default -1;
}
ResponseExcel
切面文件
js
package com.xiaomayi.excel.annotation;
import com.alibaba.excel.support.ExcelTypeEnum;
import java.lang.annotation.*;
/**
* <p>
* 自定义导出Excel注解
* </p>
*
* @author 小蚂蚁云团队
* @since 2023-10-04
*/
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ResponseExcel {
/**
* 文件名称
*
* @return 返回结果
*/
String name();
/**
* 文件后缀,默认:.xlsx
*
* @return 返回结果
*/
ExcelTypeEnum suffix() default ExcelTypeEnum.XLSX;
/**
* 文件SHEET名称
*
* @return 返回结果
*/
String sheetName() default "";
/**
* 是否合并
*
* @return 是否合并列
*/
boolean isMerge() default false;
/**
* 要合并的列
*
* @return 合并列数组
*/
int[] mergeColumns() default {};
/**
* 文件表头行数
* 备注:
* 1、合并时需计算,不指定默认-1;
* 2、不指定时取ExcelProperty注解value的长度;
*/
int headRowNumber() default -1;
}
监听抽象类
js
package com.xiaomayi.excel.listener;
import com.alibaba.excel.read.listener.ReadListener;
import java.util.List;
/**
* <p>
* 自定义读取监听抽象类
* </p>
*
* @author 小蚂蚁云团队
* @since 2023-10-04
*/
public abstract class ListReadListener<T> implements ReadListener<T> {
/**
* 自定义抽象方法,获取数据列表
*
* @return 返回结果
*/
public abstract List<T> getList();
}
文件监听器
js
package com.xiaomayi.excel.listener;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.metadata.data.ReadCellData;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* <p>
* 自定义文件处理监听器
* </p>
*
* @author 小蚂蚁云团队
* @since 2023-10-04
*/
public class DefaultListReadListener extends ListReadListener<Object> {
/**
* 定义数据对象列表
*/
private final List<Object> dataList = new ArrayList<>();
/**
* 获取读取的数据列表
*
* @return 返回结果
*/
@Override
public List<Object> getList() {
return dataList;
}
/**
* 文件头处理
*
* @param headMap 文件头Map
* @param context 分析内容
*/
@Override
public void invokeHead(Map<Integer, ReadCellData<?>> headMap, AnalysisContext context) {
super.invokeHead(headMap, context);
}
/**
* 数据源处理
*
* @param object 数据对象
* @param analysisContext 分析内筒
*/
@Override
public void invoke(Object object, AnalysisContext analysisContext) {
// 加入列表
dataList.add(object);
}
/**
* 异常处理
*
* @param exception 异常参数
* @param context 分析内筒
* @throws Exception 抛出异常
*/
@Override
public void onException(Exception exception, AnalysisContext context) throws Exception {
super.onException(exception, context);
}
/**
* 数据处理完毕后调用
*
* @param analysisContext 分析内容
*/
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
}
}
添加依赖
在 pom.xml
配置文件中引入以下依赖:
js
<!-- Excel依赖模块 -->
<dependency>
<groupId>com.xiaomayi</groupId>
<artifactId>xiaomayi-excel</artifactId>
</dependency>
注解使用
为了企业和开发者更好的了解和熟练运用注解的方式实现导入、导出功能,在用户管理模块专门编写了案例,在需要导入、导出的方法上添加对应的注解即可。
RequestExcel
导入注解使用
在需要实现导入的方法上添加注解 @RequestExcel
。
js
R importExcel(@RequestExcel List<UserExcelVO> userExcelVOList);
使用案例:
js
package com.xiaomayi.admin.controller;
import cn.hutool.core.util.RandomUtil;
import com.itextpdf.text.DocumentException;
import com.xiaomayi.core.config.AppConfig;
import com.xiaomayi.core.utils.R;
import com.xiaomayi.core.utils.StringUtils;
import com.xiaomayi.excel.annotation.RequestExcel;
import com.xiaomayi.excel.annotation.ResponseExcel;
import com.xiaomayi.logger.annotation.RequestLog;
import com.xiaomayi.logger.enums.RequestType;
import com.xiaomayi.security.utils.SecurityUtils;
import com.xiaomayi.system.dto.user.*;
import com.xiaomayi.system.service.UserService;
import com.xiaomayi.system.utils.ParamResolver;
import com.xiaomayi.system.vo.user.UserExcelVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
/**
* <p>
* 用户 前端控制器
* </p>
*
* @author 小蚂蚁云团队
* @since 2024-03-23
*/
@RestController
@RequestMapping("/user")
@Tag(name = "用户管理", description = "用户管理")
@AllArgsConstructor
public class UserController {
private final UserService userService;
/**
* 导入用户
*
* @param userExcelVOList 导入Excel
* @return 返回结果
*/
@Operation(summary = "导入用户", description = "导入用户")
@RequestLog(title = "导入用户", type = RequestType.IMPORT)
@PreAuthorize("@pms.hasAuthority('sys:user:import')")
@PostMapping("/import")
public R importExcel(@RequestExcel List<UserExcelVO> userExcelVOList) {
return userService.importExcel(userExcelVOList);
}
}
ResponseExcel
注解使用
js
@ResponseExcel(name = "用户信息", sheetName = "用户信息")
使用案例:
js
package com.xiaomayi.admin.controller;
import cn.hutool.core.util.RandomUtil;
import com.itextpdf.text.DocumentException;
import com.xiaomayi.core.config.AppConfig;
import com.xiaomayi.core.utils.R;
import com.xiaomayi.core.utils.StringUtils;
import com.xiaomayi.excel.annotation.RequestExcel;
import com.xiaomayi.excel.annotation.ResponseExcel;
import com.xiaomayi.logger.annotation.RequestLog;
import com.xiaomayi.logger.enums.RequestType;
import com.xiaomayi.security.utils.SecurityUtils;
import com.xiaomayi.system.dto.user.*;
import com.xiaomayi.system.service.UserService;
import com.xiaomayi.system.utils.ParamResolver;
import com.xiaomayi.system.vo.user.UserExcelVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
/**
* <p>
* 用户 前端控制器
* </p>
*
* @author 小蚂蚁云团队
* @since 2024-03-23
*/
@RestController
@RequestMapping("/user")
@Tag(name = "用户管理", description = "用户管理")
@AllArgsConstructor
public class UserController {
private final UserService userService;
/**
* 导出用户
*
* @return 返回结果
*/
@Operation(summary = "导出用户", description = "导出用户")
@RequestLog(title = "导出用户", type = RequestType.EXPORT)
@PreAuthorize("@pms.hasAuthority('sys:user:export')")
@ResponseExcel(name = "用户信息", sheetName = "用户信息")
@GetMapping("/export")
public List<UserExcelVO> exportExcel() {
return userService.exportExcel();
}
}
导入导出
进入用户管理模块,在导航操作栏上有导入、导出按钮,分别实现了 Excel
文件的导入和导出功能。
- 导入文件
可以从导入弹窗中点击 下载模板
,然后在 Excel模板文件
中录入需要导入的用户数据,切记登录账号请保持系统中唯一性,否则会导入报错。
以下是下载后的模板文件:
- 导出文件
点击 导出
按钮实现用户数据的导出。
输出 Excel
格式文件: