导入导出功能
# 导入导出功能实现
在实际开发中,导入导出功能广泛用于批量数据的处理。在若依框架中,通过 @Excel
注解和相关工具类,可以简化 Excel 文件的导入和导出操作。本文将详细介绍如何在若依框架中实现导入导出功能,并涵盖常见的扩展需求,如自定义数据处理、隐藏属性列等。
# 一、@Excel
注解参数说明
若依框架提供的 @Excel
注解用于标注实体类的字段,指示哪些字段需要导入导出,并指定它们的格式和行为。以下是 @Excel
注解的详细参数说明:
参数 | 类型 | 默认值 | 描述 |
---|---|---|---|
sort | int | Integer.MAX_VALUE | 导出时在 Excel 中的排序,值越小越靠前 |
name | String | 空 | 导出到 Excel 中的列名称 |
dateFormat | String | 空 | 日期格式,如:yyyy-MM-dd |
dictType | String | 空 | 如果是字典类型,请设置字典的 type 值(如:sys_user_sex ) |
readConverterExp | String | 空 | 读取内容转表达式(如:0=男,1=女,2=未知 ) |
separator | String | , | 读取字符串组内容时的分隔符 |
scale | int | -1 | BigDecimal 精度,默认:-1 (不开启格式化) |
roundingMode | int | BigDecimal.ROUND_HALF_EVEN | BigDecimal 舍入规则,默认:BigDecimal.ROUND_HALF_EVEN |
cellType | Enum | Type.STRING | 导出类型(0:数字,1:字符串,2:图片) |
height | String | 14 | 导出时每列的高度,单位为字符 |
width | String | 16 | 导出时每列的宽度,单位为字符 |
suffix | String | 空 | 文字后缀,如 % ,90 变成 90% |
defaultValue | String | 空 | 当值为空时,字段的默认值 |
prompt | String | 空 | 提示信息 |
combo | String | Null | 设置只能选择不能输入的列内容 |
comboReadDict | boolean | false | 是否从字典读取数据到 combo ,默认不读取,如读取需设置 dictType |
headerBackgroundColor | Enum | IndexedColors.GREY_50_PERCENT | 导出列头背景色 IndexedColors.XXXX |
headerColor | Enum | IndexedColors.WHITE | 导出列头字体颜色 IndexedColors.XXXX |
backgroundColor | Enum | IndexedColors.WHITE | 导出单元格背景色 IndexedColors.XXXX |
color | Enum | IndexedColors.BLACK | 导出单元格字体颜色 IndexedColors.XXXX |
targetAttr | String | 空 | 另一个类中的属性名称,支持多级获取,以小数点隔开 |
isStatistics | boolean | false | 是否自动统计数据,在最后追加一行统计数据总和 |
type | Enum | Type.ALL | 字段类型(0:导出导入;1:仅导出;2:仅导入) |
align | Enum | HorizontalAlignment.CENTER | 导出对齐方式 HorizontalAlignment.XXXX |
handler | Class | ExcelHandlerAdapter.class | 自定义数据处理器 |
args | String[] | {} | 自定义数据处理器参数 |
# 二、导出功能实现流程
# 1. 前端调用导出方法
在前端通过 Vue 组件与 Axios 实现导出功能,首先在页面中添加导出按钮,并通过点击事件触发导出操作。
<template>
<div>
<el-button type="warning" icon="el-icon-download" @click="handleExport">导出</el-button>
</div>
</template>
<script>
import { exportUserData } from '@/api/system/user'; // 导入接口方法
export default {
methods: {
handleExport() {
exportUserData(this.queryParams).then(response => {
this.downloadFile(response.msg);
});
},
downloadFile(fileName) {
window.location.href = `${process.env.VUE_APP_BASE_API}/common/download?fileName=${fileName}&delete=true`;
}
},
data() {
return {
queryParams: {
pageNum: 1,
pageSize: 10,
userName: ''
}
};
}
};
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
说明:
exportUserData
是调用后台接口导出数据的 API 方法。downloadFile
方法用于触发文件下载。
# 2. 后端实体类添加 @Excel
注解
在需要导出的实体类字段上添加 @Excel
注解,指定字段在 Excel 中的展示方式。
@Excel(name = "用户序号", prompt = "用户编号")
private Long userId;
@Excel(name = "用户名称")
private String userName;
@Excel(name = "用户性别", readConverterExp = "0=男,1=女,2=未知")
private String sex;
@Excel(name = "用户头像", cellType = ColumnType.IMAGE)
private String avatar;
@Excel(name = "帐号状态", dictType = "sys_normal_disable")
private String status;
@Excel(name = "最后登陆时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date loginDate;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 3. 在 Controller 中添加导出方法
在后端 Controller 中,定义导出方法,通过 ExcelUtil
工具类实现 Excel 导出。
@PostMapping("/export")
@ResponseBody
public AjaxResult export(User user)
{
// 查询用户列表数据
List<User> list = userService.selectUserList(user);
// 创建 Excel 工具类
ExcelUtil<User> util = new ExcelUtil<User>(User.class);
// 导出 Excel 文件并返回下载链接
return util.exportExcel(list, "用户数据");
}
2
3
4
5
6
7
8
9
10
11
提示: 默认情况下,导出流程会先创建一个临时文件,等待前端请求下载结束后删除该文件。如果遇到迅雷等二次请求下载的应用,可能会导致文件已被删除。此时可以将文件改为流的形式返回给前端,以解决该问题。
# 三、导入功能实现流程
# 1. 前端实现导入功能
在前端页面中,通过 Element UI 的 <el-upload>
组件实现文件上传和导入功能。
<template>
<div>
<el-upload
action="/api/system/user/importData" // 后端接口
:headers="uploadHeaders" // 请求头部,包含token等
:on-success="handleImportSuccess" // 上传成功处理
:on-error="handleImportError" // 上传失败处理
:show-file-list="false" // 不显示文件列表
:auto-upload="true"> // 自动上传
<el-button type="primary" icon="el-icon-upload">导入</el-button>
</el-upload>
</div>
</template>
<script>
export default {
data() {
return {
uploadHeaders: {
Authorization: "Bearer " + this.getToken()
}
};
},
methods: {
getToken() {
return localStorage.getItem("token");
},
handleImportSuccess(response) {
this.$message.success("导入成功");
this.getList(); // 刷新列表
},
handleImportError() {
this.$message.error("导入失败");
}
}
};
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# 2. 在实体变量上添加 @Excel
注解
在需要导入的实体类字段上添加 `
@Excel注解。可以通过
type` 参数指定该字段仅用于导入或导出。
@Excel(name = "用户序号")
private Long id;
@Excel(name = "部门编号", type = Type.IMPORT)
private Long deptId;
@Excel(name = "用户名称")
private String userName;
/** 导出部门多个对象 */
@Excels({
@Excel(name = "部门名称", targetAttr = "deptName", type = Type.EXPORT),
@Excel(name = "部门负责人", targetAttr = "leader", type = Type.EXPORT)
})
private SysDept dept;
/** 导出部门单个对象 */
@Excel(name = "部门名称", targetAttr = "deptName", type = Type.EXPORT)
private SysDept dept;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 3. 在 Controller 添加导入方法
在后端 Controller 中,定义导入方法,通过 ExcelUtil
工具类实现 Excel 导入。
@PostMapping("/importData")
@ResponseBody
public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception
{
// 创建 Excel 工具类
ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
// 解析 Excel 文件
List<SysUser> userList = util.importExcel(file.getInputStream());
// 获取当前登录用户
String operName = SecurityUtils.getUsername();
// 执行导入操作
String message = userService.importUser(userList, updateSupport, operName);
return AjaxResult.success(message);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
提示: 可以直接在
main
方法中运行此代码进行测试:InputStream is = new FileInputStream(new File("D:\\test.xlsx")); ExcelUtil<Entity> util = new ExcelUtil<Entity>(Entity.class); List<Entity> userList = util.importExcel(is);
1
2
3
# 四、自定义扩展功能
若依框架的导入导出功能支持多种自定义扩展,如自定义标题信息、自定义数据处理器、隐藏属性列等。
# 1. 自定义标题信息
在导出时,可以添加自定义的标题信息,使导出的 Excel 文件更具备可读性。
public AjaxResult export(SysUser user)
{
List<SysUser> list = userService.selectUserList(user);
ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
// 设置表格标题为 "用户列表"
return util.exportExcel(list, "用户数据", "用户列表");
}
2
3
4
5
6
7
# 2. 自定义数据处理器
如果需要对某些字段进行特殊处理,可以使用自定义的数据处理器。
在实体类中,通过
@Excel
注解的handler
属性指定自定义的数据处理器。public class User extends BaseEntity { @Excel(name = "用户名称", handler = MyDataHandler.class, args = { "aaa", "bbb" }) private String userName; }
1
2
3
4
5编写数据处理器,继承
ExcelHandlerAdapter
,实现format
方法。public class MyDataHandler implements ExcelHandlerAdapter { @Override public Object format(Object value, String[] args, Cell cell, Workbook wb) { // 自定义处理逻辑 if ("若依".equals(value)) { // 设置单元格文字为红色 CellStyle style = wb.createCellStyle(); Font dataFont = wb.createFont(); dataFont.setColor(IndexedColors.RED.index); style.setFont(dataFont); cell.setCellStyle(style); } return value; } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 3. 自定义隐藏属性列
根据业务需要,可以动态隐藏导出的列。例如,根据用户角色来决定是否导出用户的手机号码。
@PostMapping("/export")
public void export(HttpServletResponse response, SysUser user)
{
List<SysUser> list = userService.selectUserList(user);
ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
if (条件A) {
// 隐藏用户ID列
util.hideColumn("userId");
} else if (条件B) {
// 隐藏用户名称和手机号列
util.hideColumn("userName", "phonenumber");
}
util.exportExcel(response, list, "用户数据");
}
2
3
4
5
6
7
8
9
10
11
12
13
14
# 4. 导入对象的子对象
如果导入的对象中包含子对象,可以通过 @Excels
注解进行处理。例如,导入用户时需要包含所属部门的信息。
public class SysUser extends BaseEntity
{
/** 部门对象 */
@Excels({
@Excel(name = "部门名称", targetAttr = "deptName"),
@Excel(name = "部门负责人", targetAttr = "leader"),
@Excel(name = "部门状态", targetAttr = "status", dictType = "sys_normal_disable")
})
private SysDept dept = new SysDept();
}
2
3
4
5
6
7
8
9
10
# 5. 导出对象的子列表
如果导出的对象中包含集合列表,例如一个用户对应多个角色,可以通过以下方式实现导出。
public class SysUser
{
@Excel(name = "用户编号", cellType = ColumnType.NUMERIC, width = 20, needMerge = true)
private String userId;
@Excel(name = "用户名称", width = 20, needMerge = true)
private String userName;
@Excel(name = "角色")
private List<SysRole> roles;
// getter 和 setter 方法
}
2
3
4
5
6
7
8
9
10
11
12
13
测试代码:
public class Test
{
public static void main(String[] args) throws IOException
{
List<SysUser> userList = new ArrayList<>();
SysUser user1 = new SysUser();
List<SysRole> roles1 = new ArrayList<>();
SysRole role1 = new SysRole();
role1.setRoleId("1");
role1.setRoleName("超级管理员");
roles1.add(role1);
user1.setRoles(roles1);
userList.add(user1);
ExcelUtil<SysUser> util = new ExcelUtil<>(SysUser.class);
AjaxResult ajax = util.exportExcel(userList, "用户数据", "用户数据");
System.out.println(ajax.toString());
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22