文章目录
- @Excel注解
- excel数据导入
- 前端实现
- 后端实现
- 下载模板
- 前端实现
- 后端实现
- excel数据导出
- 前端实现
- 后端实现
- 自定义标题信息
- 导出用户管理表格新增标题(用户列表)
- 导入表格包含标题处理方式
- 自定义数据处理器
- 自定义隐藏属性列
- 导入对象的子对象
- 导出对象的子列表
@Excel注解
在实际开发中经常需要使用导入导出功能来加快数据的操作。在项目中可以使用注解来完成此项功能。 在需要被导入导出的实体类属性添加@Excel注解。
在使用@Excel注解时,通常可以使用的参数包括:
name
:指定Excel列的标题名称,用于导出时生成Excel文件的表头。orderNum
:指定Excel列的顺序,从0开始,用于导出时确定列的顺序。type
:指定导入导出时的数据类型转换,例如可以指定日期格式、数字格式等。width
:指定Excel列的宽度,用于导出时设置列宽。height
:指定Excel行的高度,用于导出时设置行高。format
:指定导入导出时的数据格式,例如可以指定日期的格式化方式。replace
:指定导入导出时的值替换规则,例如可以将特定的值替换为另一个值。exportFormat
:指定导出时的数据格式,例如可以指定数字的格式化方式。importFormat
:指定导入时的数据格式,例如可以指定日期的解析方式。
以上参数中,name
和orderNum
通常是必需的,其他参数根据实际需求进行选择。在使用时,可以根据具体情况来决定是否需要设置这些参数。
excel数据导入
目前若依的版本是在用户管理页面有数据导入的功能:
前端实现
导入功能前端的实现和之前文件上传差不多。
<!-- 用户导入对话框 -->
<el-dialog :title="upload.title" :visible.sync="upload.open" width="400px" append-to-body><el-uploadref="upload":limit="1"accept=".xlsx, .xls":headers="upload.headers":action="upload.url + '?updateSupport=' + upload.updateSupport":disabled="upload.isUploading":on-progress="handleFileUploadProgress":on-success="handleFileSuccess":auto-upload="false"drag><i class="el-icon-upload"></i><div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div><div class="el-upload__tip text-center" slot="tip"><div class="el-upload__tip" slot="tip"><el-checkbox v-model="upload.updateSupport" /> 是否更新已经存在的用户数据</div><span>仅允许导入xls、xlsx格式文件。</span><el-link type="primary" :underline="false" style="font-size:12px;vertical-align: baseline;" @click="importTemplate">下载模板</el-link></div></el-upload><div slot="footer" class="dialog-footer"><el-button type="primary" @click="submitFileForm">确 定</el-button><el-button @click="upload.open = false">取 消</el-button></div>
</el-dialog>
// 文件上传中处理
handleFileUploadProgress(event, file, fileList) {this.upload.isUploading = true;
},
// 文件上传成功处理
handleFileSuccess(response, file, fileList) {this.upload.open = false;this.upload.isUploading = false;this.$refs.upload.clearFiles();this.$alert("<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" + response.msg + "</div>", "导入结果", { dangerouslyUseHTMLString: true });this.getList();
},// 提交上传文件
submitFileForm() {this.$refs.upload.submit();
}
后端实现
在实体变量上添加@Excel注解,默认为导出导入,也可以单独设置仅导入Type.IMPORT
@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;
在Controller添加导入方法,updateSupport属性为是否存在则覆盖(可选)
@Log(title = "用户管理", businessType = BusinessType.IMPORT)
@PreAuthorize("@ss.hasPermi('system:user:import')")
@PostMapping("/importData")
public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception
{ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);List<SysUser> userList = util.importExcel(file.getInputStream());String operName = getUsername();String message = userService.importUser(userList, updateSupport, operName);return success(message);
}
下载模板
下载模板实际上就是将一张空表返回给前端。
前端实现
/** 下载模板操作 */
importTemplate() {this.download('system/user/importTemplate', {}, `user_template_${new Date().getTime()}.xlsx`)
},
后端实现
注意this.init(null, sheetName, title, Type.IMPORT); null表示数据为空,只返回了表头。
/*** 对list数据源将其里面的数据导入到excel表单* * @param sheetName 工作表的名称* @param title 标题* @return 结果*/
public void importTemplateExcel(HttpServletResponse response, String sheetName, String title)
{response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");response.setCharacterEncoding("utf-8");this.init(null, sheetName, title, Type.IMPORT);exportExcel(response);
}
excel数据导出
导出默认流程是先创建一个临时文件,等待前端请求下载结束后马上删除这个临时文件。
前端实现
<el-col :span="1.5"><el-buttontype="warning"plainicon="el-icon-download"size="mini"@click="handleExport"v-hasPermi="['system:fileNotice:export']">导出</el-button>
</el-col>
/** 导出按钮操作 */
handleExport() {this.download('system/fileNotice/export', {...this.queryParams}, `fileNotice_${new Date().getTime()}.xlsx`)
}
后端实现
@PreAuthorize("@ss.hasPermi('system:fileNotice:export')")
@Log(title = "系统文件", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, FileNotice fileNotice)
{List<FileNotice> list = fileNoticeService.selectFileNoticeList(fileNotice);ExcelUtil<FileNotice> util = new ExcelUtil<FileNotice>(FileNotice.class);util.exportExcel(response, list, "系统文件数据");
}
自定义标题信息
有时候我们希望导出表格包含标题信息,我们可以这样做。
导出用户管理表格新增标题(用户列表)
public AjaxResult export(SysUser user)
{List<SysUser> list = userService.selectUserList(user);ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);return util.exportExcel(list, "用户数据", "用户列表");
}
导入表格包含标题处理方式
util.importExcel(file.getInputStream(), 1);
其中1表示标题占用行数,根据实际情况填写。
/*** 对excel表单默认第一个索引名转换成list* * @param is 输入流* @param titleNum 标题占用行数* @return 转换后集合*/
public List<T> importExcel(InputStream is, int titleNum) throws Exception
{return importExcel(StringUtils.EMPTY, is, titleNum);
}public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception
{ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);List<SysUser> userList = util.importExcel(file.getInputStream(), 1);String operName = SecurityUtils.getUsername();String message = userService.importUser(userList, updateSupport, operName);return AjaxResult.success(message);
}
自定义数据处理器
有时候我们希望数据展现为一个特殊的格式,或者需要对数据进行其它处理。Excel注解提供了自定义数据处理器以满足各种业务场景。
1、在实体类用Excel注解handler属性指定自定义的数据处理器
public class SysUser extends BaseEntity
{@Excel(name = "用户名称",handler = MyDataHandler.class)private String nickName;
}
2、编写数据处理器MyDataHandler继承ExcelHandlerAdapter,返回值为处理后的值。
public class MyDataHandler implements ExcelHandlerAdapter
{@Overridepublic Object format(Object value, String[] args, Cell cell, Workbook wb){if ("若依".equals(value)){// 自定义用户名为若依/单元格文字设置为红色CellStyle style = wb.createCellStyle();style.setAlignment(HorizontalAlignment.CENTER);style.setVerticalAlignment(VerticalAlignment.CENTER);style.setBorderRight(BorderStyle.THIN);style.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());style.setBorderLeft(BorderStyle.THIN);style.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());style.setBorderTop(BorderStyle.THIN);style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());style.setBorderBottom(BorderStyle.THIN);style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());Font dataFont = wb.createFont();dataFont.setFontName("Arial");dataFont.setFontHeightInPoints((short) 10);dataFont.setColor(IndexedColors.RED.index);style.setFont(dataFont);cell.setCellStyle(style);}return value;}
}
自定义隐藏属性列
有时候我们希望对列信息根据业务去动态显示,那么我们可以进行如下处理。
示例:对用户进行条件判断,符合条件则隐藏属性。导出的文件则不会显示此列信息。
@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("userId", "phonenumber");} } else if (条件C) {// 不显示用户邮箱、部门名称(子对象)util.hideColumn("email", "dept.deptName");}util.exportExcel(response, list, "用户数据");
}
导入对象的子对象
有时候我们导入对象里面还包含对象,例如用户管理包含部门需要导入,那么我们可以进行如下处理。
/*** 用户对象 sys_user* * @author ruoyi*/
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();
}
导出对象的子列表
有时候对象里面还包含集合列表,例如用户管理包含多个角色需要导出,那么我们可以进行如下处理。
注意:
需要合并的须在注解里面加上needMerge = true
private List roles;的定义要放在最下面,不然合并的时候回混乱。
/*** 用户对象 sys_user* * @author ruoyi*/
public class SysUser extends BaseEntity
{/** 用户ID */@Excel(name = "用户序号", cellType = ColumnType.NUMERIC, prompt = "用户编号", needMerge = true, width = 20)private Long userId;@Excel(name = "登录名称", needMerge = true, width = 20)private String userName;@Excel(name = "最后登录IP", type = Type.EXPORT,needMerge = true)private String loginIp; @Excel(name = "角色")private List<SysRole> roles;
}public class SysRole
{@Excel(name = "角色编号", cellType = ColumnType.NUMERIC)private String roleId;@Excel(name = "角色名称")private String roleName;@Excel(name = "角色字符")private String roleKey;
}
导出文件结果: