若依ruoyi-vue实现excel导入导出

文章目录

  • @Excel注解
  • excel数据导入
    • 前端实现
    • 后端实现
  • 下载模板
    • 前端实现
    • 后端实现
  • excel数据导出
    • 前端实现
    • 后端实现
  • 自定义标题信息
    • 导出用户管理表格新增标题(用户列表)
    • 导入表格包含标题处理方式
  • 自定义数据处理器
  • 自定义隐藏属性列
  • 导入对象的子对象
  • 导出对象的子列表

@Excel注解

在实际开发中经常需要使用导入导出功能来加快数据的操作。在项目中可以使用注解来完成此项功能。 在需要被导入导出的实体类属性添加@Excel注解。
在使用@Excel注解时,通常可以使用的参数包括:

  1. name:指定Excel列的标题名称,用于导出时生成Excel文件的表头。
  2. orderNum:指定Excel列的顺序,从0开始,用于导出时确定列的顺序。
  3. type:指定导入导出时的数据类型转换,例如可以指定日期格式、数字格式等。
  4. width:指定Excel列的宽度,用于导出时设置列宽。
  5. height:指定Excel行的高度,用于导出时设置行高。
  6. format:指定导入导出时的数据格式,例如可以指定日期的格式化方式。
  7. replace:指定导入导出时的值替换规则,例如可以将特定的值替换为另一个值。
  8. exportFormat:指定导出时的数据格式,例如可以指定数字的格式化方式。
  9. importFormat:指定导入时的数据格式,例如可以指定日期的解析方式。

以上参数中,nameorderNum通常是必需的,其他参数根据实际需求进行选择。在使用时,可以根据具体情况来决定是否需要设置这些参数。

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;
}

导出文件结果:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/578755.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《Linux运维实战:达梦DM8数据库之基本操作》

一、创建表空间 1.1、使用客户端工具创建 1、使用 SYSDBA 用户登录 DM 管理工具。右键表空间模块&#xff0c;点击【新建表空间】&#xff0c;如下图所示&#xff1a; 2、可根据项目需要&#xff0c;修改表空间文件、路径、大小、是否自动扩充、扩充上限等信息&#xff0c;如下…

2024最新华为OD机试试题库全 -【两个字符串间的最短路径问题】- C卷

1. 🌈题目详情 1.1 ⚠️题目 给定两个字符串,分别为字符串 A 与字符串 B。 例如 A字符串为 “ABCABBA”,B字符串为 “CBABAC” 可以得到下图 m * n 的二维数组,定义原点为(0,0),终点为(m,n),水平与垂直的每一条边距离为1,映射成坐标系如下图。 从原点 (0,0) 到 (0,…

Discourse 最多允许有几个分类级别

和 DISCUZ 不同&#xff0c;DISCUZ 可以允许分类下面还有分类&#xff0c;再继续分类这种嵌套式分类。 Discourse 最多只允许有 2 个分类。 如果你在已有的分类下再继续分类的话&#xff0c;系统会提示错误&#xff1a; 意思就是子分类不能再分子分类。 Discourse 尽量采取了…

数据结构:单调栈和单调队列

文章目录 一、单调栈1.1、栈的思想1.2、单调栈1.2.1、单调栈的基本应用&#xff1a;找出数组中每个元素右侧第一个更大的元素1.2.2、单调栈的基本应用&#xff1a;找出数组中每个元素左侧第一个更大的元素1.2.3、单调栈拓展1.2.4、单调栈LeetCode题单 二、单调队列2.1、队列的思…

大电流电感的作用和特点

大电流电感又称为高功率电感&#xff0c;一般是指绕线型电感&#xff0c; 一、主要作用 1.在低频时&#xff0c;起蓄能和滤高频&#xff1b; 2.在高频时&#xff0c;它的阻抗特性表现的很明显。有耗能发热&#xff0c;感性效应降低等现象。 简单来说就是对交流信号进行隔离、…

深度学习pytorch——卷积神经网络(持续更新)

计算机如何解析图片&#xff1f; 在计算机的眼中&#xff0c;一张灰度图片&#xff0c;就是许多个数字组成的二维矩阵&#xff0c;每个数字就是此点的像素值&#xff08;图-1&#xff09;。在存储时&#xff0c;像素值通常位于[0, 255]区间&#xff0c;在深度学习中&#xff0…

07-工作流设计:如何设计合理的多人开发模式?

一个企业级项目是由多人合作完成的&#xff0c;不同开发者在本地开发完代码之后&#xff0c;可能提交到同一个代码仓库&#xff0c;同一个开发者也可能同时开发几个功能特性。这种多人合作开发、多功能并行开发的特性如果处理不好&#xff0c;就会带来诸如丢失代码、合错代码、…

Docker镜像逆向生成Dockerfile

你是否曾经遇到过一个想要使用的 Docker 镜像&#xff0c;但却无法修改以适应你的特定需求&#xff1f;或者你可能发现了一个喜欢的 Docker 镜像&#xff0c;但想要了解它是如何构建的&#xff1f;在这两种情况下&#xff0c;将 Docker 镜像逆向生成一个 Dockerfile 可以使用一…

fzf 命令行工具 - 终端模糊搜索

1. 介绍 fzf 命令行工具 Github 仓库&#xff1a;GitHub - junegunn/fzf: :cherry_blossom: A command-line fuzzy finder fzf 是一款使用 go 语言编写的交互式命令行工具&#xff0c;有着 “命令行模糊搜索神器” 的美称 可以用于文件列表、历史命令、命令输出结果等模糊搜索…

5-规范设计(下):commit信息风格迥异、难以阅读,如何规范?

我们在做代码开发时&#xff0c;经常需要提交代码&#xff0c;提交代码时需要填写 Commit Message&#xff08;提交说明&#xff09;&#xff0c;否则就不允许提交。 所以在 Go 项目开发时&#xff0c;一个好的 Commit Message 至关重要&#xff1a; 可以使自己或者其他开发人…

不用手机号注册海外邮箱

文章目录 1.打开**[proton官网](https://proton.me)**2.选择免费套餐3.选择邮箱后缀&#xff0c;设置用户名和密码4. 通过真人验证&#xff0c;跳过手机验证5.进入邮箱 最近需要注册ChatGPT账号&#xff0c;但是像outlook&#xff0c;hotmail的邮箱基本都会被封&#xff0c;我又…

.NET CORE 分布式事务(三) DTM实现Saga及高并发下的解决方案

目录(结尾附加项目代码资源地址) 引言&#xff1a; 1. SAGA事务模式 2. 拆分为子事务 3. 失败回滚 4. 如何做补偿 4.1 失败的分支是否需要补偿 5. 异常 6. 异常与子事务屏障 6.1 NPC的挑战 6.2 现有方案的问题 6.3 子事务屏障 6.4 原理 7. 更多高级场景 7.1 部分…