若依ruoyi-vue实现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数据导入

目前若依的版本是在用户管理页面有数据导入的功能:

前端实现

导入功能前端的实现和之前文件上传差不多。

html 复制代码
<!-- 用户导入对话框 -->
<el-dialog :title="upload.title" :visible.sync="upload.open" width="400px" append-to-body>
  <el-upload
    ref="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>
javascript 复制代码
// 文件上传中处理
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

java 复制代码
@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属性为是否存在则覆盖(可选)

java 复制代码
@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);
}

下载模板

下载模板实际上就是将一张空表返回给前端。

前端实现

javascript 复制代码
/** 下载模板操作 */
importTemplate() {
  this.download('system/user/importTemplate', {
  }, `user_template_${new Date().getTime()}.xlsx`)
},

后端实现

注意this.init(null, sheetName, title, Type.IMPORT); null表示数据为空,只返回了表头。

java 复制代码
/**
 * 对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数据导出

导出默认流程是先创建一个临时文件,等待前端请求下载结束后马上删除这个临时文件。

前端实现

html 复制代码
<el-col :span="1.5">
  <el-button
    type="warning"
    plain
    icon="el-icon-download"
    size="mini"
    @click="handleExport"
    v-hasPermi="['system:fileNotice:export']"
    >导出</el-button>
</el-col>
javascript 复制代码
/** 导出按钮操作 */
handleExport() {
  this.download('system/fileNotice/export', {
    ...this.queryParams
  }, `fileNotice_${new Date().getTime()}.xlsx`)
}

后端实现

java 复制代码
@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, "系统文件数据");
}

自定义标题信息

有时候我们希望导出表格包含标题信息,我们可以这样做。

导出用户管理表格新增标题(用户列表)

java 复制代码
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表示标题占用行数,根据实际情况填写。

java 复制代码
/**
 * 对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属性指定自定义的数据处理器

java 复制代码
public class SysUser extends BaseEntity
{
    @Excel(name = "用户名称",handler = MyDataHandler.class)
    private String nickName;
}

2、编写数据处理器MyDataHandler继承ExcelHandlerAdapter,返回值为处理后的值。

java 复制代码
public class MyDataHandler implements ExcelHandlerAdapter
{
    @Override
    public 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;
    }
}

自定义隐藏属性列

有时候我们希望对列信息根据业务去动态显示,那么我们可以进行如下处理。

示例:对用户进行条件判断,符合条件则隐藏属性。导出的文件则不会显示此列信息。

java 复制代码
@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, "用户数据");
}

导入对象的子对象

有时候我们导入对象里面还包含对象,例如用户管理包含部门需要导入,那么我们可以进行如下处理。

java 复制代码
/**
 * 用户对象 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;的定义要放在最下面,不然合并的时候回混乱。

java 复制代码
/**
 * 用户对象 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;
}

导出文件结果:

相关推荐
方圆想当图灵15 分钟前
缓存之美:万文详解 Caffeine 实现原理(下)
java·redis·缓存
fmdpenny28 分钟前
Vue3初学之商品的增,删,改功能
开发语言·javascript·vue.js
栗豆包29 分钟前
w175基于springboot的图书管理系统的设计与实现
java·spring boot·后端·spring·tomcat
等一场春雨1 小时前
Java设计模式 十四 行为型模式 (Behavioral Patterns)
java·开发语言·设计模式
涔溪1 小时前
有哪些常见的 Vue 错误?
前端·javascript·vue.js
酱学编程2 小时前
java中的单元测试的使用以及原理
java·单元测试·log4j
我的运维人生2 小时前
Java并发编程深度解析:从理论到实践
java·开发语言·python·运维开发·技术共享
一只爱吃“兔子”的“胡萝卜”2 小时前
2.Spring-AOP
java·后端·spring
HappyAcmen2 小时前
Java中List集合的面试试题及答案解析
java·面试·list
Ase5gqe3 小时前
Windows 配置 Tomcat环境
java·windows·tomcat